mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-21 03:59:59 +01:00
Converted Hebrew calendar to a child of this datum Foreign calendar is an easy way to support other calendar systems for the purpose of holidays. Added Islamic calendar and fixed Ramadan to be more accurate than it currently is.
137 lines
3.8 KiB
Plaintext
137 lines
3.8 KiB
Plaintext
#define BYOND_EPOCH 2451544.5
|
|
#define HEBREW_EPOCH 347995.5
|
|
#define ISLAMIC_EPOCH 1948439.5
|
|
|
|
/*
|
|
Source for the method of calcuation
|
|
https://www.fourmilab.ch/documents/calendar/
|
|
by John Walker 2015, released under public domain
|
|
*/
|
|
/datum/foreign_calendar
|
|
var/static/jd
|
|
var/yy
|
|
var/mm
|
|
var/dd
|
|
|
|
/datum/foreign_calendar/New()
|
|
if (!jd)
|
|
jd = realtime_to_jd()
|
|
set_date(jd)
|
|
|
|
/datum/foreign_calendar/proc/set_date()
|
|
return
|
|
|
|
/datum/foreign_calendar/proc/realtime_to_jd()
|
|
return round(world.realtime / 864000) + BYOND_EPOCH
|
|
|
|
//////////////////////////////
|
|
// Islamic Calendar //
|
|
//////////////////////////////
|
|
/datum/foreign_calendar/islamic/proc/leap_islamic(yr)
|
|
return ((yr * 11 + 14) % 30) < 11
|
|
|
|
/datum/foreign_calendar/islamic/set_date()
|
|
var/jd_adj = round(jd) + 0.5 // adjust julian date so it ends in .5
|
|
yy = round(((30 * (jd_adj - ISLAMIC_EPOCH)) + 10646) / 10631)
|
|
mm = min(12, CEILING(((jd - (29 + islamic_to_jd(yy, 1, 1))) / 29.5) + 1, 1))
|
|
dd = jd - islamic_to_jd(yy, mm, 1) + 1
|
|
|
|
/datum/foreign_calendar/islamic/proc/islamic_to_jd(year, month, day)
|
|
return day + CEILING(29.5 * (month - 1), 1) + (year - 1) * 354 + round((3 + (11 * year)) / 30) + ISLAMIC_EPOCH - 1
|
|
|
|
//////////////////////////////
|
|
// Hebrew Calendar //
|
|
//////////////////////////////
|
|
/datum/foreign_calendar/hebrew/proc/hebrew_leap(year)
|
|
switch (year % 19)
|
|
if (0, 3, 6, 8, 11, 14, 17)
|
|
return TRUE
|
|
else
|
|
return FALSE
|
|
|
|
// Hebrew to Julian
|
|
/datum/foreign_calendar/hebrew/proc/hebrew_to_jd(year, month, day)
|
|
var/months = hebrew_year_months(year)
|
|
var/jd = HEBREW_EPOCH + hebrew_delay_1(year) + hebrew_delay_2(year) + day + 1
|
|
if (month < 7)
|
|
for (var/mon = 7; mon <= months; mon++)
|
|
jd += hebrew_month_days(year, mon)
|
|
for (var/mon = 1; mon < month; mon++)
|
|
jd += hebrew_month_days(year, mon)
|
|
else
|
|
for (var/mon = 7; mon < month; mon++)
|
|
jd += hebrew_month_days(year, mon)
|
|
return jd
|
|
|
|
|
|
// Julian to Hebrew
|
|
/datum/foreign_calendar/hebrew/set_date(jd)
|
|
if (yy && mm && dd)
|
|
return
|
|
jd = round(jd) + 0.5
|
|
var/count = round(((jd - HEBREW_EPOCH) * 98496) / 35975351)
|
|
var/year = count - 1
|
|
for (var/i = count; jd >= hebrew_to_jd(i, 7, 1); i++)
|
|
year++
|
|
var/month = (jd < hebrew_to_jd(year, 1, 1)) ? 7 : 1
|
|
for (var/i = month; jd > hebrew_to_jd(year, i, hebrew_month_days(year, i)); i++)
|
|
month++
|
|
var/day = (jd - hebrew_to_jd(year, month, 1)) + 1
|
|
yy = year
|
|
mm = month
|
|
dd = day
|
|
|
|
/datum/foreign_calendar/hebrew/proc/hebrew_year_months(year)
|
|
if (hebrew_leap(year))
|
|
return 13
|
|
else
|
|
return 12
|
|
|
|
// Delay based on starting day of the year
|
|
/datum/foreign_calendar/hebrew/proc/hebrew_delay_1(year)
|
|
var/months = round(((235 * year) - 234) / 19)
|
|
var/parts = 12084 + (13753 * months)
|
|
var/day = (months * 29) + round(parts / 25920)
|
|
if (3 * (day + 1) % 7 < 3)
|
|
day++
|
|
return day
|
|
|
|
// Delay based on length of adjacent years
|
|
/datum/foreign_calendar/hebrew/proc/hebrew_delay_2(year)
|
|
var/last = hebrew_delay_1(year - 1)
|
|
var/present = hebrew_delay_1(year)
|
|
var/next = hebrew_delay_1(year + 1)
|
|
if (next - present == 356)
|
|
return 2
|
|
else if (present - last == 382)
|
|
return 1
|
|
else
|
|
return 0
|
|
|
|
/datum/foreign_calendar/hebrew/proc/hebrew_year_days(year)
|
|
return hebrew_to_jd(year + 1, 7, 1) - hebrew_to_jd(year, 7, 1)
|
|
|
|
/datum/foreign_calendar/hebrew/proc/hebrew_month_days(year, month)
|
|
switch (month)
|
|
// First of all, dispose of fixed-length 29 day months
|
|
if (2, 4, 6, 10, 13)
|
|
return 29
|
|
// If it's not a leap year, Adar has 29 days
|
|
if (12)
|
|
if (!hebrew_leap(year))
|
|
return 29
|
|
// If it's Heshvan, days depend on length of year
|
|
if (8)
|
|
if (hebrew_year_days(year) % 10 != 5)
|
|
return 29
|
|
// Similarly, Kislev varies with the length of year
|
|
if (9)
|
|
if (hebrew_year_days(year) % 10 == 3)
|
|
return 29
|
|
// Nope, it's a 30 day month
|
|
return 30
|
|
|
|
#undef ISLAMIC_EPOCH
|
|
#undef BYOND_EPOCH
|
|
#undef HEBREW_EPOCH
|