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

  1. Let total = day - 1.
  2. Add 365 or 366 for each year from 1971 up to year - 1.
  3. Add the lengths of the months before month in year (February has 29 days in a leap year).
  4. 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 total at day instead of day - 1 shifts 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.

All 307 math problems · the whole catalogue