Last active
November 7, 2021 06:07
-
-
Save potsbo/c7bbed1167af70ebb9d62bcb46106619 to your computer and use it in GitHub Desktop.
The Doomsday Algorithm
This file contains 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
require 'date' | |
ANCHOR_DAYS = { | |
1800 => 5, | |
1900 => 3, | |
2000 => 2, | |
2100 => 0, | |
} | |
# supports only 1800 ~ 2199 | |
def calc(year, month, day) | |
base_wday = get_weekday_of(year) | |
doomsday = get_doomsday_of_the_month(year, month) | |
month_shift = day - doomsday | |
(base_wday + month_shift) % 7 | |
end | |
def get_weekday_of(year) | |
last_two = year % 100 | |
nums = [ | |
ANCHOR_DAYS[year - last_two], | |
last_two / 12, | |
remainder = last_two % 12, | |
remainder / 4, | |
] | |
nums.reduce(&:+) % 7 | |
end | |
def get_doomsday_of_the_month(year, month) | |
# we have to consider leap year | |
return janfeb_doomsday(year, month) if month < 3 | |
# pi day | |
return 14 if month == 3 | |
# even numbers rule | |
return month if month % 2 == 0 | |
# work from 9 to 5 at seven eleven rule | |
{ | |
5 => 9, | |
7 => 11, | |
9 => 5, | |
11 => 7, | |
}[month] | |
end | |
def janfeb_doomsday(year, month) | |
is_leap = check_leap(year) | |
case month | |
when 1 then | |
is_leap ? 4 : 3 | |
when 2 then | |
is_leap ? 29 : 28 | |
end | |
end | |
def check_leap(year) | |
return true if year % 400 == 0 | |
return false if year % 100 == 0 | |
return true if year % 4 == 0 | |
false | |
end | |
puts calc(1976, 6, 18) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment