diff --git a/code/__HELPERS/time.dm b/code/__HELPERS/time.dm index a2402005d51..d9a6b5bf905 100644 --- a/code/__HELPERS/time.dm +++ b/code/__HELPERS/time.dm @@ -41,29 +41,23 @@ GLOBAL_VAR_INIT(rollovercheck_last_timeofday, 0) return GLOB.midnight_rollovers -///Returns the current week of the current month, from 1 to 5. -/proc/week_of_the_month() - var/day = time2text(world.timeofday, "DDD") // get the current day - var/date = text2num(time2text(world.timeofday, "DD")) // get the current date - - switch(day) - if(MONDAY) - date -= 1 - if(TUESDAY) - date -= 2 - if(WEDNESDAY) - date -= 3 - if(THURSDAY) - date -= 4 - if(FRIDAY) - date -= 5 - if(SATURDAY) - date -= 6 - if(SUNDAY) - date -= 7 - - return CEILING(date / 7, 1) + 1 - +///Returns a string day as an integer in ISO format 1 (Monday) - 7 (Sunday) +/proc/weekday_to_iso(ddd) + switch (ddd) + if (MONDAY) + return 1 + if (TUESDAY) + return 2 + if (WEDNESDAY) + return 3 + if (THURSDAY) + return 4 + if (FRIDAY) + return 5 + if (SATURDAY) + return 6 + if (SUNDAY) + return 7 ///Returns the first day of the given year and month in number format, from 1 (monday) - 7 (sunday). /proc/first_day_of_month(year, month) diff --git a/code/controllers/subsystem/events.dm b/code/controllers/subsystem/events.dm index 04fcb5d71c3..a875caf908a 100644 --- a/code/controllers/subsystem/events.dm +++ b/code/controllers/subsystem/events.dm @@ -154,15 +154,14 @@ SUBSYSTEM_DEF(events) if(!CONFIG_GET(flag/allow_holidays)) return // Holiday stuff was not enabled in the config! - var/YY = text2num(time2text(world.timeofday, "YY")) // get the current year + var/YYYY = text2num(time2text(world.timeofday, "YYYY")) // get the current year var/MM = text2num(time2text(world.timeofday, "MM")) // get the current month var/DD = text2num(time2text(world.timeofday, "DD")) // get the current day var/DDD = time2text(world.timeofday, "DDD") // get the current weekday - var/W = week_of_the_month() // is this the first monday? second? etc. for(var/H in subtypesof(/datum/holiday)) var/datum/holiday/holiday = new H() - if(holiday.shouldCelebrate(DD, MM, YY, W, DDD)) + if(holiday.shouldCelebrate(DD, MM, YYYY, DDD)) holiday.celebrate() if(!holidays) holidays = list() diff --git a/code/modules/holiday/foreign_calendar.dm b/code/modules/holiday/foreign_calendar.dm index 1c217082252..8746f46cdec 100644 --- a/code/modules/holiday/foreign_calendar.dm +++ b/code/modules/holiday/foreign_calendar.dm @@ -10,13 +10,13 @@ by John Walker 2015, released under public domain */ /datum/foreign_calendar var/jd - var/yy + var/yyyy var/mm var/dd -/datum/foreign_calendar/New(yy, mm, dd) +/datum/foreign_calendar/New(yyyy, mm, dd) if (!jd) - jd = gregorian_to_jd(yy, mm, dd) + jd = gregorian_to_jd(yyyy, mm, dd) set_date(jd) /datum/foreign_calendar/proc/set_date() @@ -53,9 +53,9 @@ by John Walker 2015, released under public domain /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 + yyyy = round(((30 * (jd_adj - ISLAMIC_EPOCH)) + 10646) / 10631) + mm = min(12, CEILING(((jd - (29 + islamic_to_jd(yyyy, 1, 1))) / 29.5) + 1, 1)) + dd = jd - islamic_to_jd(yyyy, 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 @@ -87,7 +87,7 @@ by John Walker 2015, released under public domain // Julian to Hebrew /datum/foreign_calendar/hebrew/set_date(jd) - if (yy && mm && dd) + if (yyyy && mm && dd) return jd = round(jd) + 0.5 var/count = round(((jd - HEBREW_EPOCH) * 98496) / 35975351) @@ -98,7 +98,7 @@ by John Walker 2015, released under public domain 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 + yyyy = year mm = month dd = day diff --git a/code/modules/holiday/holidays.dm b/code/modules/holiday/holidays.dm index 8aa4e6c4d37..1b43b131313 100644 --- a/code/modules/holiday/holidays.dm +++ b/code/modules/holiday/holidays.dm @@ -25,7 +25,7 @@ return copytext(name, 1, i) // Return 1 if this holidy should be celebrated today -/datum/holiday/proc/shouldCelebrate(dd, mm, yy, ww, ddd) +/datum/holiday/proc/shouldCelebrate(dd, mm, yyyy, ddd) if(always_celebrate) return TRUE @@ -105,7 +105,7 @@ drone_hat = /obj/item/clothing/head/festive /datum/holiday/birthday/greet() - var/game_age = text2num(time2text(world.timeofday, "YY")) - 3 + var/game_age = text2num(time2text(world.timeofday, "YYYY")) - 2003 var/Fact switch(game_age) if(16) @@ -126,8 +126,6 @@ Fact = " Happy golden anniversary!" if(65) Fact = " SS13 can now start thinking about retirement!" - if(96) - Fact = " Please send a time machine back to pick me up, I need to update the time formatting for this feature!" //See you later suckers if(!Fact) Fact = " SS13 is now [game_age] years old!" @@ -308,17 +306,6 @@ /datum/holiday/friendship/greet() return "Have a magical [name]!" -/datum/holiday/beer - name = "Beer Day" - -/datum/holiday/beer/shouldCelebrate(dd, mm, yy, ww, ddd) - if(mm == 8 && ddd == FRIDAY && ww == 1) //First Friday in August - return TRUE - return FALSE - -/datum/holiday/beer/getStationPrefix() - return pick("Stout","Porter","Lager","Ale","Malt","Bock","Doppelbock","Hefeweizen","Pilsner","IPA","Lite") //I'm sorry for the last one - /datum/holiday/pirate name = "Talk-Like-a-Pirate Day" begin_day = 19 @@ -334,9 +321,9 @@ /datum/holiday/programmers name = "Programmers' Day" -/datum/holiday/programmers/shouldCelebrate(dd, mm, yy, ww, ddd) //Programmer's day falls on the 2^8th day of the year +/datum/holiday/programmers/shouldCelebrate(dd, mm, yyyy, ddd) //Programmer's day falls on the 2^8th day of the year if(mm == 9) - if(yy/4 == round(yy/4)) //Note: Won't work right on September 12th, 2200 (at least it's a Friday!) + if(yyyy/4 == round(yyyy/4)) //Note: Won't work right on September 12th, 2200 (at least it's a Friday!) if(dd == 12) return TRUE else @@ -435,29 +422,12 @@ begin_month = DECEMBER drone_hat = /obj/item/clothing/mask/gas/monkeymask -/datum/holiday/moth - name = "Moth Week" - -/datum/holiday/moth/shouldCelebrate(dd, mm, yy, ww, ddd) //National Moth Week falls on the last full week of July, including the saturday and sunday before. See http://nationalmothweek.org/ for precise tracking. - if(mm == JULY) - var/week - if(first_day_of_month(yy, mm) >= 5) //Friday or later start of the month means week 5 is a full week. - week = 5 - else - week = 4 - - return (ww == week-1 && (ddd == SATURDAY || ddd == SUNDAY)) || ww == week - - -/datum/holiday/moth/getStationPrefix() - return pick("Mothball","Lepidopteran","Lightbulb","Moth","Giant Atlas","Twin-spotted Sphynx","Madagascan Sunset","Luna","Death's Head","Emperor Gum","Polyphenus","Oleander Hawk","Io","Rosy Maple","Cecropia","Noctuidae","Giant Leopard","Dysphania Militaris","Garden Tiger") - /datum/holiday/islamic name = "Islamic calendar code broken" -/datum/holiday/islamic/shouldCelebrate(dd, mm, yy, ww, ddd) - var/datum/foreign_calendar/islamic/cal = new(yy, mm, dd) - return ..(cal.dd, cal.mm, cal.yy, ww, ddd) +/datum/holiday/islamic/shouldCelebrate(dd, mm, yyyy, ddd) + var/datum/foreign_calendar/islamic/cal = new(yyyy, mm, dd) + return ..(cal.dd, cal.mm, cal.yyyy, ddd) /datum/holiday/islamic/ramadan name = "Start of Ramadan" @@ -534,7 +504,7 @@ /datum/holiday/friday_thirteenth name = "Friday the 13th" -/datum/holiday/friday_thirteenth/shouldCelebrate(dd, mm, yy, ww, ddd) +/datum/holiday/friday_thirteenth/shouldCelebrate(dd, mm, yyyy, ddd) if(dd == 13 && ddd == FRIDAY) return TRUE return FALSE @@ -548,7 +518,7 @@ var/const/days_early = 1 //to make editing the holiday easier var/const/days_extra = 1 -/datum/holiday/easter/shouldCelebrate(dd, mm, yy, ww, ddd) +/datum/holiday/easter/shouldCelebrate(dd, mm, yyyy, ddd) if(!begin_month) current_year = text2num(time2text(world.timeofday, "YYYY")) var/list/easterResults = EasterDate(current_year+year_offset) @@ -610,9 +580,9 @@ /datum/holiday/hebrew name = "If you see this the Hebrew holiday calendar code is broken" -/datum/holiday/hebrew/shouldCelebrate(dd, mm, yy, ww, ddd) - var/datum/foreign_calendar/hebrew/cal = new(yy, mm, dd) - return ..(cal.dd, cal.mm, cal.yy, ww, ddd) +/datum/holiday/hebrew/shouldCelebrate(dd, mm, yyyy, ddd) + var/datum/foreign_calendar/hebrew/cal = new(yyyy, mm, dd) + return ..(cal.dd, cal.mm, cal.yyyy, ddd) /datum/holiday/hebrew/hanukkah name = "Hanukkah" diff --git a/code/modules/holiday/nth_week.dm b/code/modules/holiday/nth_week.dm index 4195ce11097..4f32c4881fa 100644 --- a/code/modules/holiday/nth_week.dm +++ b/code/modules/holiday/nth_week.dm @@ -4,39 +4,30 @@ var/begin_week = 1 ///Weekday of begin_week to start on. var/begin_weekday = MONDAY + ///Nth weekday of type end_weekday in end_month to end on (1 to 5, defaults to begin_week). + var/end_week + ///Weekday of end_week to end on (defaults to begin_weekday). + var/end_weekday -/datum/holiday/nth_week/shouldCelebrate(dd, mm, yy, ww, ddd) - // Does not support end_day or end_month. Find me a holiday that needs that and I'll add it. - // Same with adding an end_weekday or end_week. - if (mm != begin_month) - return FALSE - if (begin_weekday != ddd) - return FALSE - var/day_number = 0 - // format of first_day_of_month proc (Monday 1 Sunday 7) - switch (begin_weekday) - if (MONDAY) - day_number = 1 - if (TUESDAY) - day_number = 2 - if (WEDNESDAY) - day_number = 3 - if (THURSDAY) - day_number = 4 - if (FRIDAY) - day_number = 5 - if (SATURDAY) - day_number = 6 - if (SUNDAY) - day_number = 7 - var/fd = first_day_of_month(yy, mm) - var/weekday_diff = day_number - fd - if (weekday_diff < 0) - weekday_diff += 7 - var/correct_day = (begin_week - 1) * 7 + weekday_diff + 1 - if (dd == correct_day) - return TRUE - return FALSE +/datum/holiday/nth_week/shouldCelebrate(dd, mm, yy, ddd) + // Does not support holidays across multiple years.. + if (!end_month) + end_month = begin_month + if (!end_week) + end_week = begin_week + if (!end_weekday) + end_weekday = begin_weekday + // check that it's not past the last day + end_day = weekday_to_iso(end_weekday) - first_day_of_month(yy, end_month) + if (end_day < 0) + end_day += 7 + end_day += (end_week - 1) * 7 + 1 + // check that it's not past the first day + begin_day = weekday_to_iso(begin_weekday) - first_day_of_month(yy, begin_month) + if (begin_day < 0) + begin_day += 7 + begin_day += (begin_week - 1) * 7 + 1 + return ..(dd, mm, yy, ddd) /datum/holiday/nth_week/thanksgiving name = "Thanksgiving in the United States" @@ -73,8 +64,29 @@ begin_month = JUNE begin_weekday = SUNDAY -/datum/holiday/nth_week/todaytest - name = "First Saturday of December" +/datum/holiday/nth_week/beer + name = "Beer Day" begin_week = 1 - begin_month = DECEMBER + begin_month = AUGUST + begin_weekday = FRIDAY + +/datum/holiday/beer/getStationPrefix() + return pick("Stout","Porter","Lager","Ale","Malt","Bock","Doppelbock","Hefeweizen","Pilsner","IPA","Lite") //I'm sorry for the last one + +/datum/holiday/nth_week/moth + name = "Moth Week" + begin_week = 3 + end_week = 4 + begin_month = JULY begin_weekday = SATURDAY + end_weekday = SUNDAY + +//National Moth Week falls on the last full week of July, including the saturday and sunday before. See http://nationalmothweek.org/ for precise tracking. +/datum/holiday/nth_week/moth/shouldCelebrate(dd, mm, yyyy, ddd) + if(first_day_of_month(yyyy, mm) >= 5) //Friday or later start of the month means week 5 is a full week. + begin_week += 1 + end_week += 1 + return ..(dd, mm, yyyy, ddd) + +/datum/holiday/nth_week/moth/getStationPrefix() + return pick("Mothball","Lepidopteran","Lightbulb","Moth","Giant Atlas","Twin-spotted Sphynx","Madagascan Sunset","Luna","Death's Head","Emperor Gum","Polyphenus","Oleander Hawk","Io","Rosy Maple","Cecropia","Noctuidae","Giant Leopard","Dysphania Militaris","Garden Tiger") diff --git a/code/modules/unit_tests/holidays.dm b/code/modules/unit_tests/holidays.dm index 4df5443e2ee..24c95a06ea6 100644 --- a/code/modules/unit_tests/holidays.dm +++ b/code/modules/unit_tests/holidays.dm @@ -1,33 +1,36 @@ // test Jewish holiday /datum/unit_test/hanukkah_2123/Run() var/datum/holiday/hebrew/hanukkah/hanukkah = new - TEST_ASSERT(hanukkah.shouldCelebrate(14, DECEMBER, 2123, 2, TUESDAY), "December 14, 2123 was not Hanukkah.") + TEST_ASSERT(hanukkah.shouldCelebrate(14, DECEMBER, 2123, TUESDAY), "December 14, 2123 was not Hanukkah.") // test Islamic holiday /datum/unit_test/ramadan_2165/Run() var/datum/holiday/islamic/ramadan/ramadan = new - TEST_ASSERT(ramadan.shouldCelebrate(6, NOVEMBER, 2165, 1, WEDNESDAY), "November 6, 2165 was not Ramadan.") + TEST_ASSERT(ramadan.shouldCelebrate(6, NOVEMBER, 2165, WEDNESDAY), "November 6, 2165 was not Ramadan.") // nth day of week /datum/unit_test/thanksgiving_2020/Run() var/datum/holiday/nth_week/thanksgiving/thanksgiving = new - TEST_ASSERT(thanksgiving.shouldCelebrate(26, NOVEMBER, 2020, 4, THURSDAY), "November 26, 2020 was not Thanksgiving.") + TEST_ASSERT(thanksgiving.shouldCelebrate(26, NOVEMBER, 2020, THURSDAY), "November 26, 2020 was not Thanksgiving.") // another nth day of week /datum/unit_test/indigenous_3683/Run() var/datum/holiday/nth_week/indigenous/indigenous = new - TEST_ASSERT(indigenous.shouldCelebrate(11, OCTOBER, 3683, 2, MONDAY), "October 11, 3683 was not Indigenous Peoples' Day.") + TEST_ASSERT(indigenous.shouldCelebrate(11, OCTOBER, 3683, MONDAY), "October 11, 3683 was not Indigenous Peoples' Day.") // plain old simple holiday /datum/unit_test/hello_2020/Run() var/datum/holiday/hello/hello = new - TEST_ASSERT(hello.shouldCelebrate(21, NOVEMBER, 2020, 3, SATURDAY), "November 21, 2020 was not Hello day.") + TEST_ASSERT(hello.shouldCelebrate(21, NOVEMBER, 2020, SATURDAY), "November 21, 2020 was not Hello day.") // holiday which goes across months /datum/unit_test/new_year_1983/Run() var/datum/holiday/new_year/new_year = new - TEST_ASSERT(new_year.shouldCelebrate(2, JANUARY, 1983, 1, SUNDAY), "January 2, 1983 was not New Year.") + TEST_ASSERT(new_year.shouldCelebrate(2, JANUARY, 1983, SUNDAY), "January 2, 1983 was not New Year.") /datum/unit_test/moth_week_2020/Run() - var/datum/holiday/moth/moth = new - TEST_ASSERT(moth.shouldCelebrate(19, JULY, 2020, 3, SATURDAY), "July 19, 2020 was not Moth Week.") + var/datum/holiday/nth_week/moth/moth = new + TEST_ASSERT(moth.shouldCelebrate(18, JULY, 2020, SATURDAY), "July 18, 2020 was not Moth Week.") + TEST_ASSERT(moth.shouldCelebrate(20, JULY, 2020, MONDAY), "July 20, 2020 was not Moth Week.") + TEST_ASSERT(moth.shouldCelebrate(24, JULY, 2020, FRIDAY), "July 24, 2020 was not Moth Week.") + TEST_ASSERT(moth.shouldCelebrate(26, JULY, 2020, SUNDAY), "July 26, 2020 was not Moth Week.")