From 9e3382f215668c9487b0aa823263a790b9ec35f6 Mon Sep 17 00:00:00 2001 From: Knut Ahlers Date: Thu, 18 Aug 2022 13:48:11 +0200 Subject: [PATCH] Restructure german holidays, fix missing days Signed-off-by: Knut Ahlers --- holidays/holidays_de.go | 198 +++++++++++++++-------------------- holidays/holidays_de_test.go | 23 ++++ 2 files changed, 110 insertions(+), 111 deletions(-) create mode 100644 holidays/holidays_de_test.go diff --git a/holidays/holidays_de.go b/holidays/holidays_de.go index 97fb7ce..ef55a03 100644 --- a/holidays/holidays_de.go +++ b/holidays/holidays_de.go @@ -1,119 +1,95 @@ package holidays +import "time" + func init() { - registerHolidayDataSource("de", holidaysDENational{}) - registerHolidayDataSource("de-bb", holidaysDEBB{}) - registerHolidayDataSource("de-be", holidaysDEBE{}) - registerHolidayDataSource("de-bw", holidaysDEBW{}) - registerHolidayDataSource("de-by", holidaysDEBY{}) - registerHolidayDataSource("de-hb", holidaysDEHB{}) - registerHolidayDataSource("de-he", holidaysDEHE{}) - registerHolidayDataSource("de-hh", holidaysDEHH{}) - registerHolidayDataSource("de-mv", holidaysDEMV{}) - registerHolidayDataSource("de-ni", holidaysDENI{}) - registerHolidayDataSource("de-nw", holidaysDENW{}) - registerHolidayDataSource("de-rp", holidaysDERP{}) - registerHolidayDataSource("de-sh", holidaysDESH{}) - registerHolidayDataSource("de-sl", holidaysDESL{}) - registerHolidayDataSource("de-sn", holidaysDESN{}) - registerHolidayDataSource("de-st", holidaysDEST{}) - registerHolidayDataSource("de-th", holidaysDETH{}) + registerHolidayDataSource("de", holidaysDE{}) + registerHolidayDataSource("de-bb", holidaysDE{state: "bb"}) + registerHolidayDataSource("de-be", holidaysDE{state: "be"}) + registerHolidayDataSource("de-bw", holidaysDE{state: "bw"}) + registerHolidayDataSource("de-by", holidaysDE{state: "by"}) + registerHolidayDataSource("de-hb", holidaysDE{state: "hb"}) + registerHolidayDataSource("de-he", holidaysDE{state: "he"}) + registerHolidayDataSource("de-hh", holidaysDE{state: "hh"}) + registerHolidayDataSource("de-mv", holidaysDE{state: "mv"}) + registerHolidayDataSource("de-ni", holidaysDE{state: "ni"}) + registerHolidayDataSource("de-nw", holidaysDE{state: "nw"}) + registerHolidayDataSource("de-rp", holidaysDE{state: "rp"}) + registerHolidayDataSource("de-sh", holidaysDE{state: "sh"}) + registerHolidayDataSource("de-sl", holidaysDE{state: "sl"}) + registerHolidayDataSource("de-sn", holidaysDE{state: "sn"}) + registerHolidayDataSource("de-st", holidaysDE{state: "st"}) + registerHolidayDataSource("de-th", holidaysDE{state: "th"}) } -type holidaysDENational struct{} +type ( + holidaysDE struct{ state string } +) -func (h holidaysDENational) GetIncludes() []string { return []string{} } -func (h holidaysDENational) GetHolidays(year int) []Holiday { - return []Holiday{ - newHoliday("New Year's Day", map[string]string{"de": "Neujahrstag"}, dateFromNumbers(year, 1, 1)), - newHoliday("Labor Day", map[string]string{"de": "Tag der Arbeit"}, dateFromNumbers(year, 5, 1)), - newHoliday("German Unity Day", map[string]string{"de": "Tag der Deutschen Einheit"}, dateFromNumbers(year, 10, 3)), - newHoliday("Christmas Day", map[string]string{"de": "Weihnachtstag"}, dateFromNumbers(year, 12, 25)), - newHoliday("Boxing Day", map[string]string{"de": "Zweiter Weihnachtsfeiertag"}, dateFromNumbers(year, 12, 26)), - newHoliday("Good Friday", map[string]string{"de": "Karfreitag"}, GregorianEasterSunday(year).Add(-2*day)), - newHoliday("Easter Sunday", map[string]string{"de": "Ostersonntag"}, GregorianEasterSunday(year)), - newHoliday("Easter Monday", map[string]string{"de": "Ostermontag"}, GregorianEasterSunday(year).Add(1*day)), - newHoliday("Ascension Day", map[string]string{"de": "Christi Himmelfahrt"}, GregorianEasterSunday(year).Add(39*day)), - newHoliday("Whit Monday", map[string]string{"de": "Pfingstmontag"}, GregorianEasterSunday(year).Add(50*day)), +func (holidaysDE) GetIncludes() []string { return nil } +func (h holidaysDE) GetHolidays(year int) []Holiday { + var ( + neujahr = newHoliday("New Year's Day", map[string]string{"de": "Neujahrstag"}, dateFromNumbers(year, 1, 1)) + hlDreiKoenige = newHoliday("Epiphany", map[string]string{"de": "Heilige Drei Könige"}, dateFromNumbers(year, 1, 6)) + womansDay = newHoliday("International Women’s Day", map[string]string{"de": "Internationaler Frauentag"}, dateFromNumbers(year, 3, 8)) + tagDerArbeit = newHoliday("Labor Day", map[string]string{"de": "Tag der Arbeit"}, dateFromNumbers(year, 5, 1)) + marHimmelfahrt = newHoliday("Assumption of Mary", map[string]string{"de": "Mariä Himmelfahrt"}, dateFromNumbers(year, 8, 15)) + kinderTag = newHoliday("World Children's Day", map[string]string{"de": "Weltkindertag"}, dateFromNumbers(year, 9, 20)) + tagDerEinheit = newHoliday("German Unity Day", map[string]string{"de": "Tag der Deutschen Einheit"}, dateFromNumbers(year, 10, 3)) + reformationsTag = newHoliday("Reformation Day", map[string]string{"de": "Reformationstag"}, dateFromNumbers(year, 10, 31)) + allerheiligen = newHoliday("All Saints", map[string]string{"de": "Allerheiligen"}, dateFromNumbers(year, 11, 1)) + weihnacht1 = newHoliday("Christmas Day", map[string]string{"de": "Weihnachtstag"}, dateFromNumbers(year, 12, 25)) + weihnacht2 = newHoliday("Boxing Day", map[string]string{"de": "Zweiter Weihnachtsfeiertag"}, dateFromNumbers(year, 12, 26)) + + karfreitag = newHoliday("Good Friday", map[string]string{"de": "Karfreitag"}, GregorianEasterSunday(year).Add(-2*day)) + osterSonntag = newHoliday("Easter Sunday", map[string]string{"de": "Ostersonntag"}, GregorianEasterSunday(year)) + osterMontag = newHoliday("Easter Monday", map[string]string{"de": "Ostermontag"}, GregorianEasterSunday(year).Add(1*day)) + chrHimmelfahrt = newHoliday("Ascension Day", map[string]string{"de": "Christi Himmelfahrt"}, GregorianEasterSunday(year).Add(39*day)) + pfingstMontag = newHoliday("Whit Monday", map[string]string{"de": "Pfingstmontag"}, GregorianEasterSunday(year).Add(50*day)) + fronleichnam = newHoliday("Corpus Christi", map[string]string{"de": "Fronleichnam"}, GregorianEasterSunday(year).Add(60*day)) + + national = []Holiday{ + neujahr, tagDerArbeit, tagDerEinheit, weihnacht1, weihnacht2, + karfreitag, osterSonntag, osterMontag, chrHimmelfahrt, pfingstMontag, + } + states = map[string][]Holiday{ + "": national, + "bb": append(national, reformationsTag), + "be": append(national, womansDay), + "bw": append(national, hlDreiKoenige, fronleichnam, allerheiligen), + "by": append(national, hlDreiKoenige, fronleichnam, marHimmelfahrt, allerheiligen), + "hb": append(national, reformationsTag), + "he": append(national, fronleichnam), + "hh": append(national, reformationsTag), + "mv": append(national, reformationsTag), + "ni": append(national, reformationsTag), + "nw": append(national, fronleichnam, allerheiligen), + "rp": append(national, fronleichnam, allerheiligen), + "sh": append(national, reformationsTag), + "sl": append(national, fronleichnam, marHimmelfahrt, allerheiligen), + "sn": append(national, reformationsTag, h.getDRP(year)), + "st": append(national, hlDreiKoenige, reformationsTag), + "th": append(national, kinderTag, reformationsTag), + } + ) + + return states[h.state] +} + +func (holidaysDE) getDRP(year int) Holiday { + var ( + day time.Time + dayN = 16 + ) + + for { + day = dateFromNumbers(year, 11, dayN) + if day.Weekday() == time.Wednesday { + break + } + + dayN++ } + + return newHoliday("Day of Repentance and Prayer", map[string]string{"de": "Buß- und Bettag"}, day) } - -type holidaysDEBB struct{} - -func (h holidaysDEBB) GetIncludes() []string { return []string{"de"} } -func (h holidaysDEBB) GetHolidays(year int) []Holiday { - return []Holiday{ - newHoliday("Reformation Day", map[string]string{"de": "Reformationstag"}, dateFromNumbers(year, 10, 31)), - } -} - -type holidaysDEBE struct{ holidaysDENational } - -type holidaysDEBW struct{} - -func (h holidaysDEBW) GetIncludes() []string { return []string{"de"} } -func (h holidaysDEBW) GetHolidays(year int) []Holiday { - return []Holiday{ - newHoliday("Epiphany", map[string]string{"de": "Heilige Drei Könige"}, dateFromNumbers(year, 1, 6)), - newHoliday("All Saints", map[string]string{"de": "Allerheiligen"}, dateFromNumbers(year, 11, 1)), - newHoliday("Corpus Christi", map[string]string{"de": "Fronleichnam"}, GregorianEasterSunday(year).Add(60*day)), - } -} - -type holidaysDEBY struct{ holidaysDEBW } - -type holidaysDEHB struct{ holidaysDENational } - -type holidaysDEHE struct{} - -func (h holidaysDEHE) GetIncludes() []string { return []string{"de"} } -func (h holidaysDEHE) GetHolidays(year int) []Holiday { - return []Holiday{ - newHoliday("Corpus Christi", map[string]string{"de": "Fronleichnam"}, GregorianEasterSunday(year).Add(60*day)), - } -} - -type holidaysDEHH struct{ holidaysDENational } - -type holidaysDEMV struct{ holidaysDEBB } - -type holidaysDENI struct{ holidaysDENational } - -type holidaysDENW struct{} - -func (h holidaysDENW) GetIncludes() []string { return []string{"de"} } -func (h holidaysDENW) GetHolidays(year int) []Holiday { - return []Holiday{ - newHoliday("All Saints", map[string]string{"de": "Allerheiligen"}, dateFromNumbers(year, 11, 1)), - newHoliday("Corpus Christi", map[string]string{"de": "Fronleichnam"}, GregorianEasterSunday(year).Add(60*day)), - } -} - -type holidaysDERP struct{ holidaysDENW } - -type holidaysDESH struct{ holidaysDENational } - -type holidaysDESL struct{} - -func (h holidaysDESL) GetIncludes() []string { return []string{"de"} } -func (h holidaysDESL) GetHolidays(year int) []Holiday { - return []Holiday{ - newHoliday("Assumption Day", map[string]string{"de": "Mariä Himmelfahrt"}, dateFromNumbers(year, 8, 15)), - newHoliday("All Saints", map[string]string{"de": "Allerheiligen"}, dateFromNumbers(year, 11, 1)), - newHoliday("Corpus Christi", map[string]string{"de": "Fronleichnam"}, GregorianEasterSunday(year).Add(60*day)), - } -} - -type holidaysDESN struct{ holidaysDEBB } - -type holidaysDEST struct{} - -func (h holidaysDEST) GetIncludes() []string { return []string{"de"} } -func (h holidaysDEST) GetHolidays(year int) []Holiday { - return []Holiday{ - newHoliday("Epiphany", map[string]string{"de": "Heilige Drei Könige"}, dateFromNumbers(year, 1, 6)), - newHoliday("Reformation Day", map[string]string{"de": "Reformationstag"}, dateFromNumbers(year, 10, 31)), - } -} - -type holidaysDETH struct{ holidaysDEBB } diff --git a/holidays/holidays_de_test.go b/holidays/holidays_de_test.go new file mode 100644 index 0000000..2af89f2 --- /dev/null +++ b/holidays/holidays_de_test.go @@ -0,0 +1,23 @@ +package holidays + +import ( + "testing" + "time" +) + +func TestDRPDate(t *testing.T) { + for year, exp := range map[int]time.Time{ + 2021: dateFromNumbers(2021, 11, 17), + 2022: dateFromNumbers(2022, 11, 16), + 2023: dateFromNumbers(2023, 11, 22), + 2024: dateFromNumbers(2024, 11, 20), + 2025: dateFromNumbers(2025, 11, 19), + 2026: dateFromNumbers(2026, 11, 18), + 2027: dateFromNumbers(2027, 11, 17), + } { + h := holidaysDE{}.getDRP(year) + if !h.ParsedDate.Equal(exp) { + t.Errorf("DRP %d: Expected %s, got %s", year, exp, h.ParsedDate) + } + } +}