Day of the Week
Problem
Given a date represented by day, month and year, return the corresponding day of the week. The answer is one of {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"}. The given date is always valid and lies between the years 1971 and 2100.
day = 31, month = 8, year = 2019"Saturday"def day_of_the_week(day, month, year):
week = ["Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"]
mdays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
def is_leap(y):
return y % 4 == 0 and (y % 100 != 0 or y % 400 == 0)
days = 0
for y in range(1971, year):
days += 366 if is_leap(y) else 365
for m in range(1, month):
days += mdays[m - 1]
if m == 2 and is_leap(year):
days += 1
days += day - 1
# 1971-01-01 was a Friday (index 5)
return week[(days + 5) % 7]
function dayOfTheWeek(day, month, year) {
const week = ["Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"];
const mdays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
const isLeap = (y) => y % 4 === 0 && (y % 100 !== 0 || y % 400 === 0);
let days = 0;
for (let y = 1971; y < year; y++) days += isLeap(y) ? 366 : 365;
for (let m = 1; m < month; m++) {
days += mdays[m - 1];
if (m === 2 && isLeap(year)) days += 1;
}
days += day - 1;
// 1971-01-01 was a Friday (index 5)
return week[(days + 5) % 7];
}
class Solution {
public String dayOfTheWeek(int day, int month, int year) {
String[] week = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"};
int[] mdays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int days = 0;
for (int y = 1971; y < year; y++) days += isLeap(y) ? 366 : 365;
for (int m = 1; m < month; m++) {
days += mdays[m - 1];
if (m == 2 && isLeap(year)) days += 1;
}
days += day - 1;
// 1971-01-01 was a Friday (index 5)
return week[(days + 5) % 7];
}
private boolean isLeap(int y) {
return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0);
}
}
string dayOfTheWeek(int day, int month, int year) {
string week[] = {"Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday"};
int mdays[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
auto isLeap = [](int y) {
return y % 4 == 0 && (y % 100 != 0 || y % 400 == 0);
};
int days = 0;
for (int y = 1971; y < year; y++) days += isLeap(y) ? 366 : 365;
for (int m = 1; m < month; m++) {
days += mdays[m - 1];
if (m == 2 && isLeap(year)) days += 1;
}
days += day - 1;
// 1971-01-01 was a Friday (index 5)
return week[(days + 5) % 7];
}
Explanation
The trick is to count the total number of days elapsed from a known anchor date, then use mod 7 to land on the right weekday. We anchor on 1971-01-01, which was a Friday (index 5).
We build up days in three stages. First we add a full year's length for every year from 1971 up to (but not including) the target year, using 366 for leap years and 365 otherwise. The is_leap helper checks the rule: divisible by 4, but not by 100 unless also by 400.
Next we add the lengths of every full month before the target month, adding one extra day if February falls in a leap year. Finally we add day - 1 to land on the exact date (the 1st is zero days past the start).
The weekday is week[(days + 5) % 7]. The + 5 shifts our count so that 0 elapsed days maps to Friday, the anchor's weekday.
Example: for 2019-08-31 the code sums all years 1971-2018, then Jan-Jul of 2019, then 30 more days. Taking (days + 5) % 7 gives index 6, which is Saturday.