Day of the Week — Easy Problem & Solution
Given a valid date as three integers day, month and year, return the day of the week it falls on, as one of: "Sunday", "Monday", "Tuesday", "Wednesday",…
- Difficulty: Easy
- Topics: Math
- Asked at: Amazon, Microsoft
- Time limit: 2 s
- Memory limit: 256 MB
- Languages: JavaScript, TypeScript, Python, Java, C++, C, C#, Go, Kotlin, Swift, Rust, PHP and Ruby
Problem statement
Given a valid date as three integers day, month and year, return the day of the week it falls on, as one of:
"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday".
Use the Gregorian calendar (leap years are divisible by 4 but not by 100, or divisible by 400). As an anchor, January 1st, 1971 was a Friday.
Example 1
Input: day = 31, month = 8, year = 2019
Output: Saturday
Example 2
Input: day = 18, month = 7, year = 1999
Output: Sunday
Example 3
Input: day = 15, month = 8, year = 1993
Output: Sunday
Constraints
The date is valid and lies between the years 1971 and 2100 (inclusive)
How to solve Day of the Week
Count the days elapsed since a known Friday (1971-01-01) and reduce modulo 7.
Approach
- Let
total = day - 1. - Add 365 or 366 for each year from 1971 up to
year - 1. - Add the lengths of the months before
monthinyear(February has 29 days in a leap year). - With the names listed from Sunday (index 0), return
names[(5 + total) % 7]— Friday is index 5.
Why it works
total is exactly the number of days from 1971-01-01 to the given date, and every 7 days the weekday returns to the same value, so the weekday is Friday shifted by total mod 7.
Complexity
- Time —
O(year − 1971) - Space —
O(1)
Pitfalls
- Starting
totalatdayinstead ofday - 1shifts every answer by one weekday. - The century rule: 2000 is a leap year, 2100 is not.
- Zeller's congruence also works but is easy to get wrong for January and February, which it treats as months 13 and 14 of the previous year.
Reference solution
Python
def dayOfTheWeek(day: int, month: int, year: int) -> str:
names = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
def is_leap(y: int) -> bool:
return (y % 4 == 0 and y % 100 != 0) or y % 400 == 0
lengths = [31, 29 if is_leap(year) else 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
total = day - 1
for y in range(1971, year):
total += 366 if is_leap(y) else 365
total += sum(lengths[:month - 1])
return names[(5 + total) % 7]JavaScript
var dayOfTheWeek = function(day, month, year) {
var names = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var isLeap = function(y) { return (y % 4 === 0 && y % 100 !== 0) || y % 400 === 0; };
var lengths = [31, isLeap(year) ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
var total = day - 1;
for (var y = 1971; y < year; y++) total += isLeap(y) ? 366 : 365;
for (var m = 0; m < month - 1; m++) total += lengths[m];
return names[(5 + total) % 7];
};Also on the editorial tab: C, C#, C++, Go, Java, Kotlin, PHP, Ruby, Rust, Swift, TypeScript.