Day of the week calculation

For given date in year-month-day, the day of the week can be deduced for the rule of leap years [1] and the fact that January 1, 1 is a Monday [2].

Since a year is a leap year if the year number is a multiple of 4 that is not a multiple of 100 that is not a multiple of 400. The number of leap year up to year y is given by:

def num_leap(y):
    return y//4-y//100+y//400

For a common year, the numbers of days for the twelve months are:

[31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

The number of days before each month in a common year is calculated with:

p = 0
days_before_month = [
    [p, p := p + m][0] for m in
    [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
]
print('[',', '.join(map(str,days_before_month)),']',sep='')

The result is:

[0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334]

Since the extra day of a leap year is added to February, the leap status of current year is only relevant when month number m<3. We can calculate the number of days from January 1, 1 as:

def day_number(y,m,d):
    return (y-1)*365+num_leap(y-(m<3))+days_before_month[m-1]+d

Or, pack everything in the function:

def day_number(y,m,d):
    return (y-1)*365+(lambda y:y//4-y//100+y//400)(y-(m<3))+[0,31,59,90,120,151,181,212,243,273,304,334][m-1]+d

[1] https://en.wikipedia.org/wiki/Leap_year
[2] https://en.wikipedia.org/wiki/AD_1

Leave a Reply

Your email address will not be published. Required fields are marked *