Created
August 9, 2012 10:46
-
-
Save dvoiss/3303206 to your computer and use it in GitHub Desktop.
Reddit Daily Programmer Challenge: Weekday Calculations
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# Challenge: http://www.reddit.com/r/dailyprogrammer/comments/xx97s/882012_challenge_86_intermediate_weekday/ | |
# Solution: http://www.reddit.com/r/dailyprogrammer/comments/xx97s/882012_challenge_86_intermediate_weekday/c5qgu1k | |
# Run code online: http://ideone.com/HIyf7 | |
import sys | |
# this example assumes proper dates are entered (there are no safety checks performed) | |
if len(sys.argv) == 1: | |
print 'Enter a date string as input in the format month/day/year' | |
print 'Example: January 17, 1981 is inputted as "1/17/1981"' | |
exit() | |
# split string and convert to integers | |
month, day, year = map( lambda x: int(x), sys.argv[1].split('/') ) | |
# gregorian? | |
is_gregorian = True | |
if (year < 0): | |
is_gregorian = False | |
year = year - 1 # account for there being no year zero | |
else: | |
from datetime import date | |
julian_calendar_fail = date(1582, 10, 15) # julian calendar goes away | |
is_gregorian = date(year, month, day) > julian_calendar_fail | |
# leap year calculation: | |
if is_gregorian and year % 4 == 0 and not ( year % 100 == 0 and year % 400 != 0 ): | |
is_leap_year = True | |
elif not is_gregorian and year % 4 == 0: # julian | |
is_leap_year = True | |
else: | |
is_leap_year = False | |
if (month == 2): | |
days_in_month = 29 if is_leap_year else 28 | |
else: | |
from calendar import monthrange | |
days_in_month = monthrange(2000, month) # year irrelevant for non-February months | |
# safety: | |
century = int( str(year)[:-2] ) if str(year)[:-2] != '' else 0 | |
year = int( str(year)[-2:] ) if str(year)[-2:] != '' else 0 | |
# the doomsday calculation: http://en.wikipedia.org/wiki/Doomsday_rule | |
doomsdays = [ 4 if is_leap_year else 3, 29 if is_leap_year else 28, 0, 4, 9, 6, 11, 8, 5, 10, 7, 12 ] | |
# weekdays, starting with Monday == 0 | |
days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] | |
a = year / 12 | |
b = year % 12 | |
c = b / 4 | |
d = ( a + b + c ) | |
# "Finding a year's Doomsday" section @ http://en.wikipedia.org/wiki/Doomsday_rule: | |
if is_gregorian: | |
d = d % 7 | |
anchor_days = [ 1, 6, 4, 2 ] # from wikipedia link above | |
anchor = anchor_days[ century % 4 ] | |
offset = day - doomsdays[ month - 1 ] | |
day_of_week = (d + anchor + offset) | |
else: | |
anchor = 6 + d - century | |
anchor += 7 if anchor < 0 else -7 # normalize between -7 and 7 | |
offset = day - doomsdays[ month - 1 ] | |
day_of_week = (anchor + offset) | |
# normalize day_of_week to be between 0 and 6 | |
day_of_week = day_of_week % 7 | |
print days[ day_of_week ] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment