diff --git a/README.md b/README.md index d4c72d34c9..c9c2347327 100644 --- a/README.md +++ b/README.md @@ -726,7 +726,7 @@ any) in brackets, available languages and additional holiday categories. All cou DE States: BB (Brandenburg), BE (Berlin), BW (Baden-Württemberg), BY (Bayern), HB (Bremen), HE (Hessen), HH (Hamburg), MV (Mecklenburg-Vorpommern), NI (Niedersachsen), NW (Nordrhein-Westfalen), RP (Rheinland-Pfalz), SH (Schleswig-Holstein), SL (Saarland), SN (Sachsen), ST (Sachsen-Anhalt), TH (Thüringen); cities: Augsburg de, en_US, th, uk -CATHOLIC +CATHOLIC, SCHOOL Ghana diff --git a/holidays/countries/germany.py b/holidays/countries/germany.py index 5f9be24820..556d0b9492 100644 --- a/holidays/countries/germany.py +++ b/holidays/countries/germany.py @@ -10,10 +10,11 @@ # Website: https://github.com/vacanza/holidays # License: MIT (see LICENSE file) +from datetime import date, timedelta from gettext import gettext as tr from holidays.calendars.gregorian import MAY, JUN, OCT -from holidays.constants import CATHOLIC, PUBLIC +from holidays.constants import CATHOLIC, PUBLIC, SCHOOL from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays from holidays.holiday_base import HolidayBase @@ -43,7 +44,23 @@ class Germany(HolidayBase, ChristianHolidays, InternationalHolidays, StaticHolid * [Sachsen](https://web.archive.org/web/20250808020452/https://www.revosax.sachsen.de/vorschrift/3997-SaechsSFG) * [Sachsen-Anhalt](https://web.archive.org/web/20250615214949/http://www.landesrecht.sachsen-anhalt.de/bsst/document/jlr-FeiertGSTpP2) * [Thüringen](https://web.archive.org/web/20250712163548/http://landesrecht.thueringen.de/bsth/document/jlr-FeiertGTHV5P2) - + School Holiday References: + * [Brandenburg](https://bravors.brandenburg.de/sixcms/media.php/66/VV-Schulbetrieb-Anlage-1-2025.pdf) + * [Berlin](https://www.berlin.de/sen/bjf/service/kalender/ferien/ferienordnung-des-landes-berlin-2024_2025-bis-2029_2030.pdf?ts=1752674587) + * [Baden-Württemberg](https://km.baden-wuerttemberg.de/de/service/ferien) + * [Bayern](https://www.verkuendung-bayern.de/baymbl/2022-747/) + * [Bremen](https://www.bildung.bremen.de/ferientermine-3404) + * [Hessen](https://kultus.hessen.de/Schulsystem/Ferien/Ferientermine) + * [Hamburg](https://www.hamburg.de/resource/blob/134372/5bc131bdd36a604f67b361d21f7df37e/ferienordnung-hamburg-2024-2030-data.pdf) + * [Mecklenburg-Vorpommern](https://www.landesrecht-mv.de/bsmv/document/jlr-AFer2024-2030VMVrahmen) + * [Niedersachsen](https://www.mk.niedersachsen.de/download/98089/Ferienuebersicht_fuer_Niedersachsen_Schuljahr_2024_25_-_2029_30.pdf) + * [Nordrhein-Westfalen(https://www.schulministerium.nrw/service/ferienordnung-fuer-nordrhein-westfalen-fuer-die-schuljahre-bis-202930) + * [Rheinland-Pfalz](https://bm.rlp.de/service/ferientermine) + * [Schleswig-Holstein](https://www.schleswig-holstein.de/DE/landesregierung/themen/bildung-hochschulen/ferientermine/ferientermine_node.html) + * [Saarland](https://www.saarland.de/SharedDocs/Downloads/DE/mbk/Bildungsserver/allgemeine-informationen/ferienordnung_ab_2024_amtsblatt.pdf?__blob=publicationFile&v=1) + * [Sachsen](https://www.schule.sachsen.de/schuljahrestermine-4793.html) + * [Sachsen-Anhalt](https://mb.sachsen-anhalt.de/fileadmin/Bibliothek/Landesjournal/Bildung_und_Wissenschaft/Erlasse/Ferienregelung_2024_bis_2030.pdf) + * [Thüringen](https://bildung.thueringen.de/schule/schulwesen/ferien) !!! note "Note" "Mariä Himmelfahrt" is only a holiday in Bavaria (BY) and "Fronleichnam" in Saxony (SN) and Thuringia (TH) if municipality is mostly catholic which @@ -93,7 +110,7 @@ class Germany(HolidayBase, ChristianHolidays, InternationalHolidays, StaticHolid "Sachsen-Anhalt": "ST", "Thüringen": "TH", } - supported_categories = (CATHOLIC, PUBLIC) + supported_categories = (CATHOLIC, PUBLIC, SCHOOL) supported_languages = ("de", "en_US", "th", "uk") _deprecated_subdivisions = ("BYP",) @@ -102,6 +119,1200 @@ def __init__(self, *args, **kwargs) -> None: InternationalHolidays.__init__(self) StaticHolidays.__init__(self, GermanyStaticHolidays) super().__init__(*args, **kwargs) + # Disable automatic expansion after initial population to avoid + # implicitly populating adjacent years when checking membership + # (keeps per-year population semantics for school holiday checks). + self.expand = False + + def _add_school_holidays_hh(self, year): + # Helper to add a range of holidays + def _add_holiday_range(name, start_date, end_date): + current_date = start_date + while current_date <= end_date: + if current_date.year == self._year: + # Ensure holiday is added for the populated year by passing + # month and day to _add_holiday so it constructs the date + # using `self._year` (prevents cross-year leakage). + self._add_holiday(name, current_date.month, current_date.day) + current_date += timedelta(days=1) + + # Definition of holidays as (Name, Start Date, End Date) + # For single days, Start Date == End Date + holidays_map = [] + + if year == 2025: + holidays_map = [ + (tr("Weihnachtsferien"), date(2025, 12, 17), date(2025, 12, 31)), + ] + elif year == 2026: + holidays_map = [ + (tr("Weihnachtsferien"), date(2026, 1, 1), date(2026, 1, 2)), + (tr("Halbjahrespause"), date(2026, 1, 30), date(2026, 1, 30)), + (tr("Frühjahrsferien"), date(2026, 3, 2), date(2026, 3, 13)), + (tr("Himmelfahrt/Pfingsten"), date(2026, 5, 11), date(2026, 5, 15)), + (tr("Sommerferien"), date(2026, 7, 9), date(2026, 8, 19)), + (tr("Herbstferien"), date(2026, 10, 19), date(2026, 10, 30)), + (tr("Weihnachtsferien"), date(2026, 12, 21), date(2026, 12, 31)), + ] + elif year == 2027: + holidays_map = [ + (tr("Weihnachtsferien"), date(2027, 1, 1), date(2027, 1, 1)), + (tr("Halbjahrespause"), date(2027, 1, 29), date(2027, 1, 29)), + (tr("Frühjahrsferien"), date(2027, 3, 1), date(2027, 3, 12)), + (tr("Himmelfahrt/Pfingsten"), date(2027, 5, 7), date(2027, 5, 14)), + (tr("Sommerferien"), date(2027, 7, 1), date(2027, 8, 11)), + (tr("Herbstferien"), date(2027, 10, 11), date(2027, 10, 22)), + (tr("Weihnachtsferien"), date(2027, 12, 20), date(2027, 12, 31)), + ] + elif year == 2028: + holidays_map = [ + (tr("Halbjahrespause"), date(2028, 1, 28), date(2028, 1, 28)), + (tr("Frühjahrsferien"), date(2028, 3, 6), date(2028, 3, 17)), + (tr("Himmelfahrt/Pfingsten"), date(2028, 5, 22), date(2028, 5, 26)), + (tr("Sommerferien"), date(2028, 7, 3), date(2028, 8, 11)), + (tr("Herbstferien"), date(2028, 10, 2), date(2028, 10, 13)), + (tr("Brückentag"), date(2028, 10, 30), date(2028, 10, 30)), + (tr("Weihnachtsferien"), date(2028, 12, 18), date(2028, 12, 29)), + ] + elif year == 2029: + holidays_map = [ + (tr("Halbjahrespause"), date(2029, 2, 2), date(2029, 2, 2)), + (tr("Frühjahrsferien"), date(2029, 3, 5), date(2029, 3, 16)), + (tr("Himmelfahrt/Pfingsten"), date(2029, 5, 11), date(2029, 5, 18)), + (tr("Sommerferien"), date(2029, 7, 2), date(2029, 8, 10)), + (tr("Herbstferien"), date(2029, 10, 1), date(2029, 10, 12)), + (tr("Weihnachtsferien"), date(2029, 12, 21), date(2029, 12, 31)), + ] + elif year == 2030: + holidays_map = [ + (tr("Weihnachtsferien"), date(2030, 1, 1), date(2030, 1, 4)), + (tr("Halbjahrespause"), date(2030, 2, 1), date(2030, 2, 1)), + (tr("Frühjahrsferien"), date(2030, 3, 4), date(2030, 3, 15)), + (tr("Himmelfahrt/Pfingsten"), date(2030, 5, 20), date(2030, 5, 24)), + (tr("Brückentag"), date(2030, 5, 31), date(2030, 5, 31)), + (tr("Sommerferien"), date(2030, 7, 4), date(2030, 8, 14)), + ] + + for name, start, end in holidays_map: + _add_holiday_range(name, start, end) + + def _add_school_holidays_nw(self, year): + # Helper to add a range of holidays for Nordrhein-Westfalen (NW) + def _add_holiday_range(name, start_date, end_date): + current_date = start_date + while current_date <= end_date: + if current_date.year == self._year: + self._add_holiday(name, current_date.month, current_date.day) + current_date += timedelta(days=1) + + holidays_map = [] + + if year == 2025: + holidays_map = [ + (tr("Weihnachtsferien"), date(2025, 12, 22), date(2025, 12, 31)), + ] + elif year == 2026: + holidays_map = [ + (tr("Weihnachtsferien"), date(2026, 1, 1), date(2026, 1, 6)), + (tr("Sommerferien"), date(2026, 7, 20), date(2026, 9, 1)), + (tr("Herbstferien"), date(2026, 10, 17), date(2026, 10, 31)), + (tr("Weihnachtsferien"), date(2026, 12, 23), date(2026, 12, 31)), + ] + elif year == 2027: + holidays_map = [ + (tr("Osterferien"), date(2027, 3, 22), date(2027, 4, 3)), + (tr("Pfingsten"), date(2027, 5, 18), date(2027, 5, 18)), + (tr("Sommerferien"), date(2027, 7, 19), date(2027, 8, 31)), + (tr("Herbstferien"), date(2027, 10, 23), date(2027, 11, 6)), + (tr("Weihnachtsferien"), date(2027, 12, 24), date(2027, 12, 31)), + ] + elif year == 2028: + holidays_map = [ + (tr("Osterferien"), date(2028, 4, 10), date(2028, 4, 22)), + (tr("Sommerferien"), date(2028, 7, 10), date(2028, 8, 22)), + (tr("Herbstferien"), date(2028, 10, 23), date(2028, 11, 4)), + (tr("Weihnachtsferien"), date(2028, 12, 21), date(2028, 12, 31)), + ] + elif year == 2029: + holidays_map = [ + (tr("Osterferien"), date(2029, 3, 26), date(2029, 4, 7)), + (tr("Pfingsten"), date(2029, 5, 22), date(2029, 5, 22)), + (tr("Sommerferien"), date(2029, 7, 2), date(2029, 8, 14)), + (tr("Herbstferien"), date(2029, 10, 15), date(2029, 10, 27)), + (tr("Weihnachtsferien"), date(2029, 12, 20), date(2029, 12, 31)), + ] + elif year == 2030: + holidays_map = [ + (tr("Osterferien"), date(2030, 4, 15), date(2030, 4, 27)), + ] + + for name, start, end in holidays_map: + _add_holiday_range(name, start, end) + + def _add_school_holidays_rp(self, year): + # Helper to add a range of holidays for Rheinland-Pfalz (RP) + def _add_holiday_range(name, start_date, end_date): + current_date = start_date + while current_date <= end_date: + if current_date.year == self._year: + self._add_holiday(name, current_date.month, current_date.day) + current_date += timedelta(days=1) + + holidays_map = [] + + if year == 2025: + holidays_map = [ + (tr("Sommerferien"), date(2025, 7, 7), date(2025, 8, 16)), + (tr("Herbstferien"), date(2025, 10, 13), date(2025, 10, 25)), + (tr("Weihnachtsferien"), date(2025, 12, 22), date(2025, 12, 31)), + ] + elif year == 2026: + holidays_map = [ + (tr("Weihnachtsferien"), date(2026, 1, 1), date(2026, 1, 8)), + (tr("Osterferien"), date(2026, 3, 30), date(2026, 4, 11)), + (tr("Sommerferien"), date(2026, 6, 29), date(2026, 8, 8)), + (tr("Herbstferien"), date(2026, 10, 5), date(2026, 10, 17)), + (tr("Weihnachtsferien"), date(2026, 12, 23), date(2026, 12, 31)), + ] + elif year == 2027: + holidays_map = [ + (tr("Weihnachtsferien"), date(2027, 1, 1), date(2027, 1, 9)), + (tr("Osterferien"), date(2027, 3, 22), date(2027, 4, 3)), + (tr("Sommerferien"), date(2027, 6, 28), date(2027, 8, 7)), + (tr("Herbstferien"), date(2027, 10, 4), date(2027, 10, 16)), + (tr("Weihnachtsferien"), date(2027, 12, 23), date(2027, 12, 31)), + ] + elif year == 2028: + holidays_map = [ + (tr("Weihnachtsferien"), date(2028, 1, 1), date(2028, 1, 8)), + (tr("Osterferien"), date(2028, 4, 10), date(2028, 4, 22)), + (tr("Sommerferien"), date(2028, 7, 3), date(2028, 8, 12)), + (tr("Herbstferien"), date(2028, 10, 9), date(2028, 10, 21)), + (tr("Weihnachtsferien"), date(2028, 12, 21), date(2028, 12, 31)), + ] + elif year == 2029: + holidays_map = [ + (tr("Weihnachtsferien"), date(2029, 1, 1), date(2029, 1, 9)), + (tr("Osterferien"), date(2029, 3, 26), date(2029, 4, 7)), + (tr("Sommerferien"), date(2029, 7, 16), date(2029, 8, 25)), + (tr("Herbstferien"), date(2029, 10, 22), date(2029, 11, 3)), + (tr("Weihnachtsferien"), date(2029, 12, 24), date(2029, 12, 31)), + ] + elif year == 2030: + holidays_map = [ + (tr("Weihnachtsferien"), date(2030, 1, 1), date(2030, 1, 10)), + (tr("Osterferien"), date(2030, 4, 15), date(2030, 5, 1)), + ] + + for name, start, end in holidays_map: + _add_holiday_range(name, start, end) + + def _add_school_holidays_hb(self, year): + # Helper to add a range of holidays for Bremen (HB) + def _add_holiday_range(name, start_date, end_date): + current_date = start_date + while current_date <= end_date: + if current_date.year == self._year: + self._add_holiday(name, current_date.month, current_date.day) + current_date += timedelta(days=1) + + holidays_map = [] + + if year == 2025: + holidays_map = [ + (tr("Weihnachtsferien"), date(2025, 12, 22), date(2025, 12, 31)), + ] + elif year == 2026: + holidays_map = [ + (tr("Weihnachtsferien"), date(2026, 1, 1), date(2026, 1, 5)), + (tr("Halbjahresferien"), date(2026, 2, 2), date(2026, 2, 3)), + (tr("Osterferien"), date(2026, 3, 23), date(2026, 4, 7)), + (tr("Tag nach Himmelfahrt"), date(2026, 5, 15), date(2026, 5, 15)), + (tr("Pfingsten"), date(2026, 5, 26), date(2026, 5, 26)), + (tr("Sommerferien"), date(2026, 7, 2), date(2026, 8, 12)), + (tr("Herbstferien"), date(2026, 10, 12), date(2026, 10, 24)), + (tr("Weihnachtsferien"), date(2026, 12, 23), date(2026, 12, 31)), + ] + elif year == 2027: + holidays_map = [ + (tr("Weihnachtsferien"), date(2027, 1, 1), date(2027, 1, 9)), + (tr("Halbjahresferien"), date(2027, 2, 1), date(2027, 2, 2)), + (tr("Osterferien"), date(2027, 3, 22), date(2027, 4, 3)), + (tr("Tag nach Himmelfahrt"), date(2027, 5, 7), date(2027, 5, 7)), + (tr("Pfingsten"), date(2027, 5, 18), date(2027, 5, 18)), + (tr("Sommerferien"), date(2027, 7, 8), date(2027, 8, 18)), + (tr("Herbstferien"), date(2027, 10, 18), date(2027, 10, 30)), + (tr("Weihnachtsferien"), date(2027, 12, 23), date(2027, 12, 31)), + ] + elif year == 2028: + holidays_map = [ + (tr("Weihnachtsferien"), date(2028, 1, 1), date(2028, 1, 8)), + (tr("Halbjahresferien"), date(2028, 1, 31), date(2028, 2, 1)), + (tr("Osterferien"), date(2028, 4, 10), date(2028, 4, 22)), + (tr("Tag nach Himmelfahrt"), date(2028, 5, 26), date(2028, 5, 26)), + (tr("Pfingsten"), date(2028, 6, 6), date(2028, 6, 6)), + (tr("Sommerferien"), date(2028, 7, 20), date(2028, 8, 30)), + (tr("Tag vor dem 03. Oktober"), date(2028, 10, 2), date(2028, 10, 2)), + (tr("Herbstferien"), date(2028, 10, 23), date(2028, 11, 4)), + (tr("Weihnachtsferien"), date(2028, 12, 27), date(2028, 12, 31)), + ] + elif year == 2029: + holidays_map = [ + (tr("Weihnachtsferien"), date(2029, 1, 1), date(2029, 1, 6)), + (tr("Halbjahresferien"), date(2029, 2, 1), date(2029, 2, 2)), + (tr("Osterferien"), date(2029, 3, 19), date(2029, 4, 3)), + (tr("Tag vor dem 01. Mai"), date(2029, 4, 30), date(2029, 4, 30)), + (tr("Tag nach Himmelfahrt"), date(2029, 5, 11), date(2029, 5, 11)), + (tr("Pfingsten"), date(2029, 5, 22), date(2029, 5, 22)), + (tr("Sommerferien"), date(2029, 7, 19), date(2029, 8, 29)), + (tr("Tage nach dem 03. Oktober"), date(2029, 10, 4), date(2029, 10, 5)), + (tr("Herbstferien"), date(2029, 10, 22), date(2029, 11, 2)), + (tr("Weihnachtsferien"), date(2029, 12, 21), date(2029, 12, 31)), + ] + elif year == 2030: + holidays_map = [ + (tr("Weihnachtsferien"), date(2030, 1, 1), date(2030, 1, 5)), + (tr("Halbjahresferien"), date(2030, 1, 31), date(2030, 2, 1)), + (tr("Osterferien"), date(2030, 4, 8), date(2030, 4, 23)), + (tr("Tag nach Himmelfahrt"), date(2030, 5, 31), date(2030, 5, 31)), + (tr("Pfingsten"), date(2030, 6, 11), date(2030, 6, 11)), + (tr("Sommerferien"), date(2030, 7, 11), date(2030, 8, 21)), + ] + + for name, start, end in holidays_map: + _add_holiday_range(name, start, end) + + def _add_school_holidays_sl(self, year): + # Helper to add a range of holidays for Saarland (SL) + def _add_holiday_range(name, start_date, end_date): + current_date = start_date + while current_date <= end_date: + if current_date.year == self._year: + self._add_holiday(name, current_date.month, current_date.day) + current_date += timedelta(days=1) + + holidays_map = [] + + if year == 2025: + holidays_map = [ + (tr("Weihnachtsferien"), date(2025, 12, 22), date(2025, 12, 31)), + ] + elif year == 2026: + holidays_map = [ + (tr("Weihnachtsferien"), date(2026, 1, 1), date(2026, 1, 2)), + (tr("Fastnachtsferien"), date(2026, 2, 16), date(2026, 2, 20)), + (tr("Osterferien"), date(2026, 4, 7), date(2026, 4, 17)), + (tr("Sommerferien"), date(2026, 6, 29), date(2026, 8, 7)), + (tr("Herbstferien"), date(2026, 10, 5), date(2026, 10, 16)), + (tr("Weihnachtsferien"), date(2026, 12, 21), date(2026, 12, 31)), + ] + elif year == 2027: + holidays_map = [ + (tr("Fastnachtsferien"), date(2027, 2, 8), date(2027, 2, 12)), + (tr("Osterferien"), date(2027, 3, 30), date(2027, 4, 9)), + (tr("Sommerferien"), date(2027, 6, 28), date(2027, 8, 6)), + (tr("Herbstferien"), date(2027, 10, 4), date(2027, 10, 15)), + (tr("Weihnachtsferien"), date(2027, 12, 20), date(2027, 12, 31)), + ] + elif year == 2028: + holidays_map = [ + (tr("Fastnachtsferien"), date(2028, 2, 21), date(2028, 2, 29)), + (tr("Osterferien"), date(2028, 4, 12), date(2028, 4, 21)), + (tr("Sommerferien"), date(2028, 7, 3), date(2028, 8, 11)), + (tr("Herbstferien"), date(2028, 10, 9), date(2028, 10, 20)), + (tr("Weihnachtsferien"), date(2028, 12, 20), date(2028, 12, 31)), + ] + elif year == 2029: + holidays_map = [ + (tr("Weihnachtsferien"), date(2029, 1, 1), date(2029, 1, 2)), + (tr("Fastnachtsferien"), date(2029, 2, 12), date(2029, 2, 16)), + (tr("Osterferien"), date(2029, 3, 26), date(2029, 4, 6)), + (tr("Pfingstferien"), date(2029, 5, 22), date(2029, 5, 25)), + (tr("Sommerferien"), date(2029, 7, 16), date(2029, 8, 24)), + (tr("Herbstferien"), date(2029, 10, 22), date(2029, 11, 2)), + (tr("Weihnachtsferien"), date(2029, 12, 21), date(2029, 12, 31)), + ] + elif year == 2030: + holidays_map = [ + (tr("Weihnachtsferien"), date(2030, 1, 1), date(2030, 1, 4)), + (tr("Fastnachtsferien"), date(2030, 2, 25), date(2030, 3, 5)), + (tr("Osterferien"), date(2030, 4, 15), date(2030, 4, 26)), + (tr("Sommerferien"), date(2030, 7, 22), date(2030, 8, 30)), + ] + + for name, start, end in holidays_map: + _add_holiday_range(name, start, end) + + def _add_school_holidays_th(self, year): + # Helper to add a range of holidays for Thüringen (TH) + def _add_holiday_range(name, start_date, end_date): + current_date = start_date + while current_date <= end_date: + if current_date.year == self._year: + self._add_holiday(name, current_date.month, current_date.day) + current_date += timedelta(days=1) + + holidays_map = [] + + if year == 2025: + holidays_map = [ + (tr("Weihnachtsferien"), date(2025, 12, 22), date(2025, 12, 31)), + ] + elif year == 2026: + holidays_map = [ + (tr("Weihnachtsferien"), date(2026, 1, 1), date(2026, 1, 3)), + (tr("Winterferien"), date(2026, 2, 16), date(2026, 2, 21)), + (tr("Osterferien"), date(2026, 4, 7), date(2026, 4, 17)), + (tr("Schulfreier Tag"), date(2026, 5, 15), date(2026, 5, 15)), + (tr("Sommerferien"), date(2026, 7, 4), date(2026, 8, 14)), + (tr("Herbstferien"), date(2026, 10, 12), date(2026, 10, 24)), + (tr("Weihnachtsferien"), date(2026, 12, 23), date(2026, 12, 31)), + ] + elif year == 2027: + holidays_map = [ + (tr("Weihnachtsferien"), date(2027, 1, 1), date(2027, 1, 2)), + (tr("Winterferien"), date(2027, 2, 1), date(2027, 2, 6)), + (tr("Osterferien"), date(2027, 3, 22), date(2027, 4, 3)), + (tr("Schulfreier Tag"), date(2027, 5, 7), date(2027, 5, 7)), + (tr("Sommerferien"), date(2027, 7, 10), date(2027, 8, 20)), + (tr("Herbstferien"), date(2027, 10, 9), date(2027, 10, 23)), + (tr("Weihnachtsferien"), date(2027, 12, 23), date(2027, 12, 31)), + ] + elif year == 2028: + holidays_map = [ + (tr("Winterferien"), date(2028, 2, 7), date(2028, 2, 12)), + (tr("Osterferien"), date(2028, 4, 3), date(2028, 4, 15)), + (tr("Schulfreier Tag"), date(2028, 5, 26), date(2028, 5, 26)), + (tr("Sommerferien"), date(2028, 7, 22), date(2028, 9, 1)), + (tr("Herbstferien"), date(2028, 10, 23), date(2028, 11, 3)), + (tr("Weihnachtsferien"), date(2028, 12, 23), date(2028, 12, 31)), + ] + elif year == 2029: + holidays_map = [ + (tr("Weihnachtsferien"), date(2029, 1, 1), date(2029, 1, 5)), + (tr("Winterferien"), date(2029, 2, 12), date(2029, 2, 17)), + (tr("Osterferien"), date(2029, 3, 26), date(2029, 4, 7)), + (tr("Schulfreier Tag"), date(2029, 5, 11), date(2029, 5, 11)), + (tr("Sommerferien"), date(2029, 7, 21), date(2029, 8, 31)), + (tr("Herbstferien"), date(2029, 10, 22), date(2029, 11, 3)), + (tr("Weihnachtsferien"), date(2029, 12, 22), date(2029, 12, 31)), + ] + elif year == 2030: + holidays_map = [ + (tr("Weihnachtsferien"), date(2030, 1, 1), date(2030, 1, 4)), + (tr("Winterferien"), date(2030, 2, 11), date(2030, 2, 16)), + (tr("Osterferien"), date(2030, 4, 8), date(2030, 4, 20)), + (tr("Schulfreier Tag"), date(2030, 5, 31), date(2030, 5, 31)), + (tr("Sommerferien"), date(2030, 7, 13), date(2030, 8, 23)), + ] + + for name, start, end in holidays_map: + _add_holiday_range(name, start, end) + + def _add_school_holidays_sh(self, year): + # Helper to add a range of holidays for Schleswig-Holstein (SH) + def _add_holiday_range(name, start_date, end_date): + current_date = start_date + while current_date <= end_date: + if current_date.year == self._year: + self._add_holiday(name, current_date.month, current_date.day) + current_date += timedelta(days=1) + + holidays_map = [] + + if year == 2025: + holidays_map = [ + (tr("Weihnachtsferien"), date(2025, 12, 19), date(2025, 12, 31)), + ] + elif year == 2026: + holidays_map = [ + (tr("Weihnachtsferien"), date(2026, 1, 1), date(2026, 1, 6)), + (tr("Osterferien"), date(2026, 3, 26), date(2026, 4, 10)), + (tr("Himmelfahrt"), date(2026, 5, 15), date(2026, 5, 15)), + (tr("Sommerferien"), date(2026, 7, 4), date(2026, 8, 15)), + (tr("Herbstferien"), date(2026, 10, 12), date(2026, 10, 24)), + (tr("Weihnachtsferien"), date(2026, 12, 21), date(2026, 12, 31)), + ] + elif year == 2027: + holidays_map = [ + (tr("Osterferien"), date(2027, 3, 30), date(2027, 4, 10)), + (tr("Himmelfahrt"), date(2027, 5, 7), date(2027, 5, 7)), + (tr("Sommerferien"), date(2027, 7, 3), date(2027, 8, 14)), + (tr("Herbstferien"), date(2027, 10, 11), date(2027, 10, 23)), + (tr("Weihnachtsferien"), date(2027, 12, 23), date(2027, 12, 31)), + ] + elif year == 2028: + holidays_map = [ + (tr("Weihnachtsferien"), date(2028, 1, 1), date(2028, 1, 8)), + (tr("Osterferien"), date(2028, 4, 3), date(2028, 4, 15)), + (tr("Himmelfahrt"), date(2028, 5, 26), date(2028, 5, 26)), + (tr("Sommerferien"), date(2028, 6, 24), date(2028, 8, 4)), + (tr("Herbstferien"), date(2028, 10, 16), date(2028, 10, 30)), + (tr("Weihnachtsferien"), date(2028, 12, 21), date(2028, 12, 31)), + ] + elif year == 2029: + holidays_map = [ + (tr("Osterferien"), date(2029, 3, 23), date(2029, 4, 6)), + (tr("Himmelfahrt"), date(2029, 5, 11), date(2029, 5, 11)), + (tr("Sommerferien"), date(2029, 6, 23), date(2029, 8, 3)), + (tr("Herbstferien"), date(2029, 10, 8), date(2029, 10, 19)), + (tr("Weihnachtsferien"), date(2029, 12, 21), date(2029, 12, 31)), + ] + elif year == 2030: + holidays_map = [ + (tr("Weihnachtsferien"), date(2030, 1, 1), date(2030, 1, 8)), + (tr("Osterferien"), date(2030, 4, 8), date(2030, 4, 20)), + (tr("Himmelfahrt"), date(2030, 5, 31), date(2030, 5, 31)), + (tr("Sommerferien"), date(2030, 7, 8), date(2030, 8, 17)), + (tr("Herbstferien"), date(2030, 10, 14), date(2030, 10, 25)), + (tr("Weihnachtsferien"), date(2030, 12, 20), date(2030, 12, 31)), + ] + elif year == 2031: + holidays_map = [ + (tr("Osterferien"), date(2031, 3, 28), date(2031, 4, 10)), + (tr("Himmelfahrt"), date(2031, 5, 23), date(2031, 5, 23)), + (tr("Weihnachtsferien"), date(2031, 1, 1), date(2031, 1, 6)), + ] + + for name, start, end in holidays_map: + _add_holiday_range(name, start, end) + + def _add_school_holidays_sn(self, year): + # Helper to add a range of holidays for Sachsen (SN) + def _add_holiday_range(name, start_date, end_date): + current_date = start_date + while current_date <= end_date: + if current_date.year == self._year: + self._add_holiday(name, current_date.month, current_date.day) + current_date += timedelta(days=1) + + holidays_map = [] + + if year == 2025: + holidays_map = [ + (tr("Weihnachtsferien"), date(2025, 12, 22), date(2025, 12, 31)), + ] + elif year == 2026: + holidays_map = [ + (tr("Weihnachtsferien"), date(2026, 1, 1), date(2026, 1, 2)), + (tr("Winterferien"), date(2026, 2, 9), date(2026, 2, 21)), + (tr("Osterferien"), date(2026, 4, 3), date(2026, 4, 10)), + (tr("Sommerferien"), date(2026, 7, 4), date(2026, 8, 14)), + (tr("Unterrichtsfreier Tag"), date(2026, 5, 15), date(2026, 5, 15)), + (tr("Herbstferien"), date(2026, 10, 12), date(2026, 10, 24)), + (tr("Weihnachtsferien"), date(2026, 12, 23), date(2026, 12, 31)), + ] + elif year == 2027: + holidays_map = [ + (tr("Weihnachtsferien"), date(2027, 1, 1), date(2027, 1, 2)), + (tr("Winterferien"), date(2027, 2, 8), date(2027, 2, 19)), + (tr("Osterferien"), date(2027, 3, 26), date(2027, 4, 2)), + (tr("Pfingstferien"), date(2027, 5, 15), date(2027, 5, 18)), + (tr("Unterrichtsfreier Tag"), date(2027, 5, 7), date(2027, 5, 7)), + (tr("Sommerferien"), date(2027, 7, 10), date(2027, 8, 20)), + (tr("Herbstferien"), date(2027, 10, 11), date(2027, 10, 23)), + (tr("Weihnachtsferien"), date(2027, 12, 23), date(2027, 12, 31)), + ] + elif year == 2028: + holidays_map = [ + (tr("Weihnachtsferien"), date(2028, 1, 1), date(2028, 1, 1)), + (tr("Winterferien"), date(2028, 2, 14), date(2028, 2, 26)), + (tr("Osterferien"), date(2028, 4, 14), date(2028, 4, 22)), + (tr("Unterrichtsfreier Tag"), date(2028, 5, 26), date(2028, 5, 26)), + (tr("Sommerferien"), date(2028, 7, 22), date(2028, 9, 1)), + (tr("Herbstferien"), date(2028, 10, 23), date(2028, 11, 3)), + (tr("Weihnachtsferien"), date(2028, 12, 23), date(2028, 12, 31)), + ] + elif year == 2029: + holidays_map = [ + (tr("Weihnachtsferien"), date(2029, 1, 1), date(2029, 1, 1)), + (tr("Winterferien"), date(2029, 2, 5), date(2029, 2, 16)), + (tr("Osterferien"), date(2029, 3, 29), date(2029, 4, 6)), + (tr("Pfingstferien"), date(2029, 5, 19), date(2029, 5, 22)), + (tr("Unterrichtsfreier Tag"), date(2029, 5, 11), date(2029, 5, 11)), + (tr("Sommerferien"), date(2029, 7, 21), date(2029, 8, 31)), + (tr("Herbstferien"), date(2029, 10, 22), date(2029, 11, 2)), + (tr("Weihnachtsferien"), date(2029, 12, 22), date(2029, 12, 31)), + ] + elif year == 2030: + holidays_map = [ + (tr("Weihnachtsferien"), date(2030, 1, 1), date(2030, 1, 4)), + (tr("Winterferien"), date(2030, 2, 18), date(2030, 3, 1)), + (tr("Osterferien"), date(2030, 4, 19), date(2030, 4, 26)), + (tr("Pfingstferien"), date(2030, 6, 8), date(2030, 6, 11)), + (tr("Unterrichtsfreier Tag"), date(2030, 5, 31), date(2030, 5, 31)), + (tr("Sommerferien"), date(2030, 7, 13), date(2030, 8, 23)), + ] + + for name, start, end in holidays_map: + _add_holiday_range(name, start, end) + + def _add_school_holidays_st(self, year): + # Helper to add a range of holidays for Sachsen-Anhalt (ST) + def _add_holiday_range(name, start_date, end_date): + current_date = start_date + while current_date <= end_date: + if current_date.year == self._year: + self._add_holiday(name, current_date.month, current_date.day) + current_date += timedelta(days=1) + + holidays_map = [] + + if year == 2025: + holidays_map = [ + (tr("Weihnachtsferien"), date(2025, 12, 22), date(2025, 12, 31)), + ] + elif year == 2026: + holidays_map = [ + (tr("Weihnachtsferien"), date(2026, 1, 1), date(2026, 1, 5)), + (tr("Winterferien"), date(2026, 1, 31), date(2026, 2, 6)), + (tr("Osterferien"), date(2026, 3, 30), date(2026, 4, 4)), + (tr("Pfingstferien"), date(2026, 5, 26), date(2026, 5, 29)), + (tr("Sommerferien"), date(2026, 7, 4), date(2026, 8, 14)), + (tr("Herbstferien"), date(2026, 10, 19), date(2026, 10, 30)), + (tr("Weihnachtsferien"), date(2026, 12, 21), date(2026, 12, 31)), + ] + elif year == 2027: + holidays_map = [ + (tr("Weihnachtsferien"), date(2027, 1, 1), date(2027, 1, 5)), + (tr("Winterferien"), date(2027, 2, 1), date(2027, 2, 6)), + (tr("Osterferien"), date(2027, 3, 22), date(2027, 3, 27)), + (tr("Pfingstferien"), date(2027, 5, 15), date(2027, 5, 22)), + (tr("Sommerferien"), date(2027, 7, 10), date(2027, 8, 20)), + (tr("Herbstferien"), date(2027, 10, 18), date(2027, 10, 23)), + (tr("Weihnachtsferien"), date(2027, 12, 20), date(2027, 12, 31)), + ] + elif year == 2028: + holidays_map = [ + (tr("Winterferien"), date(2028, 2, 7), date(2028, 2, 12)), + (tr("Osterferien"), date(2028, 4, 10), date(2028, 4, 22)), + (tr("Pfingstferien"), date(2028, 6, 3), date(2028, 6, 10)), + (tr("Sommerferien"), date(2028, 7, 22), date(2028, 9, 1)), + (tr("Beweglicher Ferientag"), date(2028, 10, 2), date(2028, 10, 2)), + (tr("Herbstferien"), date(2028, 10, 30), date(2028, 11, 3)), + (tr("Weihnachtsferien"), date(2028, 12, 21), date(2028, 12, 31)), + ] + elif year == 2029: + holidays_map = [ + (tr("Weihnachtsferien"), date(2029, 1, 1), date(2029, 1, 5)), + (tr("Winterferien"), date(2029, 2, 5), date(2029, 2, 10)), + (tr("Osterferien"), date(2029, 3, 26), date(2029, 3, 31)), + (tr("Beweglicher Ferientag"), date(2029, 4, 30), date(2029, 4, 30)), + (tr("Pfingstferien"), date(2029, 5, 11), date(2029, 5, 25)), + (tr("Sommerferien"), date(2029, 7, 21), date(2029, 8, 31)), + (tr("Herbstferien"), date(2029, 10, 29), date(2029, 11, 2)), + (tr("Weihnachtsferien"), date(2029, 12, 21), date(2029, 12, 31)), + ] + elif year == 2030: + holidays_map = [ + (tr("Weihnachtsferien"), date(2030, 1, 1), date(2030, 1, 5)), + (tr("Winterferien"), date(2030, 2, 4), date(2030, 2, 8)), + (tr("Osterferien"), date(2030, 4, 8), date(2030, 4, 20)), + (tr("Beweglicher Ferientag"), date(2030, 5, 31), date(2030, 5, 31)), + (tr("Pfingstferien"), date(2030, 6, 3), date(2030, 6, 8)), + (tr("Sommerferien"), date(2030, 7, 13), date(2030, 8, 23)), + ] + + for name, start, end in holidays_map: + _add_holiday_range(name, start, end) + + def _add_school_holidays_bw(self, year): + # Helper to add a range of holidays for Baden-Württemberg + def _add_holiday_range(name, start_date, end_date): + current_date = start_date + while current_date <= end_date: + if current_date.year == self._year: + self._add_holiday(name, current_date.month, current_date.day) + current_date += timedelta(days=1) + + holidays_map = [] + + if year == 2025: + holidays_map = [ + (tr("Sommerferien"), date(2025, 7, 31), date(2025, 9, 13)), + (tr("Herbstferien"), date(2025, 10, 27), date(2025, 10, 30)), + (tr("Weihnachtsferien"), date(2025, 12, 22), date(2025, 12, 31)), + ] + elif year == 2026: + holidays_map = [ + (tr("Weihnachtsferien"), date(2026, 1, 1), date(2026, 1, 5)), + (tr("Osterferien"), date(2026, 3, 30), date(2026, 4, 11)), + (tr("Pfingstferien"), date(2026, 5, 26), date(2026, 6, 5)), + (tr("Sommerferien"), date(2026, 7, 30), date(2026, 9, 12)), + (tr("Herbstferien"), date(2026, 10, 26), date(2026, 10, 30)), + (tr("Weihnachtsferien"), date(2026, 12, 23), date(2026, 12, 31)), + ] + elif year == 2027: + holidays_map = [ + (tr("Weihnachtsferien"), date(2027, 1, 1), date(2027, 1, 9)), + (tr("Osterferien"), date(2027, 3, 30), date(2027, 4, 3)), + (tr("Pfingstferien"), date(2027, 5, 18), date(2027, 5, 29)), + (tr("Sommerferien"), date(2027, 7, 29), date(2027, 9, 11)), + (tr("Herbstferien"), date(2027, 11, 2), date(2027, 11, 6)), + (tr("Weihnachtsferien"), date(2027, 12, 23), date(2027, 12, 31)), + ] + elif year == 2028: + holidays_map = [ + (tr("Weihnachtsferien"), date(2028, 1, 1), date(2028, 1, 8)), + (tr("Osterferien"), date(2028, 4, 18), date(2028, 4, 22)), + (tr("Pfingstferien"), date(2028, 6, 6), date(2028, 6, 17)), + (tr("Sommerferien"), date(2028, 7, 27), date(2028, 9, 9)), + (tr("Herbstferien"), date(2028, 10, 30), date(2028, 11, 3)), + (tr("Weihnachtsferien"), date(2028, 12, 23), date(2028, 12, 31)), + ] + elif year == 2029: + holidays_map = [ + (tr("Weihnachtsferien"), date(2029, 1, 1), date(2029, 1, 5)), + (tr("Osterferien"), date(2029, 3, 26), date(2029, 4, 7)), + (tr("Pfingstferien"), date(2029, 5, 22), date(2029, 6, 1)), + (tr("Sommerferien"), date(2029, 7, 26), date(2029, 9, 8)), + (tr("Herbstferien"), date(2029, 10, 29), date(2029, 11, 2)), + (tr("Weihnachtsferien"), date(2029, 12, 22), date(2029, 12, 31)), + ] + elif year == 2030: + holidays_map = [ + (tr("Weihnachtsferien"), date(2030, 1, 1), date(2030, 1, 5)), + (tr("Osterferien"), date(2030, 4, 15), date(2030, 4, 26)), + (tr("Pfingstferien"), date(2030, 6, 11), date(2030, 6, 21)), + ] + + for name, start, end in holidays_map: + _add_holiday_range(name, start, end) + + def _add_school_holidays_by(self, year): + # Helper to add a range of holidays for Bayern (BY) + def _add_holiday_range(name, start_date, end_date): + current_date = start_date + while current_date <= end_date: + if current_date.year == self._year: + self._add_holiday(name, current_date.month, current_date.day) + current_date += timedelta(days=1) + + holidays_map = [] + + if year == 2025: + holidays_map = [ + (tr("Weihnachtsferien"), date(2025, 12, 22), date(2025, 12, 31)), + ] + elif year == 2026: + holidays_map = [ + (tr("Weihnachtsferien"), date(2026, 1, 1), date(2026, 1, 5)), + (tr("Frühjahrsferien"), date(2026, 2, 16), date(2026, 2, 20)), + (tr("Osterferien"), date(2026, 3, 30), date(2026, 4, 10)), + (tr("Pfingstferien"), date(2026, 5, 26), date(2026, 6, 5)), + (tr("Sommerferien"), date(2026, 8, 3), date(2026, 9, 14)), + ( + tr("Tage um Allerheiligen"), + date(2026, 11, 2), + date(2026, 11, 6), + ), + (tr("Weihnachtsferien"), date(2026, 12, 24), date(2026, 12, 31)), + ] + elif year == 2027: + holidays_map = [ + (tr("Weihnachtsferien"), date(2027, 1, 1), date(2027, 1, 8)), + (tr("Frühjahrsferien"), date(2027, 2, 8), date(2027, 2, 12)), + (tr("Osterferien"), date(2027, 3, 22), date(2027, 4, 2)), + (tr("Pfingstferien"), date(2027, 5, 18), date(2027, 5, 28)), + (tr("Sommerferien"), date(2027, 8, 2), date(2027, 9, 13)), + ( + tr(" Tage um Allerheiligen"), + date(2027, 11, 2), + date(2027, 11, 5), + ), + (tr("Weihnachtsferien"), date(2027, 12, 24), date(2027, 12, 31)), + ] + elif year == 2028: + holidays_map = [ + (tr("Weihnachtsferien"), date(2028, 1, 1), date(2028, 1, 7)), + (tr("Frühjahrsferien"), date(2028, 2, 28), date(2028, 3, 3)), + (tr("Osterferien"), date(2028, 4, 10), date(2028, 4, 21)), + (tr("Pfingstferien"), date(2028, 6, 6), date(2028, 6, 16)), + (tr("Sommerferien"), date(2028, 7, 31), date(2028, 9, 11)), + ( + tr("Tage um Allerheiligen"), + date(2028, 10, 30), + date(2028, 11, 3), + ), + (tr("Weihnachtsferien"), date(2028, 12, 23), date(2028, 12, 31)), + ] + elif year == 2029: + holidays_map = [ + (tr("Weihnachtsferien"), date(2029, 1, 1), date(2029, 1, 5)), + (tr("Frühjahrsferien"), date(2029, 2, 12), date(2029, 2, 16)), + (tr("Osterferien"), date(2029, 3, 26), date(2029, 4, 6)), + (tr("Pfingstferien"), date(2029, 5, 22), date(2029, 6, 1)), + (tr("Sommerferien"), date(2029, 7, 30), date(2029, 9, 10)), + ( + tr("Tage um Allerheiligen"), + date(2029, 10, 29), + date(2029, 11, 2), + ), + (tr("Weihnachtsferien"), date(2029, 12, 24), date(2029, 12, 31)), + ] + elif year == 2030: + holidays_map = [ + (tr("Weihnachtsferien"), date(2030, 1, 1), date(2030, 1, 4)), + (tr("Frühjahrsferien"), date(2030, 3, 4), date(2030, 3, 8)), + (tr("Osterferien"), date(2030, 4, 15), date(2030, 4, 26)), + (tr("Pfingstferien"), date(2030, 6, 11), date(2030, 6, 21)), + ] + + for name, start, end in holidays_map: + _add_holiday_range(name, start, end) + + def _add_school_holidays_be(self, year): + # Helper to add a range of holidays for Berlin (BE) + def _add_holiday_range(name, start_date, end_date): + current_date = start_date + while current_date <= end_date: + if current_date.year == self._year: + self._add_holiday(name, current_date.month, current_date.day) + current_date += timedelta(days=1) + + holidays_map = [] + + if year == 2025: + holidays_map = [ + (tr("Weihnachtsferien"), date(2025, 12, 22), date(2025, 12, 31)), + ] + elif year == 2026: + holidays_map = [ + (tr("Weihnachtsferien"), date(2026, 1, 1), date(2026, 1, 2)), + (tr("Winterferien"), date(2026, 2, 2), date(2026, 2, 7)), + (tr("Osterferien"), date(2026, 3, 30), date(2026, 4, 10)), + (tr("Unterrichtsfreier Tag nach AZVO"), date(2026, 5, 15), date(2026, 5, 15)), + (tr("Pfingstferien"), date(2026, 5, 26), date(2026, 5, 26)), + (tr("Sommerferien"), date(2026, 7, 9), date(2026, 8, 22)), + (tr("Herbstferien"), date(2026, 10, 19), date(2026, 10, 31)), + (tr("Weihnachtsferien"), date(2026, 12, 23), date(2026, 12, 31)), + ] + elif year == 2027: + holidays_map = [ + (tr("Weihnachtsferien"), date(2027, 1, 1), date(2027, 1, 2)), + (tr("Winterferien"), date(2027, 2, 1), date(2027, 2, 6)), + (tr("Osterferien"), date(2027, 3, 22), date(2027, 4, 2)), + (tr("Unterrichtsfreier Tag nach AZVO"), date(2027, 5, 7), date(2027, 5, 7)), + (tr("Pfingstferien"), date(2027, 5, 18), date(2027, 5, 19)), + (tr("Sommerferien"), date(2027, 7, 1), date(2027, 8, 14)), + (tr("Herbstferien"), date(2027, 10, 11), date(2027, 10, 23)), + (tr("Weihnachtsferien"), date(2027, 12, 22), date(2027, 12, 31)), + ] + elif year == 2028: + holidays_map = [ + (tr("Weihnachtsferien"), date(2028, 1, 1), date(2028, 1, 2)), + (tr("Winterferien"), date(2028, 1, 31), date(2028, 2, 5)), + (tr("Osterferien"), date(2028, 4, 10), date(2028, 4, 22)), + (tr("Unterrichtsfreier Tag nach AZVO"), date(2028, 5, 26), date(2028, 5, 26)), + (tr("Pfingstferien"), date(2028, 6, 1), date(2028, 6, 2)), + (tr("Sommerferien"), date(2028, 7, 1), date(2028, 8, 12)), + (tr("Herbstferien"), date(2028, 10, 2), date(2028, 10, 14)), + (tr("Weihnachtsferien"), date(2028, 12, 22), date(2028, 12, 31)), + ] + elif year == 2029: + holidays_map = [ + (tr("Weihnachtsferien"), date(2029, 1, 1), date(2029, 1, 4)), + (tr("Winterferien"), date(2029, 1, 29), date(2029, 2, 3)), + (tr("Osterferien"), date(2029, 3, 26), date(2029, 4, 6)), + (tr("Unterrichtsfreie Tage"), date(2029, 3, 9), date(2029, 3, 9)), + (tr("Unterrichtsfreie Tage"), date(2029, 4, 30), date(2029, 4, 30)), + (tr("Unterrichtsfreier Tag nach AZVO"), date(2029, 5, 11), date(2029, 5, 11)), + (tr("Pfingstferien"), date(2029, 5, 22), date(2029, 5, 25)), + (tr("Sommerferien"), date(2029, 7, 1), date(2029, 8, 11)), + (tr("Herbstferien"), date(2029, 10, 1), date(2029, 10, 12)), + (tr("Weihnachtsferien"), date(2029, 12, 21), date(2029, 12, 31)), + ] + elif year == 2030: + holidays_map = [ + (tr("Weihnachtsferien"), date(2030, 1, 1), date(2030, 1, 4)), + (tr("Winterferien"), date(2030, 2, 4), date(2030, 2, 9)), + (tr("Osterferien"), date(2030, 4, 15), date(2030, 4, 26)), + (tr("Unterrichtsfreier Tag nach AZVO"), date(2030, 5, 31), date(2030, 5, 31)), + (tr("Pfingstferien"), date(2030, 6, 7), date(2030, 6, 7)), + (tr("Sommerferien"), date(2030, 7, 4), date(2030, 8, 17)), + ] + + for name, start, end in holidays_map: + _add_holiday_range(name, start, end) + + def _add_school_holidays_mv(self, year): + # Helper to add a range of holidays for Mecklenburg-Vorpommern (MV) + def _add_holiday_range(name, start_date, end_date): + current_date = start_date + while current_date <= end_date: + if current_date.year == self._year: + self._add_holiday(name, current_date.month, current_date.day) + current_date += timedelta(days=1) + + holidays_map = [] + + if year == 2025: + holidays_map = [ + (tr("Weihnachtsferien"), date(2025, 12, 20), date(2025, 12, 31)), + ] + elif year == 2026: + holidays_map = [ + (tr("Weihnachtsferien"), date(2026, 1, 1), date(2026, 1, 3)), + (tr("Winterferien"), date(2026, 2, 9), date(2026, 2, 20)), + (tr("Osterferien"), date(2026, 3, 30), date(2026, 4, 8)), + (tr("Pfingstferien"), date(2026, 5, 22), date(2026, 5, 26)), + (tr("Zusätzliche feststehende Ferientage"), date(2026, 5, 15), date(2026, 5, 15)), + (tr("Sommerferien"), date(2026, 7, 13), date(2026, 8, 22)), + (tr("Herbstferien"), date(2026, 10, 15), date(2026, 10, 24)), + (tr("Weihnachtsferien"), date(2026, 12, 21), date(2026, 12, 31)), + ] + elif year == 2027: + holidays_map = [ + (tr("Weihnachtsferien"), date(2027, 1, 1), date(2027, 1, 2)), + (tr("Winterferien"), date(2027, 2, 8), date(2027, 2, 19)), + (tr("Osterferien"), date(2027, 3, 24), date(2027, 4, 2)), + (tr("Pfingstferien"), date(2027, 5, 14), date(2027, 5, 18)), + (tr("Zusätzliche feststehende Ferientage"), date(2027, 5, 7), date(2027, 5, 7)), + (tr("Sommerferien"), date(2027, 7, 5), date(2027, 8, 14)), + (tr("Herbstferien"), date(2027, 10, 14), date(2027, 10, 23)), + (tr("Weihnachtsferien"), date(2027, 12, 22), date(2027, 12, 31)), + ] + elif year == 2028: + holidays_map = [ + (tr("Weihnachtsferien"), date(2028, 1, 1), date(2028, 1, 2)), + (tr("Winterferien"), date(2028, 2, 5), date(2028, 2, 17)), + (tr("Osterferien"), date(2028, 4, 12), date(2028, 4, 21)), + (tr("Pfingstferien"), date(2028, 6, 2), date(2028, 6, 6)), + (tr("Zusätzliche feststehende Ferientage"), date(2028, 5, 26), date(2028, 5, 26)), + (tr("Sommerferien"), date(2028, 6, 26), date(2028, 8, 5)), + (tr("Herbstferien"), date(2028, 10, 23), date(2028, 10, 28)), + (tr("Weihnachtsferien"), date(2028, 12, 22), date(2028, 12, 31)), + ] + elif year == 2029: + holidays_map = [ + (tr("Weihnachtsferien"), date(2029, 1, 1), date(2029, 1, 4)), + (tr("Winterferien"), date(2029, 2, 5), date(2029, 2, 16)), + (tr("Osterferien"), date(2029, 3, 28), date(2029, 4, 6)), + (tr("Pfingstferien"), date(2029, 5, 18), date(2029, 5, 22)), + (tr("Zusätzliche feststehende Ferientage"), date(2029, 3, 9), date(2029, 3, 9)), + (tr("Zusätzliche feststehende Ferientage"), date(2029, 4, 30), date(2029, 4, 30)), + (tr("Zusätzliche feststehende Ferientage"), date(2029, 3, 30), date(2029, 3, 30)), + (tr("Zusätzliche feststehende Ferientage"), date(2029, 4, 30), date(2029, 4, 30)), + (tr("Zusätzliche feststehende Ferientage"), date(2029, 5, 11), date(2029, 5, 11)), + (tr("Sommerferien"), date(2029, 6, 18), date(2029, 7, 28)), + (tr("Herbstferien"), date(2029, 10, 22), date(2029, 10, 27)), + (tr("Weihnachtsferien"), date(2029, 12, 21), date(2029, 12, 31)), + ] + elif year == 2030: + holidays_map = [ + (tr("Weihnachtsferien"), date(2030, 1, 1), date(2030, 1, 4)), + (tr("Winterferien"), date(2030, 2, 4), date(2030, 2, 15)), + (tr("Osterferien"), date(2030, 4, 17), date(2030, 4, 26)), + (tr("Pfingstferien"), date(2030, 6, 7), date(2030, 6, 11)), + (tr("Sommerferien"), date(2030, 7, 1), date(2030, 8, 10)), + ] + + for name, start, end in holidays_map: + _add_holiday_range(name, start, end) + + def _add_school_holidays_ni(self, year): + # Helper to add a range of holidays for Niedersachsen (NI) + def _add_holiday_range(name, start_date, end_date): + current_date = start_date + while current_date <= end_date: + if current_date.year == self._year: + self._add_holiday(name, current_date.month, current_date.day) + current_date += timedelta(days=1) + + holidays_map = [] + + if year == 2025: + holidays_map = [(tr("Weihnachtsferien"), date(2025, 12, 22), date(2025, 12, 31))] + elif year == 2026: + holidays_map = [ + (tr("Weihnachtsferien"), date(2026, 1, 1), date(2026, 1, 5)), + (tr("Halbjahresferien"), date(2026, 2, 2), date(2026, 2, 3)), + (tr("Osterferien"), date(2026, 3, 23), date(2026, 4, 7)), + ( + tr("Ferien in Verbindung mit dem 1. Mai und Himmelfahrt"), + date(2026, 5, 15), + date(2026, 5, 15), + ), + (tr("Pfingstferien"), date(2026, 5, 26), date(2026, 5, 26)), + (tr("Sommerferien"), date(2026, 7, 2), date(2026, 8, 12)), + (tr("Herbstferien"), date(2026, 10, 12), date(2026, 10, 24)), + (tr("Weihnachtsferien"), date(2026, 12, 23), date(2026, 12, 31)), + ] + elif year == 2027: + holidays_map = [ + (tr("Weihnachtsferien"), date(2027, 1, 1), date(2027, 1, 9)), + (tr("Halbjahresferien"), date(2027, 2, 1), date(2027, 2, 2)), + (tr("Osterferien"), date(2027, 3, 22), date(2027, 4, 3)), + ( + tr("Ferien in Verbindung mit dem 1. Mai und Himmelfahrt"), + date(2027, 5, 7), + date(2027, 5, 7), + ), + (tr("Pfingstferien"), date(2027, 5, 18), date(2027, 5, 18)), + (tr("Sommerferien"), date(2027, 7, 8), date(2027, 8, 18)), + (tr("Herbstferien"), date(2027, 10, 16), date(2027, 10, 30)), + (tr("Weihnachtsferien"), date(2027, 12, 23), date(2027, 12, 31)), + ] + elif year == 2028: + holidays_map = [ + (tr("Weihnachtsferien"), date(2028, 1, 1), date(2028, 1, 8)), + (tr("Halbjahresferien"), date(2028, 1, 31), date(2028, 2, 1)), + (tr("Osterferien"), date(2028, 4, 10), date(2028, 4, 22)), + ( + tr("Ferien in Verbindung mit dem 1. Mai und Himmelfahrt"), + date(2028, 5, 26), + date(2028, 5, 26), + ), + (tr("Pfingstferien"), date(2028, 6, 6), date(2028, 6, 6)), + (tr("Sommerferien"), date(2028, 7, 20), date(2028, 8, 30)), + (tr("Herbstferien"), date(2028, 10, 2), date(2028, 10, 2)), + (tr("Herbstferien"), date(2028, 10, 23), date(2028, 11, 4)), + (tr("Weihnachtsferien"), date(2028, 12, 27), date(2028, 12, 31)), + ] + elif year == 2029: + holidays_map = [ + (tr("Weihnachtsferien"), date(2029, 1, 1), date(2029, 1, 6)), + (tr("Halbjahresferien"), date(2029, 2, 1), date(2029, 2, 2)), + (tr("Osterferien"), date(2029, 3, 19), date(2029, 4, 3)), + ( + tr("Ferien in Verbindung mit dem 1. Mai und Himmelfahrt"), + date(2029, 4, 30), + date(2029, 4, 30), + ), + ( + tr("Ferien in Verbindung mit dem 1. Mai und Himmelfahrt"), + date(2029, 5, 11), + date(2029, 5, 11), + ), + (tr("Pfingstferien"), date(2029, 5, 22), date(2029, 5, 22)), + (tr("Sommerferien"), date(2029, 7, 19), date(2029, 8, 29)), + (tr("Herbstferien"), date(2029, 10, 4), date(2029, 10, 5)), + (tr("Herbstferien"), date(2029, 10, 22), date(2029, 11, 2)), + (tr("Weihnachtsferien"), date(2029, 12, 21), date(2029, 12, 31)), + ] + elif year == 2030: + holidays_map = [ + (tr("Weihnachtsferien"), date(2030, 1, 1), date(2030, 1, 5)), + (tr("Halbjahresferien"), date(2030, 1, 31), date(2030, 2, 1)), + (tr("Osterferien"), date(2030, 4, 8), date(2030, 4, 23)), + ( + tr("Ferien in Verbindung mit dem 1. Mai und Himmelfahrt"), + date(2030, 5, 31), + date(2030, 5, 31), + ), + (tr("Pfingstferien"), date(2030, 6, 11), date(2030, 6, 11)), + (tr("Sommerferien"), date(2030, 7, 11), date(2030, 8, 21)), + ] + + for name, start, end in holidays_map: + _add_holiday_range(name, start, end) + + def _add_school_holidays_bb(self, year): + # Helper to add a range of holidays for Brandenburg (BB) + def _add_holiday_range(name, start_date, end_date): + current_date = start_date + while current_date <= end_date: + if current_date.year == self._year: + self._add_holiday(name, current_date.month, current_date.day) + current_date += timedelta(days=1) + + holidays_map = [] + + if year == 2025: + # Part of the 2025/2026 Christmas range (only 2025 portion) + holidays_map = [ + (tr("Weihnachtsferien"), date(2025, 12, 22), date(2025, 12, 31)), + ] + elif year == 2026: + holidays_map = [ + (tr("Weihnachtsferien"), date(2026, 1, 1), date(2026, 1, 2)), + (tr("Winterferien"), date(2026, 2, 2), date(2026, 2, 7)), + (tr("Osterferien"), date(2026, 3, 30), date(2026, 4, 10)), + (tr("Pfingsten"), date(2026, 5, 26), date(2026, 5, 26)), + (tr("Variabler Ferientag"), date(2026, 5, 13), date(2026, 5, 13)), + (tr("Variabler Ferientag"), date(2026, 5, 15), date(2026, 5, 15)), + (tr("Variabler Ferientag"), date(2026, 5, 18), date(2026, 5, 18)), + (tr("Sommerferien"), date(2026, 7, 9), date(2026, 8, 22)), + (tr("Herbstferien"), date(2026, 10, 19), date(2026, 10, 30)), + (tr("Weihnachtsferien"), date(2026, 12, 23), date(2026, 12, 31)), + ] + elif year == 2027: + holidays_map = [ + (tr("Weihnachtsferien"), date(2027, 1, 1), date(2027, 1, 2)), + (tr("Winterferien"), date(2027, 2, 1), date(2027, 2, 6)), + (tr("Osterferien"), date(2027, 3, 22), date(2027, 4, 3)), + (tr("Pfingsten"), date(2027, 5, 18), date(2027, 5, 18)), + (tr("Variabler Ferientag"), date(2027, 5, 7), date(2027, 5, 7)), + (tr("Sommerferien"), date(2027, 7, 1), date(2027, 8, 14)), + (tr("Herbstferien"), date(2027, 10, 11), date(2027, 10, 23)), + (tr("Weihnachtsferien"), date(2027, 12, 23), date(2027, 12, 31)), + ] + elif year == 2028: + holidays_map = [ + (tr("Winterferien"), date(2028, 1, 31), date(2028, 2, 5)), + (tr("Osterferien"), date(2028, 4, 10), date(2028, 4, 22)), + (tr("Variabler Ferientag"), date(2028, 5, 26), date(2028, 5, 26)), + (tr("Sommerferien"), date(2028, 6, 29), date(2028, 8, 12)), + (tr("Herbstferien"), date(2028, 10, 2), date(2028, 10, 14)), + (tr("Variabler Ferientag"), date(2028, 10, 30), date(2028, 10, 30)), + (tr("Weihnachtsferien"), date(2028, 12, 22), date(2028, 12, 31)), + ] + elif year == 2029: + holidays_map = [ + (tr("Weihnachtsferien"), date(2029, 1, 1), date(2029, 1, 2)), + (tr("Winterferien"), date(2029, 1, 29), date(2029, 2, 3)), + (tr("Osterferien"), date(2029, 3, 26), date(2029, 4, 6)), + (tr("Pfingsten"), date(2029, 5, 22), date(2029, 5, 22)), + (tr("Variabler Ferientag"), date(2029, 4, 30), date(2029, 4, 30)), + (tr("Variabler Ferientag"), date(2029, 5, 11), date(2029, 5, 11)), + (tr("Sommerferien"), date(2029, 6, 28), date(2029, 8, 11)), + ] + + for name, start, end in holidays_map: + _add_holiday_range(name, start, end) + + def _add_school_holidays_he(self, year): + # Helper to add a range of holidays for Hessen (HE) + def _add_holiday_range(name, start_date, end_date): + current_date = start_date + while current_date <= end_date: + if current_date.year == self._year: + self._add_holiday(name, current_date.month, current_date.day) + current_date += timedelta(days=1) + + holidays_map = [] + + if year == 2025: + holidays_map = [ + (tr("Weihnachtsferien"), date(2025, 12, 22), date(2025, 12, 31)), + ] + elif year == 2026: + holidays_map = [ + (tr("Weihnachtsferien"), date(2026, 1, 1), date(2026, 1, 10)), + (tr("Osterferien"), date(2026, 3, 30), date(2026, 4, 10)), + (tr("Sommerferien"), date(2026, 6, 29), date(2026, 8, 7)), + (tr("Herbstferien"), date(2026, 10, 5), date(2026, 10, 17)), + (tr("Weihnachtsferien"), date(2026, 12, 23), date(2026, 12, 31)), + ] + elif year == 2027: + holidays_map = [ + (tr("Weihnachtsferien"), date(2027, 1, 1), date(2027, 1, 10)), + (tr("Osterferien"), date(2027, 3, 22), date(2027, 4, 2)), + (tr("Sommerferien"), date(2027, 6, 28), date(2027, 8, 6)), + (tr("Herbstferien"), date(2027, 10, 4), date(2027, 10, 16)), + (tr("Weihnachtsferien"), date(2027, 12, 23), date(2027, 12, 31)), + ] + elif year == 2028: + holidays_map = [ + (tr("Weihnachtsferien"), date(2028, 1, 1), date(2028, 1, 11)), + (tr("Osterferien"), date(2028, 4, 3), date(2028, 4, 14)), + (tr("Sommerferien"), date(2028, 7, 3), date(2028, 8, 11)), + (tr("Herbstferien"), date(2028, 10, 9), date(2028, 10, 20)), + (tr("Weihnachtsferien"), date(2028, 12, 27), date(2028, 12, 31)), + ] + elif year == 2029: + holidays_map = [ + (tr("Weihnachtsferien"), date(2029, 1, 1), date(2029, 1, 11)), + (tr("Osterferien"), date(2029, 3, 29), date(2029, 4, 13)), + (tr("Sommerferien"), date(2029, 7, 16), date(2029, 8, 24)), + (tr("Herbstferien"), date(2029, 10, 15), date(2029, 10, 26)), + (tr("Weihnachtsferien"), date(2029, 12, 24), date(2029, 12, 31)), + ] + elif year == 2030: + holidays_map = [ + (tr("Weihnachtsferien"), date(2030, 1, 1), date(2030, 1, 11)), + (tr("Osterferien"), date(2030, 4, 8), date(2030, 4, 22)), + (tr("Sommerferien"), date(2030, 7, 22), date(2030, 8, 30)), + ] + + for name, start, end in holidays_map: + _add_holiday_range(name, start, end) + + def _populate(self, year): + super()._populate(year) + + if self.subdiv == "HH" and SCHOOL in self.categories: + self._add_school_holidays_hh(year) + # Ensure no holidays from other years were accidentally added + # (defensive cleanup for cross-year ranges). + for dt in list(self.keys()): + if dt.year != year: + self.pop(dt) + if self.subdiv == "BB" and SCHOOL in self.categories: + self._add_school_holidays_bb(year) + for dt in list(self.keys()): + if dt.year != year: + self.pop(dt) + if self.subdiv == "HB" and SCHOOL in self.categories: + self._add_school_holidays_hb(year) + for dt in list(self.keys()): + if dt.year != year: + self.pop(dt) + if self.subdiv == "BW" and SCHOOL in self.categories: + self._add_school_holidays_bw(year) + for dt in list(self.keys()): + if dt.year != year: + self.pop(dt) + if self.subdiv == "BY" and SCHOOL in self.categories: + self._add_school_holidays_by(year) + for dt in list(self.keys()): + if dt.year != year: + self.pop(dt) + if self.subdiv == "BE" and SCHOOL in self.categories: + self._add_school_holidays_be(year) + for dt in list(self.keys()): + if dt.year != year: + self.pop(dt) + if self.subdiv == "MV" and SCHOOL in self.categories: + self._add_school_holidays_mv(year) + for dt in list(self.keys()): + if dt.year != year: + self.pop(dt) + if self.subdiv == "RP" and SCHOOL in self.categories: + self._add_school_holidays_rp(year) + for dt in list(self.keys()): + if dt.year != year: + self.pop(dt) + if self.subdiv == "SL" and SCHOOL in self.categories: + self._add_school_holidays_sl(year) + for dt in list(self.keys()): + if dt.year != year: + self.pop(dt) + if self.subdiv == "NI" and SCHOOL in self.categories: + self._add_school_holidays_ni(year) + for dt in list(self.keys()): + if dt.year != year: + self.pop(dt) + if self.subdiv == "NW" and SCHOOL in self.categories: + self._add_school_holidays_nw(year) + for dt in list(self.keys()): + if dt.year != year: + self.pop(dt) + if self.subdiv == "HE" and SCHOOL in self.categories: + self._add_school_holidays_he(year) + for dt in list(self.keys()): + if dt.year != year: + self.pop(dt) + if self.subdiv == "TH" and SCHOOL in self.categories: + self._add_school_holidays_th(year) + for dt in list(self.keys()): + if dt.year != year: + self.pop(dt) + if self.subdiv == "SH" and SCHOOL in self.categories: + self._add_school_holidays_sh(year) + for dt in list(self.keys()): + if dt.year != year: + self.pop(dt) + if self.subdiv == "SN" and SCHOOL in self.categories: + self._add_school_holidays_sn(year) + for dt in list(self.keys()): + if dt.year != year: + self.pop(dt) + if self.subdiv == "ST" and SCHOOL in self.categories: + self._add_school_holidays_st(year) + for dt in list(self.keys()): + if dt.year != year: + self.pop(dt) def _populate_public_holidays(self): # New Year's Day. diff --git a/holidays/locale/de/LC_MESSAGES/DE.po b/holidays/locale/de/LC_MESSAGES/DE.po index 90032d5d33..91bd55d212 100644 --- a/holidays/locale/de/LC_MESSAGES/DE.po +++ b/holidays/locale/de/LC_MESSAGES/DE.po @@ -13,9 +13,9 @@ # Germany holidays. msgid "" msgstr "" -"Project-Id-Version: Holidays 0.87\n" +"Project-Id-Version: Holidays 0.88\n" "POT-Creation-Date: 2023-04-04 16:13+0300\n" -"PO-Revision-Date: 2025-12-02 18:19+0200\n" +"PO-Revision-Date: 2025-12-27 00:27+0100\n" "Last-Translator: ~Jhellico \n" "Language-Team: Holidays Localization Team\n" "Language: de\n" @@ -26,6 +26,87 @@ msgstr "" "X-Generator: Poedit 3.6\n" "X-Source-Language: de\n" +msgid "Weihnachtsferien" +msgstr "" + +msgid "Halbjahrespause" +msgstr "" + +msgid "Frühjahrsferien" +msgstr "" + +msgid "Himmelfahrt/Pfingsten" +msgstr "" + +msgid "Sommerferien" +msgstr "" + +msgid "Herbstferien" +msgstr "" + +msgid "Brückentag" +msgstr "" + +msgid "Osterferien" +msgstr "" + +msgid "Pfingsten" +msgstr "" + +msgid "Halbjahresferien" +msgstr "" + +msgid "Tag nach Himmelfahrt" +msgstr "" + +msgid "Tag vor dem 03. Oktober" +msgstr "" + +msgid "Tag vor dem 01. Mai" +msgstr "" + +msgid "Tage nach dem 03. Oktober" +msgstr "" + +msgid "Fastnachtsferien" +msgstr "" + +msgid "Pfingstferien" +msgstr "" + +msgid "Winterferien" +msgstr "" + +msgid "Schulfreier Tag" +msgstr "" + +msgid "Himmelfahrt" +msgstr "" + +msgid "Unterrichtsfreier Tag" +msgstr "" + +msgid "Beweglicher Ferientag" +msgstr "" + +msgid "Tage um Allerheiligen" +msgstr "" + +msgid "Unterrichtsfreier Tag nach AZVO" +msgstr "" + +msgid "Unterrichtsfreie Tage" +msgstr "" + +msgid "Zusätzliche feststehende Ferientage" +msgstr "" + +msgid "Ferien in Verbindung mit dem 1. Mai und Himmelfahrt" +msgstr "" + +msgid "Variabler Ferientag" +msgstr "" + #. New Year's Day. msgid "Neujahr" msgstr "" diff --git a/holidays/locale/en_US/LC_MESSAGES/DE.po b/holidays/locale/en_US/LC_MESSAGES/DE.po index 0792a39ca7..f004c51861 100644 --- a/holidays/locale/en_US/LC_MESSAGES/DE.po +++ b/holidays/locale/en_US/LC_MESSAGES/DE.po @@ -14,9 +14,9 @@ # msgid "" msgstr "" -"Project-Id-Version: Holidays 0.87\n" +"Project-Id-Version: Holidays 0.88\n" "POT-Creation-Date: 2023-04-04 16:13+0300\n" -"PO-Revision-Date: 2025-12-02 18:19+0200\n" +"PO-Revision-Date: 2025-12-27 00:27+0100\n" "Last-Translator: ~Jhellico \n" "Language-Team: Holidays Localization Team\n" "Language: en_US\n" @@ -27,6 +27,87 @@ msgstr "" "X-Generator: Poedit 3.6\n" "X-Source-Language: de\n" +msgid "Weihnachtsferien" +msgstr "Christmas holidays" + +msgid "Halbjahrespause" +msgstr "mid-term break" + +msgid "Frühjahrsferien" +msgstr "Spring break" + +msgid "Himmelfahrt/Pfingsten" +msgstr "Ascension/Pentecost break" + +msgid "Sommerferien" +msgstr "Summer holidays" + +msgid "Herbstferien" +msgstr "Autumn break" + +msgid "Brückentag" +msgstr "Bridge day" + +msgid "Osterferien" +msgstr "Easter holidays" + +msgid "Pfingsten" +msgstr "Pentecost" + +msgid "Halbjahresferien" +msgstr "mid-term holidays" + +msgid "Tag nach Himmelfahrt" +msgstr "Day after Ascension" + +msgid "Tag vor dem 03. Oktober" +msgstr "Day before German Unity Day" + +msgid "Tag vor dem 01. Mai" +msgstr "Day before May Day" + +msgid "Tage nach dem 03. Oktober" +msgstr "Days after German Unity Day" + +msgid "Fastnachtsferien" +msgstr "Carnival break" + +msgid "Pfingstferien" +msgstr "Pentecost holidays" + +msgid "Winterferien" +msgstr "Winter holidays" + +msgid "Schulfreier Tag" +msgstr "School-free day" + +msgid "Himmelfahrt" +msgstr "Ascension" + +msgid "Unterrichtsfreier Tag" +msgstr "Non-teaching day" + +msgid "Beweglicher Ferientag" +msgstr "Movable holiday" + +msgid "Tage um Allerheiligen" +msgstr "days around All Saints' Day" + +msgid "Unterrichtsfreier Tag nach AZVO" +msgstr "Non-teaching day according to AZVO" + +msgid "Unterrichtsfreie Tage" +msgstr "Non-teaching days" + +msgid "Zusätzliche feststehende Ferientage" +msgstr "Additional fixed holiday days" + +msgid "Ferien in Verbindung mit dem 1. Mai und Himmelfahrt" +msgstr "Holidays connected with May Day and Ascension Day" + +msgid "Variabler Ferientag" +msgstr "Variable holiday" + #. New Year's Day. msgid "Neujahr" msgstr "New Year's Day" diff --git a/holidays/locale/th/LC_MESSAGES/DE.po b/holidays/locale/th/LC_MESSAGES/DE.po index 73180f2c1f..c1cccabf5e 100644 --- a/holidays/locale/th/LC_MESSAGES/DE.po +++ b/holidays/locale/th/LC_MESSAGES/DE.po @@ -14,9 +14,9 @@ # msgid "" msgstr "" -"Project-Id-Version: Holidays 0.87\n" +"Project-Id-Version: Holidays 0.88\n" "POT-Creation-Date: 2024-09-05 23:21+0700\n" -"PO-Revision-Date: 2025-12-02 18:20+0200\n" +"PO-Revision-Date: 2025-12-27 00:53+0100\n" "Last-Translator: ~Jhellico \n" "Language-Team: Holidays Localization Team\n" "Language: th\n" @@ -27,6 +27,87 @@ msgstr "" "X-Generator: Poedit 3.6\n" "X-Source-Language: de\n" +msgid "Weihnachtsferien" +msgstr "Weihnachtsferien" + +msgid "Halbjahrespause" +msgstr "Halbjahrespause" + +msgid "Frühjahrsferien" +msgstr "Frühjahrsferien" + +msgid "Himmelfahrt/Pfingsten" +msgstr "Himmelfahrt/Pfingsten" + +msgid "Sommerferien" +msgstr "Sommerferien" + +msgid "Herbstferien" +msgstr "Herbstferien" + +msgid "Brückentag" +msgstr "Brückentag" + +msgid "Osterferien" +msgstr "Osterferien" + +msgid "Pfingsten" +msgstr "Pfingsten" + +msgid "Halbjahresferien" +msgstr "Halbjahresferien" + +msgid "Tag nach Himmelfahrt" +msgstr "Tag nach Himmelfahrt" + +msgid "Tag vor dem 03. Oktober" +msgstr "Tag vor dem 03. Oktober" + +msgid "Tag vor dem 01. Mai" +msgstr "Tag vor dem 01. Mai" + +msgid "Tage nach dem 03. Oktober" +msgstr "Tage nach dem 03. Oktober" + +msgid "Fastnachtsferien" +msgstr "Fastnachtsferien" + +msgid "Pfingstferien" +msgstr "Pfingstferien" + +msgid "Winterferien" +msgstr "Winterferien" + +msgid "Schulfreier Tag" +msgstr "Schulfreier Tag" + +msgid "Himmelfahrt" +msgstr "Himmelfahrt" + +msgid "Unterrichtsfreier Tag" +msgstr "Unterrichtsfreier Tag" + +msgid "Beweglicher Ferientag" +msgstr "Beweglicher Ferientag" + +msgid "Tage um Allerheiligen" +msgstr "Tage um Allerheiligen" + +msgid "Unterrichtsfreier Tag nach AZVO" +msgstr "Unterrichtsfreier Tag nach AZVO" + +msgid "Unterrichtsfreie Tage" +msgstr "Unterrichtsfreie Tage" + +msgid "Zusätzliche feststehende Ferientage" +msgstr "Zusätzliche feststehende Ferientage" + +msgid "Ferien in Verbindung mit dem 1. Mai und Himmelfahrt" +msgstr "Ferien in Verbindung mit dem 1. Mai und Himmelfahrt" + +msgid "Variabler Ferientag" +msgstr "Variabler Ferientag" + #. New Year's Day. msgid "Neujahr" msgstr "วันขึ้นปีใหม่" diff --git a/holidays/locale/uk/LC_MESSAGES/DE.po b/holidays/locale/uk/LC_MESSAGES/DE.po index 9764c6deb1..f6b6967b74 100644 --- a/holidays/locale/uk/LC_MESSAGES/DE.po +++ b/holidays/locale/uk/LC_MESSAGES/DE.po @@ -14,9 +14,9 @@ # msgid "" msgstr "" -"Project-Id-Version: Holidays 0.87\n" +"Project-Id-Version: Holidays 0.88\n" "POT-Creation-Date: 2023-04-04 16:13+0300\n" -"PO-Revision-Date: 2025-12-02 18:19+0200\n" +"PO-Revision-Date: 2025-12-27 00:53+0100\n" "Last-Translator: ~Jhellico \n" "Language-Team: Holidays Localization Team\n" "Language: uk\n" @@ -27,6 +27,87 @@ msgstr "" "X-Generator: Poedit 3.6\n" "X-Source-Language: de\n" +msgid "Weihnachtsferien" +msgstr "Weihnachtsferien" + +msgid "Halbjahrespause" +msgstr "Halbjahrespause" + +msgid "Frühjahrsferien" +msgstr "Frühjahrsferien" + +msgid "Himmelfahrt/Pfingsten" +msgstr "Himmelfahrt/Pfingsten" + +msgid "Sommerferien" +msgstr "Sommerferien" + +msgid "Herbstferien" +msgstr "Herbstferien" + +msgid "Brückentag" +msgstr "Brückentag" + +msgid "Osterferien" +msgstr "Osterferien" + +msgid "Pfingsten" +msgstr "Pfingsten" + +msgid "Halbjahresferien" +msgstr "Halbjahresferien" + +msgid "Tag nach Himmelfahrt" +msgstr "Tag nach Himmelfahrt" + +msgid "Tag vor dem 03. Oktober" +msgstr "Tag vor dem 03. Oktober" + +msgid "Tag vor dem 01. Mai" +msgstr "Tag vor dem 01. Mai" + +msgid "Tage nach dem 03. Oktober" +msgstr "Tage nach dem 03. Oktober" + +msgid "Fastnachtsferien" +msgstr "Fastnachtsferien" + +msgid "Pfingstferien" +msgstr "Pfingstferien" + +msgid "Winterferien" +msgstr "Winterferien" + +msgid "Schulfreier Tag" +msgstr "Schulfreier Tag" + +msgid "Himmelfahrt" +msgstr "Himmelfahrt" + +msgid "Unterrichtsfreier Tag" +msgstr "Unterrichtsfreier Tag" + +msgid "Beweglicher Ferientag" +msgstr "Beweglicher Ferientag" + +msgid "Tage um Allerheiligen" +msgstr "Tage um Allerheiligen" + +msgid "Unterrichtsfreier Tag nach AZVO" +msgstr "Unterrichtsfreier Tag nach AZVO" + +msgid "Unterrichtsfreie Tage" +msgstr "Unterrichtsfreie Tage" + +msgid "Zusätzliche feststehende Ferientage" +msgstr "Zusätzliche feststehende Ferientage" + +msgid "Ferien in Verbindung mit dem 1. Mai und Himmelfahrt" +msgstr "Ferien in Verbindung mit dem 1. Mai und Himmelfahrt" + +msgid "Variabler Ferientag" +msgstr "Variabler Ferientag" + #. New Year's Day. msgid "Neujahr" msgstr "Новий рік" diff --git a/tests/countries/test_germany.py b/tests/countries/test_germany.py index 695d089f41..7b01e1c013 100644 --- a/tests/countries/test_germany.py +++ b/tests/countries/test_germany.py @@ -356,6 +356,249 @@ def test_l10n_default(self): ("2022-12-26", "Zweiter Weihnachtstag"), ) + +class TestGermanySaarlandSchoolHolidays(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass(Germany, with_subdiv_categories=True) + + def test_christmas_cross_year(self): + # 2025 Christmas range spans 2025->2026. Ensure per-year population. + h_2025 = Germany(years=2025, subdiv="SL", categories=("school",)) + self.assertIn("2025-12-22", h_2025) + self.assertEqual(h_2025["2025-12-22"], "Weihnachtsferien") + + h_2026 = Germany(years=2026, subdiv="SL", categories=("school",)) + self.assertIn("2026-01-01", h_2026) + self.assertEqual(h_2026["2026-01-01"], "Weihnachtsferien") + self.assertNotIn("2025-12-22", h_2026) + + def test_key_2026_ranges(self): + h = Germany(years=2026, subdiv="SL", categories=("school",)) + self.assertIn("2026-02-16", h) + self.assertEqual(h["2026-02-16"], "Fastnachtsferien") + self.assertIn("2026-04-07", h) + self.assertEqual(h["2026-04-07"], "Osterferien") + self.assertIn("2026-06-29", h) + self.assertEqual(h["2026-06-29"], "Sommerferien") + self.assertIn("2026-08-07", h) + self.assertEqual(h["2026-08-07"], "Sommerferien") + self.assertIn("2026-10-05", h) + self.assertEqual(h["2026-10-05"], "Herbstferien") + + def test_2029_and_2030_ranges(self): + h_2029 = Germany(years=2029, subdiv="SL", categories=("school",)) + self.assertIn("2029-05-22", h_2029) + self.assertEqual(h_2029["2029-05-22"], "Pfingstferien") + self.assertIn("2029-07-16", h_2029) + self.assertEqual(h_2029["2029-07-16"], "Sommerferien") + self.assertIn("2029-12-21", h_2029) + self.assertEqual(h_2029["2029-12-21"], "Weihnachtsferien") + + h_2030 = Germany(years=2030, subdiv="SL", categories=("school",)) + self.assertIn("2030-01-01", h_2030) + self.assertEqual(h_2030["2030-01-01"], "Weihnachtsferien") + self.assertIn("2030-02-25", h_2030) + self.assertEqual(h_2030["2030-02-25"], "Fastnachtsferien") + self.assertIn("2030-07-22", h_2030) + self.assertEqual(h_2030["2030-07-22"], "Sommerferien") + + +class TestGermanyThuringiaSchoolHolidays(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass(Germany, with_subdiv_categories=True) + + def test_christmas_cross_year(self): + # 2025 Christmas range spans 2025->2026. Ensure per-year population. + h_2025 = Germany(years=2025, subdiv="TH", categories=("school",)) + self.assertIn("2025-12-22", h_2025) + self.assertEqual(h_2025["2025-12-22"], "Weihnachtsferien") + + h_2026 = Germany(years=2026, subdiv="TH", categories=("school",)) + self.assertIn("2026-01-01", h_2026) + self.assertEqual(h_2026["2026-01-01"], "Weihnachtsferien") + self.assertNotIn("2025-12-22", h_2026) + + def test_key_2026_ranges(self): + h = Germany(years=2026, subdiv="TH", categories=("school",)) + self.assertIn("2026-02-16", h) + self.assertEqual(h["2026-02-16"], "Winterferien") + self.assertIn("2026-04-07", h) + self.assertEqual(h["2026-04-07"], "Osterferien") + self.assertIn("2026-05-15", h) + self.assertEqual(h["2026-05-15"], "Schulfreier Tag") + self.assertIn("2026-07-04", h) + self.assertEqual(h["2026-07-04"], "Sommerferien") + + def test_2027_and_2030_ranges(self): + h_2027 = Germany(years=2027, subdiv="TH", categories=("school",)) + self.assertIn("2027-02-01", h_2027) + self.assertEqual(h_2027["2027-02-01"], "Winterferien") + self.assertIn("2027-07-10", h_2027) + self.assertEqual(h_2027["2027-07-10"], "Sommerferien") + + h_2030 = Germany(years=2030, subdiv="TH", categories=("school",)) + self.assertIn("2030-01-01", h_2030) + self.assertEqual(h_2030["2030-01-01"], "Weihnachtsferien") + self.assertIn("2030-05-31", h_2030) + self.assertEqual(h_2030["2030-05-31"], "Schulfreier Tag") + + +class TestGermanySchleswigHolsteinSchoolHolidays(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass(Germany, with_subdiv_categories=True) + + def test_christmas_cross_year(self): + h_2025 = Germany(years=2025, subdiv="SH", categories=("school",)) + self.assertIn("2025-12-19", h_2025) + self.assertEqual(h_2025["2025-12-19"], "Weihnachtsferien") + + h_2026 = Germany(years=2026, subdiv="SH", categories=("school",)) + self.assertIn("2026-01-01", h_2026) + self.assertEqual(h_2026["2026-01-01"], "Weihnachtsferien") + self.assertNotIn("2025-12-19", h_2026) + + def test_key_2026_ranges(self): + h = Germany(years=2026, subdiv="SH", categories=("school",)) + self.assertIn("2026-03-26", h) + self.assertEqual(h["2026-03-26"], "Osterferien") + self.assertIn("2026-05-15", h) + self.assertEqual(h["2026-05-15"], "Himmelfahrt") + self.assertIn("2026-07-04", h) + self.assertEqual(h["2026-07-04"], "Sommerferien") + + def test_2028_and_2030_ranges(self): + h_2028 = Germany(years=2028, subdiv="SH", categories=("school",)) + self.assertIn("2028-06-24", h_2028) + self.assertEqual(h_2028["2028-06-24"], "Sommerferien") + + h_2030 = Germany(years=2030, subdiv="SH", categories=("school",)) + self.assertIn("2030-07-08", h_2030) + self.assertEqual(h_2030["2030-07-08"], "Sommerferien") + self.assertIn("2030-05-31", h_2030) + self.assertEqual(h_2030["2030-05-31"], "Himmelfahrt") + + +class TestGermanySaxonySchoolHolidays(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass(Germany, with_subdiv_categories=True) + + def test_christmas_cross_year(self): + h_2025 = Germany(years=2025, subdiv="SN", categories=("school",)) + self.assertIn("2025-12-22", h_2025) + self.assertEqual(h_2025["2025-12-22"], "Weihnachtsferien") + + h_2026 = Germany(years=2026, subdiv="SN", categories=("school",)) + self.assertIn("2026-01-01", h_2026) + self.assertEqual(h_2026["2026-01-01"], "Weihnachtsferien") + self.assertNotIn("2025-12-22", h_2026) + + def test_key_2026_ranges(self): + h = Germany(years=2026, subdiv="SN", categories=("school",)) + self.assertIn("2026-02-09", h) + self.assertEqual(h["2026-02-09"], "Winterferien") + self.assertIn("2026-04-03", h) + self.assertEqual(h["2026-04-03"], "Osterferien") + self.assertIn("2026-07-04", h) + self.assertEqual(h["2026-07-04"], "Sommerferien") + self.assertIn("2026-05-15", h) + self.assertEqual(h["2026-05-15"], "Unterrichtsfreier Tag") + + def test_2027_and_2029_ranges(self): + h_2027 = Germany(years=2027, subdiv="SN", categories=("school",)) + self.assertIn("2027-05-15", h_2027) + self.assertEqual(h_2027["2027-05-15"], "Pfingstferien") + self.assertIn("2027-07-10", h_2027) + self.assertEqual(h_2027["2027-07-10"], "Sommerferien") + + h_2029 = Germany(years=2029, subdiv="SN", categories=("school",)) + self.assertIn("2029-03-29", h_2029) + self.assertEqual(h_2029["2029-03-29"], "Osterferien") + self.assertIn("2029-07-21", h_2029) + self.assertEqual(h_2029["2029-07-21"], "Sommerferien") + + +class TestGermanySaxonyAnhaltSchoolHolidays(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass(Germany, with_subdiv_categories=True) + + def test_christmas_cross_year(self): + h_2025 = Germany(years=2025, subdiv="ST", categories=("school",)) + self.assertIn("2025-12-22", h_2025) + self.assertEqual(h_2025["2025-12-22"], "Weihnachtsferien") + + h_2026 = Germany(years=2026, subdiv="ST", categories=("school",)) + self.assertIn("2026-01-01", h_2026) + self.assertEqual(h_2026["2026-01-01"], "Weihnachtsferien") + self.assertNotIn("2025-12-22", h_2026) + + def test_key_2026_ranges(self): + h = Germany(years=2026, subdiv="ST", categories=("school",)) + self.assertIn("2026-01-31", h) + self.assertEqual(h["2026-01-31"], "Winterferien") + self.assertIn("2026-03-30", h) + self.assertEqual(h["2026-03-30"], "Osterferien") + self.assertIn("2026-05-26", h) + self.assertEqual(h["2026-05-26"], "Pfingstferien") + self.assertIn("2026-07-04", h) + self.assertEqual(h["2026-07-04"], "Sommerferien") + + def test_2028_and_2029_ranges(self): + h_2028 = Germany(years=2028, subdiv="ST", categories=("school",)) + self.assertIn("2028-06-03", h_2028) + self.assertEqual(h_2028["2028-06-03"], "Pfingstferien") + self.assertIn("2028-10-02", h_2028) + self.assertEqual(h_2028["2028-10-02"], "Beweglicher Ferientag") + + h_2029 = Germany(years=2029, subdiv="ST", categories=("school",)) + self.assertIn("2029-04-30", h_2029) + self.assertEqual(h_2029["2029-04-30"], "Beweglicher Ferientag") + self.assertIn("2029-05-11", h_2029) + self.assertEqual(h_2029["2029-05-11"], "Pfingstferien") + + +class TestGermanyHamburgSchoolHolidays(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass(Germany, with_subdiv_categories=True) + + def test_christmas_cross_year(self): + # 2025 Christmas range spans 2025->2026. Ensure per-year population. + h_2025 = Germany(years=2025, subdiv="HH", categories=("school",)) + self.assertIn("2025-12-17", h_2025) + self.assertEqual(h_2025["2025-12-17"], "Weihnachtsferien") + + h_2026 = Germany(years=2026, subdiv="HH", categories=("school",)) + # 2026 object should include 2026-01-01 but not 2025-12-17 + self.assertIn("2026-01-01", h_2026) + self.assertEqual(h_2026["2026-01-01"], "Weihnachtsferien") + self.assertNotIn("2025-12-17", h_2026) + + def test_halfyear_and_spring_2026(self): + h = Germany(years=2026, subdiv="HH", categories=("school",)) + self.assertIn("2026-01-30", h) + self.assertEqual(h["2026-01-30"], "Halbjahrespause") + self.assertIn("2026-03-02", h) + self.assertEqual(h["2026-03-02"], "Frühjahrsferien") + + def test_himmelfahrt_pfingsten_and_summer_2026(self): + h = Germany(years=2026, subdiv="HH", categories=("school",)) + self.assertIn("2026-05-11", h) + self.assertEqual(h["2026-05-11"], "Himmelfahrt/Pfingsten") + self.assertIn("2026-07-09", h) + self.assertEqual(h["2026-07-09"], "Sommerferien") + self.assertIn("2026-08-19", h) + self.assertEqual(h["2026-08-19"], "Sommerferien") + + def test_default_categories_excludes_school(self): + # If no categories specified, school category should not be present. + h = Germany(years=2026, subdiv="HH") + self.assertNotIn("2026-07-09", h) + def test_l10n_en_us(self): self.assertLocalizedHolidays( "en_US", @@ -430,3 +673,382 @@ def test_l10n_uk(self): ("2022-12-25", "Перший день Різдва"), ("2022-12-26", "Другий день Різдва"), ) + + +class TestGermanyBadenWuerttembergSchoolHolidays(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass(Germany, with_subdiv_categories=True) + + def test_summer_and_christmas_2025(self): + h = Germany(years=2025, subdiv="BW", categories=("school",)) + self.assertIn("2025-07-31", h) + self.assertEqual(h["2025-07-31"], "Sommerferien") + self.assertIn("2025-12-22", h) + self.assertEqual(h["2025-12-22"], "Weihnachtsferien") + + def test_2026_ranges(self): + h = Germany(years=2026, subdiv="BW", categories=("school",)) + self.assertIn("2026-03-30", h) + self.assertEqual(h["2026-03-30"], "Osterferien") + self.assertIn("2026-05-26", h) + self.assertEqual(h["2026-05-26"], "Pfingstferien") + + +class TestGermanyBayernSchoolHolidays(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass(Germany, with_subdiv_categories=True) + + def test_christmas_2025_2026(self): + h1 = Germany(years=2025, subdiv="BY", categories=("school",)) + self.assertIn("2025-12-22", h1) + self.assertEqual(h1["2025-12-22"], "Weihnachtsferien") + + h2 = Germany(years=2026, subdiv="BY", categories=("school",)) + self.assertIn("2026-01-05", h2) + self.assertEqual(h2["2026-01-05"], "Weihnachtsferien") + + def test_spring_and_summer_2026(self): + h = Germany(years=2026, subdiv="BY", categories=("school",)) + self.assertIn("2026-02-16", h) + self.assertEqual(h["2026-02-16"], "Frühjahrsferien") + self.assertIn("2026-08-03", h) + self.assertEqual(h["2026-08-03"], "Sommerferien") + + +class TestGermanyBerlinSchoolHolidays(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass(Germany, with_subdiv_categories=True) + + def test_christmas_and_winter_2025_2026(self): + h = Germany(years=2025, subdiv="BE", categories=("school",)) + self.assertIn("2025-12-22", h) + self.assertEqual(h["2025-12-22"], "Weihnachtsferien") + + +class TestGermanyBrandenburgSchoolHolidays(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass(Germany, with_subdiv_categories=True) + + def test_christmas_cross_year_2025_2026(self): + g25 = Germany(years=2025, subdiv="BB", categories=("school",)) + self.assertIn("2025-12-22", g25) + self.assertEqual(g25["2025-12-22"], "Weihnachtsferien") + + g26 = Germany(years=2026, subdiv="BB", categories=("school",)) + # 2026 object should include the 2026 portion of Christmas but not 2025-12-22 + self.assertIn("2026-01-01", g26) + self.assertEqual(g26["2026-01-01"], "Weihnachtsferien") + self.assertNotIn("2025-12-22", g26) + + def test_spring_and_pfingsten_2026(self): + g = Germany(years=2026, subdiv="BB", categories=("school",)) + self.assertIn("2026-02-02", g) + self.assertEqual(g["2026-02-02"], "Winterferien") + self.assertIn("2026-03-30", g) + self.assertEqual(g["2026-03-30"], "Osterferien") + self.assertIn("2026-05-26", g) + self.assertEqual(g["2026-05-26"], "Pfingsten") + # Variable days + self.assertIn("2026-05-13", g) + self.assertIn("2026-05-15", g) + self.assertIn("2026-05-18", g) + + def test_summer_and_autumn_2026(self): + g = Germany(years=2026, subdiv="BB", categories=("school",)) + self.assertIn("2026-07-09", g) + self.assertEqual(g["2026-07-09"], "Sommerferien") + self.assertIn("2026-10-19", g) + self.assertEqual(g["2026-10-19"], "Herbstferien") + + def test_variable_days_2028_2029(self): + g28 = Germany(years=2028, subdiv="BB", categories=("school",)) + self.assertIn("2028-05-26", g28) + self.assertIn("2028-10-30", g28) + + g29 = Germany(years=2029, subdiv="BB", categories=("school",)) + self.assertIn("2029-04-30", g29) + self.assertIn("2029-05-11", g29) + self.assertIn("2029-05-22", g29) + + +class TestGermanyBremenSchoolHolidays(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass(Germany, with_subdiv_categories=True) + + def test_christmas_cross_year_2025_2026(self): + b25 = Germany(years=2025, subdiv="HB", categories=("school",)) + self.assertIn("2025-12-22", b25) + self.assertEqual(b25["2025-12-22"], "Weihnachtsferien") + + b26 = Germany(years=2026, subdiv="HB", categories=("school",)) + self.assertIn("2026-01-01", b26) + self.assertEqual(b26["2026-01-01"], "Weihnachtsferien") + self.assertNotIn("2025-12-22", b26) + + def test_halfyear_and_easter_2026(self): + b = Germany(years=2026, subdiv="HB", categories=("school",)) + self.assertIn("2026-02-02", b) + self.assertEqual(b["2026-02-02"], "Halbjahresferien") + self.assertIn("2026-03-23", b) + self.assertEqual(b["2026-03-23"], "Osterferien") + + def test_himmelfahrt_pfingsten_and_summer_2026(self): + b = Germany(years=2026, subdiv="HB", categories=("school",)) + self.assertIn("2026-05-15", b) + self.assertEqual(b["2026-05-15"], "Tag nach Himmelfahrt") + self.assertIn("2026-05-26", b) + self.assertEqual(b["2026-05-26"], "Pfingsten") + self.assertIn("2026-07-02", b) + self.assertEqual(b["2026-07-02"], "Sommerferien") + + def test_autumn_and_christmas_2026_2027(self): + b = Germany(years=2026, subdiv="HB", categories=("school",)) + self.assertIn("2026-10-12", b) + self.assertEqual(b["2026-10-12"], "Herbstferien") + + b27 = Germany(years=2027, subdiv="HB", categories=("school",)) + self.assertIn("2027-01-01", b27) + self.assertIn("2027-12-23", b27) + + def test_special_days_2028_2029(self): + b28 = Germany(years=2028, subdiv="HB", categories=("school",)) + self.assertIn("2028-10-02", b28) + self.assertEqual(b28["2028-10-02"], "Tag vor dem 03. Oktober") + + b29 = Germany(years=2029, subdiv="HB", categories=("school",)) + self.assertIn("2029-04-30", b29) + self.assertIn("2029-10-04", b29) + + def test_summer_2030(self): + b30 = Germany(years=2030, subdiv="HB", categories=("school",)) + self.assertIn("2030-07-11", b30) + self.assertEqual(b30["2030-07-11"], "Sommerferien") + + +class TestGermanyHessenSchoolHolidays(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass(Germany, with_subdiv_categories=True) + + def test_christmas_cross_year_2025_2026(self): + h25 = Germany(years=2025, subdiv="HE", categories=("school",)) + self.assertIn("2025-12-22", h25) + self.assertEqual(h25["2025-12-22"], "Weihnachtsferien") + + h26 = Germany(years=2026, subdiv="HE", categories=("school",)) + self.assertIn("2026-01-01", h26) + self.assertEqual(h26["2026-01-01"], "Weihnachtsferien") + self.assertNotIn("2025-12-22", h26) + + def test_easter_and_summer_2026(self): + h = Germany(years=2026, subdiv="HE", categories=("school",)) + self.assertIn("2026-03-30", h) + self.assertEqual(h["2026-03-30"], "Osterferien") + self.assertIn("2026-06-29", h) + self.assertEqual(h["2026-06-29"], "Sommerferien") + + def test_autumn_and_christmas_2026_2027(self): + h = Germany(years=2026, subdiv="HE", categories=("school",)) + self.assertIn("2026-10-05", h) + self.assertEqual(h["2026-10-05"], "Herbstferien") + + h27 = Germany(years=2027, subdiv="HE", categories=("school",)) + self.assertIn("2027-12-23", h27) + self.assertEqual(h27["2027-12-23"], "Weihnachtsferien") + + def test_ranges_through_2030(self): + h28 = Germany(years=2028, subdiv="HE", categories=("school",)) + self.assertIn("2028-07-03", h28) + self.assertIn("2028-10-09", h28) + + h29 = Germany(years=2029, subdiv="HE", categories=("school",)) + self.assertIn("2029-07-16", h29) + self.assertIn("2029-10-15", h29) + + h30 = Germany(years=2030, subdiv="HE", categories=("school",)) + self.assertIn("2030-07-22", h30) + + +class TestGermanyMecklenburgVorpommernSchoolHolidays(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass(Germany, with_subdiv_categories=True) + + def test_christmas_cross_year_2025_2026(self): + m25 = Germany(years=2025, subdiv="MV", categories=("school",)) + self.assertIn("2025-12-20", m25) + self.assertEqual(m25["2025-12-20"], "Weihnachtsferien") + + m26 = Germany(years=2026, subdiv="MV", categories=("school",)) + self.assertIn("2026-01-01", m26) + self.assertEqual(m26["2026-01-01"], "Weihnachtsferien") + self.assertNotIn("2025-12-20", m26) + + def test_winter_easter_pfingsten_2026(self): + m = Germany(years=2026, subdiv="MV", categories=("school",)) + self.assertIn("2026-02-09", m) + self.assertEqual(m["2026-02-09"], "Winterferien") + self.assertIn("2026-03-30", m) + self.assertEqual(m["2026-03-30"], "Osterferien") + self.assertIn("2026-05-22", m) + self.assertEqual(m["2026-05-22"], "Pfingstferien") + self.assertIn("2026-05-15", m) + + def test_summer_and_autumn_2026(self): + m = Germany(years=2026, subdiv="MV", categories=("school",)) + self.assertIn("2026-07-13", m) + self.assertEqual(m["2026-07-13"], "Sommerferien") + self.assertIn("2026-10-15", m) + self.assertEqual(m["2026-10-15"], "Herbstferien") + + def test_variable_and_special_days_2027_2029(self): + m27 = Germany(years=2027, subdiv="MV", categories=("school",)) + self.assertIn("2027-05-07", m27) + self.assertIn("2027-07-05", m27) + + m29 = Germany(years=2029, subdiv="MV", categories=("school",)) + self.assertIn("2029-03-09", m29) + self.assertIn("2029-04-30", m29) + self.assertIn("2029-05-11", m29) + self.assertIn("2029-06-18", m29) + + def test_ranges_through_2030(self): + m30 = Germany(years=2030, subdiv="MV", categories=("school",)) + self.assertIn("2030-04-17", m30) + self.assertIn("2030-07-01", m30) + + +class TestGermanyNiedersachsenSchoolHolidays(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass(Germany, with_subdiv_categories=True) + + def test_christmas_cross_year_2025_2026(self): + n25 = Germany(years=2025, subdiv="NI", categories=("school",)) + self.assertIn("2025-12-22", n25) + self.assertEqual(n25["2025-12-22"], "Weihnachtsferien") + + n26 = Germany(years=2026, subdiv="NI", categories=("school",)) + self.assertIn("2026-01-01", n26) + self.assertEqual(n26["2026-01-01"], "Weihnachtsferien") + self.assertNotIn("2025-12-22", n26) + + def test_halfyear_and_easter_2026(self): + n = Germany(years=2026, subdiv="NI", categories=("school",)) + self.assertIn("2026-02-02", n) + self.assertEqual(n["2026-02-02"], "Halbjahresferien") + self.assertIn("2026-03-23", n) + self.assertEqual(n["2026-03-23"], "Osterferien") + + def test_may_and_pfingsten_2026(self): + n = Germany(years=2026, subdiv="NI", categories=("school",)) + self.assertIn("2026-05-15", n) + self.assertIn("2026-05-26", n) + + def test_summer_and_autumn_2026(self): + n = Germany(years=2026, subdiv="NI", categories=("school",)) + self.assertIn("2026-07-02", n) + self.assertIn("2026-10-12", n) + + def test_ranges_through_2030(self): + n27 = Germany(years=2027, subdiv="NI", categories=("school",)) + self.assertIn("2027-07-08", n27) + self.assertIn("2027-10-16", n27) + + n29 = Germany(years=2029, subdiv="NI", categories=("school",)) + self.assertIn("2029-07-19", n29) + self.assertIn("2029-10-04", n29) + + n30 = Germany(years=2030, subdiv="NI", categories=("school",)) + self.assertIn("2030-07-11", n30) + + +class TestGermanyNordrheinWestfalenSchoolHolidays(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass(Germany, with_subdiv_categories=True) + + def test_christmas_cross_year_2025_2026(self): + w25 = Germany(years=2025, subdiv="NW", categories=("school",)) + self.assertIn("2025-12-22", w25) + self.assertEqual(w25["2025-12-22"], "Weihnachtsferien") + + w26 = Germany(years=2026, subdiv="NW", categories=("school",)) + self.assertIn("2026-01-01", w26) + self.assertEqual(w26["2026-01-01"], "Weihnachtsferien") + self.assertNotIn("2025-12-22", w26) + + def test_summer_2026(self): + w = Germany(years=2026, subdiv="NW", categories=("school",)) + self.assertIn("2026-07-20", w) + self.assertIn("2026-09-01", w) + + def test_autumn_2026(self): + w = Germany(years=2026, subdiv="NW", categories=("school",)) + self.assertIn("2026-10-17", w) + self.assertIn("2026-10-31", w) + + def test_oster_and_pfingsten_2027(self): + w27 = Germany(years=2027, subdiv="NW", categories=("school",)) + self.assertIn("2027-03-22", w27) + self.assertIn("2027-05-18", w27) + + def test_ranges_through_2030(self): + w29 = Germany(years=2029, subdiv="NW", categories=("school",)) + self.assertIn("2029-03-26", w29) + self.assertIn("2029-07-02", w29) + self.assertIn("2029-10-15", w29) + + w30 = Germany(years=2030, subdiv="NW", categories=("school",)) + self.assertIn("2030-04-15", w30) + + +class TestGermanyRheinlandPfalzSchoolHolidays(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + super().setUpClass(Germany, with_subdiv_categories=True) + + def test_summer_and_christmas_2025(self): + r25 = Germany(years=2025, subdiv="RP", categories=("school",)) + self.assertIn("2025-07-07", r25) + self.assertEqual(r25["2025-07-07"], "Sommerferien") + self.assertIn("2025-12-22", r25) + self.assertEqual(r25["2025-12-22"], "Weihnachtsferien") + + def test_2026_ranges(self): + r26 = Germany(years=2026, subdiv="RP", categories=("school",)) + self.assertIn("2026-03-30", r26) + self.assertEqual(r26["2026-03-30"], "Osterferien") + self.assertIn("2026-06-29", r26) + self.assertEqual(r26["2026-06-29"], "Sommerferien") + + def test_cross_year_christmas(self): + r26 = Germany(years=2026, subdiv="RP", categories=("school",)) + self.assertIn("2026-01-01", r26) + self.assertEqual(r26["2026-01-01"], "Weihnachtsferien") + self.assertNotIn("2025-12-22", r26) + + def test_ranges_through_2030(self): + r29 = Germany(years=2029, subdiv="RP", categories=("school",)) + self.assertIn("2029-07-16", r29) + self.assertIn("2029-10-22", r29) + + r30 = Germany(years=2030, subdiv="RP", categories=("school",)) + self.assertIn("2030-01-01", r30) + self.assertIn("2030-04-15", r30) + + h2 = Germany(years=2026, subdiv="BE", categories=("school",)) + self.assertIn("2026-02-02", h2) + self.assertEqual(h2["2026-02-02"], "Winterferien") + + def test_special_and_summer_2026(self): + h = Germany(years=2026, subdiv="BE", categories=("school",)) + self.assertIn("2026-05-15", h) + self.assertEqual(h["2026-05-15"], "Unterrichtsfreier Tag nach AZVO") + self.assertIn("2026-07-09", h) + self.assertEqual(h["2026-07-09"], "Sommerferien")