Skip to content

Instantly share code, notes, and snippets.

@potsbo
Last active November 7, 2021 06:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save potsbo/c7bbed1167af70ebb9d62bcb46106619 to your computer and use it in GitHub Desktop.
Save potsbo/c7bbed1167af70ebb9d62bcb46106619 to your computer and use it in GitHub Desktop.
The Doomsday Algorithm
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