diff --git a/README.md b/README.md index 0d6111725..ef765d28c 100644 --- a/README.md +++ b/README.md @@ -105,7 +105,7 @@ and detailed information. ## Available Countries -We currently support 182 country codes. The standard way to refer to a country is by using its [ISO +We currently support 183 country codes. The standard way to refer to a country is by using its [ISO 3166-1 alpha-2 code](https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes), the same used for domain names, and for a subdivision its [ISO 3166-2 code](https://en.wikipedia.org/wiki/ISO_3166-2). Some countries have common or foreign names or @@ -987,6 +987,13 @@ any) in brackets, available languages and additional holiday categories. All cou +Niger +NE + +en_US, fr_NE +OPTIONAL + + Nigeria NG diff --git a/holidays/countries/__init__.py b/holidays/countries/__init__.py index a2f0a6a27..e1e68324a 100644 --- a/holidays/countries/__init__.py +++ b/holidays/countries/__init__.py @@ -132,6 +132,7 @@ from .netherlands import Netherlands, NL, NLD from .new_zealand import NewZealand, NZ, NZL from .nicaragua import Nicaragua, NI, NIC +from .niger import Niger, NE, NER from .nigeria import Nigeria, NG, NGA from .north_macedonia import NorthMacedonia, MK, MKD from .northern_mariana_islands import NorthernMarianaIslands, MP, MNP, HolidaysMP diff --git a/holidays/countries/niger.py b/holidays/countries/niger.py new file mode 100644 index 000000000..2f07095b2 --- /dev/null +++ b/holidays/countries/niger.py @@ -0,0 +1,320 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from gettext import gettext as tr + +from holidays import OPTIONAL, PUBLIC +from holidays.calendars import _CustomIslamicHolidays +from holidays.calendars.gregorian import ( + JAN, + FEB, + MAR, + APR, + MAY, + JUN, + JUL, + AUG, + SEP, + OCT, + NOV, + DEC, + SUN, +) +from holidays.groups import ChristianHolidays, InternationalHolidays, IslamicHolidays +from holidays.observed_holiday_base import ObservedHolidayBase, SUN_TO_NEXT_MON + + +class Niger(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays): + """Niger holidays. + + References: + * [Law No. 59-22 of December 24, 1959](https://web.archive.org/web/20241106023958/https://www.impots.gouv.ne/media/loi/1960.pdf) + * + * + * + * + * + * [Eid al-Adha](https://web.archive.org/web/20250117013558/https://www.timeanddate.com/holidays/niger/eid-al-adha) + * [Eid al-Fitr](https://web.archive.org/web/20250114130118/https://www.timeanddate.com/holidays/niger/eid-al-fitr) + * [Laylat al-Qadr](https://web.archive.org/web/20250531033137/https://www.timeanddate.com/holidays/niger/laylat-al-qadr) + * [Islamic New Year](https://web.archive.org/web/20240723135601/https://www.timeanddate.com/holidays/niger/muharram-new-year) + * [Prophet's Birthday](https://web.archive.org/web/20250124122731/https://www.timeanddate.com/holidays/niger/prophet-birthday) + + Notes: + After Law No. 97-020 of June 20, 1997 establishing public holidays came into + effect, holidays that fell on the mandatory weekly rest day (Sunday) were + observed on the next Monday. + """ + + country = "NE" + default_language = "fr_NE" + supported_languages = ("en_US", "fr_NE") + supported_categories = (OPTIONAL, PUBLIC) + # %s (observed). + observed_label = tr("%s (observé)") + # %s (estimated). + estimated_label = tr("%s (estimé)") + # %s (observed, estimated). + observed_estimated_label = tr("%s (observé, estimé)") + # Law No. 59-22. + start_year = 1960 + weekend = {SUN} + + def __init__(self, islamic_show_estimated: bool = True, *args, **kwargs): + """ + Args: + islamic_show_estimated: + Whether to add "estimated" label to Islamic holidays name + if holiday date is estimated. + """ + ChristianHolidays.__init__(self) + InternationalHolidays.__init__(self) + IslamicHolidays.__init__( + self, cls=NigerIslamicHolidays, show_estimated=islamic_show_estimated + ) + kwargs.setdefault("observed_rule", SUN_TO_NEXT_MON) + kwargs.setdefault("observed_since", 1998) + super().__init__(*args, **kwargs) + + def _populate_public_holidays(self): + # New Year's Day. + self._add_observed(self._add_new_years_day(tr("Jour de l'An"))) + + # Easter Monday. + self._add_easter_monday(tr("Lundi de Pâques")) + + if self._year >= 1995: + # National Concord Day. + self._add_observed(self._add_holiday_apr_24(tr("Fête nationale de la Concorde"))) + + # International Labor Day. + self._add_observed(self._add_labor_day(tr("Journée internationale du travail"))) + + if self._year >= 2024: + # Anniversary of the CNSP Coup. + self._add_observed(self._add_holiday_jul_26(tr("Anniversaire du coup d'État du CNSP"))) + + self._add_observed( + self._add_holiday_aug_3( + # Anniversary of the Proclamation of Independence. + tr("L'anniversaire de la proclamation de l'indépendance") + if self._year >= 1961 + # Independence Day. + else tr("Jour de l'indépendance") + ) + ) + + # National Day. + self._add_observed(self._add_holiday_dec_18(tr("Fête nationale"))) + + # Christmas Day. + self._add_observed(self._add_christmas_day(tr("Noël"))) + + # Islamic New Year. + for dt in self._add_islamic_new_year_day(tr("Jour de l'An musulman")): + self._add_observed(dt) + + # Prophet's Birthday. + for dt in self._add_mawlid_day(tr("Mouloud")): + self._add_observed(dt) + + # Laylat al-Qadr. + for dt in self._add_laylat_al_qadr_day(tr("Laylat al-Qadr")): + self._add_observed(dt) + + # Eid al-Fitr. + for dt in self._add_eid_al_fitr_day(tr("Korité")): + self._add_observed(dt) + + # Eid al-Adha. + self._add_eid_al_adha_day(tr("Tabaski")) + + # Day after Eid al-Adha. + for dt in self._add_eid_al_adha_day_two(tr("Lendemain de la Tabaski")): + self._add_observed(dt) + + def _populate_optional_holidays(self): + # Ascension Day. + self._add_ascension_thursday(tr("Ascension")) + + # Whit Monday. + self._add_whit_monday(tr("Lundi de Pentecôte")) + + # Assumption Day. + self._add_observed(self._add_assumption_of_mary_day(tr("Assomption"))) + + # All Saints' Day. + self._add_observed(self._add_all_saints_day(tr("Toussaint"))) + + +class NigerIslamicHolidays(_CustomIslamicHolidays): + EID_AL_ADHA_DATES = { + 1998: (APR, 8), + 1999: (MAR, 28), + 2000: (MAR, 16), + 2001: (MAR, 6), + 2002: (FEB, 23), + 2003: (FEB, 12), + 2004: (FEB, 2), + 2005: (JAN, 21), + 2006: ((JAN, 10), (DEC, 31)), + 2007: (DEC, 20), + 2008: (DEC, 9), + 2009: (NOV, 28), + 2010: (NOV, 17), + 2011: (NOV, 7), + 2012: (OCT, 26), + 2013: (OCT, 15), + 2014: (OCT, 5), + 2016: (SEP, 13), + 2017: (SEP, 2), + 2018: (AUG, 22), + 2019: (AUG, 11), + 2020: (JUL, 31), + 2021: (JUL, 20), + 2022: (JUL, 10), + 2023: (JUN, 28), + 2024: (JUN, 16), + 2025: (JUN, 7), + } + + EID_AL_FITR_DATES = { + 1998: (JAN, 30), + 1999: (JAN, 19), + 2000: ((JAN, 8), (DEC, 28)), + 2001: (DEC, 17), + 2002: (DEC, 6), + 2003: (NOV, 26), + 2004: (NOV, 14), + 2005: (NOV, 4), + 2006: (OCT, 24), + 2007: (OCT, 13), + 2008: (OCT, 2), + 2009: (SEP, 21), + 2010: (SEP, 10), + 2011: (AUG, 31), + 2012: (AUG, 19), + 2013: (AUG, 8), + 2014: (JUL, 29), + 2015: (JUL, 18), + 2016: (JUL, 7), + 2017: (JUN, 26), + 2018: (JUN, 15), + 2019: (JUN, 4), + 2020: (MAY, 23), + 2021: (MAY, 12), + 2022: (MAY, 1), + 2023: (APR, 21), + 2024: (APR, 9), + 2025: (MAR, 30), + } + + HIJRI_NEW_YEAR_DATES = { + 1998: (APR, 28), + 1999: (APR, 17), + 2000: (APR, 6), + 2001: (MAR, 26), + 2002: (MAR, 15), + 2003: (MAR, 5), + 2004: (FEB, 22), + 2005: (FEB, 10), + 2006: (JAN, 31), + 2007: (JAN, 20), + 2008: ((JAN, 10), (DEC, 29)), + 2009: (DEC, 18), + 2010: (DEC, 8), + 2011: (NOV, 27), + 2012: (NOV, 15), + 2013: (NOV, 5), + 2014: (OCT, 25), + 2015: (OCT, 15), + 2016: (OCT, 3), + 2017: (SEP, 22), + 2018: (SEP, 12), + 2019: (AUG, 31), + 2020: (AUG, 21), + 2021: (AUG, 10), + 2022: (JUL, 30), + 2023: (JUL, 19), + 2024: (JUL, 6), + 2025: (JUN, 27), + } + + LAYLAT_AL_QADR_DATES = { + 1998: (JAN, 26), + 1999: (JAN, 15), + 2000: ((JAN, 4), (DEC, 24)), + 2001: (DEC, 13), + 2002: (DEC, 2), + 2003: (NOV, 22), + 2004: (NOV, 11), + 2005: (OCT, 31), + 2006: (OCT, 20), + 2007: (OCT, 9), + 2008: (SEP, 28), + 2009: (SEP, 17), + 2010: (SEP, 6), + 2011: (AUG, 27), + 2012: (AUG, 15), + 2013: (AUG, 4), + 2014: (JUL, 25), + 2015: (JUL, 14), + 2016: (JUL, 2), + 2017: (JUN, 22), + 2018: (JUN, 11), + 2019: (JUN, 1), + 2020: (MAY, 20), + 2021: (MAY, 9), + 2022: (APR, 28), + 2023: (APR, 18), + 2024: (APR, 6), + 2025: (MAR, 27), + } + + MAWLID_DATES = { + 1998: (JUL, 7), + 1999: (JUN, 26), + 2000: (JUN, 15), + 2001: (JUN, 4), + 2002: (MAY, 24), + 2003: (MAY, 14), + 2004: (MAY, 2), + 2005: (APR, 21), + 2006: (APR, 11), + 2007: (MAR, 31), + 2008: (MAR, 20), + 2009: (MAR, 9), + 2010: (FEB, 26), + 2011: (FEB, 16), + 2012: (FEB, 5), + 2013: (JAN, 24), + 2014: (JAN, 14), + 2015: ((JAN, 3), (DEC, 24)), + 2016: (DEC, 12), + 2017: (DEC, 1), + 2018: (NOV, 21), + 2019: (NOV, 10), + 2020: (OCT, 29), + 2021: (OCT, 18), + 2022: (OCT, 8), + 2023: (SEP, 27), + 2024: (SEP, 16), + 2025: (SEP, 5), + } + + +class NE(Niger): + pass + + +class NER(Niger): + pass diff --git a/holidays/locale/en_US/LC_MESSAGES/NE.po b/holidays/locale/en_US/LC_MESSAGES/NE.po new file mode 100644 index 000000000..304087de4 --- /dev/null +++ b/holidays/locale/en_US/LC_MESSAGES/NE.po @@ -0,0 +1,118 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) +# +# Niger holidays en_US localization. +# +msgid "" +msgstr "" +"Project-Id-Version: Holidays 0.75\n" +"POT-Creation-Date: 2025-05-30 19:15+0000\n" +"PO-Revision-Date: 2025-05-30 19:15+0000\n" +"Last-Translator: Abheelash Mishra \n" +"Language-Team: Holidays Localization Team\n" +"Language: en_US\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Lingva 5.0.6\n" +"X-Source-Language: fr\n" + +#. %s (observed). +#, c-format +msgid "%s (observé)" +msgstr "%s (observed)" + +#. %s (estimated). +#, c-format +msgid "%s (estimé)" +msgstr "%s (estimated)" + +#. %s (observed, estimated). +#, c-format +msgid "%s (observé, estimé)" +msgstr "%s (observed, estimated)" + +#. New Year's Day. +msgid "Jour de l'An" +msgstr "New Year's Day" + +#. Easter Monday. +msgid "Lundi de Pâques" +msgstr "Easter Monday" + +#. National Concord Day. +msgid "Fête nationale de la Concorde" +msgstr "National Concord Day" + +#. International Labor Day. +msgid "Journée internationale du travail" +msgstr "International Labor Day" + +#. Anniversary of the CNSP Coup. +msgid "Anniversaire du coup d'État du CNSP" +msgstr "Anniversary of the CNSP Coup" + +#. Anniversary of the Proclamation of Independence. +msgid "L'anniversaire de la proclamation de l'indépendance" +msgstr "Anniversary of the Proclamation of Independence" + +#. Independence Day. +msgid "Jour de l'indépendance" +msgstr "Independence Day" + +#. National Day. +msgid "Fête nationale" +msgstr "National Day" + +#. Christmas Day. +msgid "Noël" +msgstr "Christmas Day" + +#. Islamic New Year. +msgid "Jour de l'An musulman" +msgstr "Islamic New Year" + +#. Prophet's Birthday. +msgid "Mouloud" +msgstr "Prophet's Birthday" + +#. Eid al-Fitr. +msgid "Korité" +msgstr "Eid al-Fitr" + +#. Eid al-Adha. +msgid "Tabaski" +msgstr "Eid al-Adha" + +#. Day after Eid al-Adha. +msgid "Lendemain de la Tabaski" +msgstr "Day after Eid al-Adha" + +#. Laylat al-Qadr. +msgid "Laylat al-Qadr" +msgstr "Laylat al-Qadr" + +#. Ascension Day. +msgid "Ascension" +msgstr "Ascension" + +#. Whit Monday. +msgid "Lundi de Pentecôte" +msgstr "Whit Monday" + +#. Assumption Day. +msgid "Assomption" +msgstr "Assumption Day" + +#. All Saints' Day. +msgid "Toussaint" +msgstr "All Saints' Day" diff --git a/holidays/locale/fr_NE/LC_MESSAGES/NE.po b/holidays/locale/fr_NE/LC_MESSAGES/NE.po new file mode 100644 index 000000000..a59ec48ac --- /dev/null +++ b/holidays/locale/fr_NE/LC_MESSAGES/NE.po @@ -0,0 +1,118 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) +# +# Niger holidays. +# +msgid "" +msgstr "" +"Project-Id-Version: Holidays 0.75\n" +"POT-Creation-Date: 2025-06-02 13:28+0000\n" +"PO-Revision-Date: 2025-06-02 13:28+0000\n" +"Last-Translator: Abheelash Mishra \n" +"Language-Team: Holidays Localization Team\n" +"Language: fr_NE\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: Lingva 5.0.6\n" +"X-Source-Language: fr_NE\n" + +#. %s (observed). +#, c-format +msgid "%s (observé)" +msgstr "" + +#. %s (estimated). +#, c-format +msgid "%s (estimé)" +msgstr "" + +#. %s (observed, estimated). +#, c-format +msgid "%s (observé, estimé)" +msgstr "" + +#. New Year's Day. +msgid "Jour de l'An" +msgstr "" + +#. Easter Monday. +msgid "Lundi de Pâques" +msgstr "" + +#. National Concord Day. +msgid "Fête nationale de la Concorde" +msgstr "" + +#. International Labor Day. +msgid "Journée internationale du travail" +msgstr "" + +#. Anniversary of the CNSP Coup. +msgid "Anniversaire du coup d'État du CNSP" +msgstr "" + +#. Anniversary of the Proclamation of Independence. +msgid "L'anniversaire de la proclamation de l'indépendance" +msgstr "" + +#. Independence Day. +msgid "Jour de l'indépendance" +msgstr "" + +#. National Day. +msgid "Fête nationale" +msgstr "" + +#. Christmas Day. +msgid "Noël" +msgstr "" + +#. Islamic New Year. +msgid "Jour de l'An musulman" +msgstr "" + +#. Prophet's Birthday. +msgid "Mouloud" +msgstr "" + +#. Laylat al-Qadr. +msgid "Laylat al-Qadr" +msgstr "" + +#. Eid al-Fitr. +msgid "Korité" +msgstr "" + +#. Eid al-Adha. +msgid "Tabaski" +msgstr "" + +#. Day after Eid al-Adha. +msgid "Lendemain de la Tabaski" +msgstr "" + +#. Ascension Day. +msgid "Ascension" +msgstr "" + +#. Whit Monday. +msgid "Lundi de Pentecôte" +msgstr "" + +#. Assumption Day. +msgid "Assomption" +msgstr "" + +#. All Saints' Day. +msgid "Toussaint" +msgstr "" diff --git a/holidays/registry.py b/holidays/registry.py index 3c99e3c52..72564c028 100644 --- a/holidays/registry.py +++ b/holidays/registry.py @@ -140,6 +140,7 @@ "netherlands": ("Netherlands", "NL", "NLD"), "new_zealand": ("NewZealand", "NZ", "NZL"), "nicaragua": ("Nicaragua", "NI", "NIC"), + "niger": ("Niger", "NE", "NER"), "nigeria": ("Nigeria", "NG", "NGA"), "north_macedonia": ("NorthMacedonia", "MK", "MKD"), "northern_mariana_islands": ("NorthernMarianaIslands", "MP", "MNP", "HolidaysMP"), diff --git a/tests/countries/test_niger.py b/tests/countries/test_niger.py new file mode 100644 index 000000000..49f502da2 --- /dev/null +++ b/tests/countries/test_niger.py @@ -0,0 +1,373 @@ +# holidays +# -------- +# A fast, efficient Python library for generating country, province and state +# specific sets of holidays on the fly. It aims to make determining whether a +# specific date is a holiday as fast and flexible as possible. +# +# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file) +# dr-prodigy (c) 2017-2023 +# ryanss (c) 2014-2017 +# Website: https://github.com/vacanza/holidays +# License: MIT (see LICENSE file) + +from unittest import TestCase + +from holidays import OPTIONAL +from holidays.countries.niger import Niger, NE, NER +from tests.common import CommonCountryTests + + +class TestNiger(CommonCountryTests, TestCase): + @classmethod + def setUpClass(cls): + years = range(1960, 2050) + super().setUpClass(Niger, years=years, years_non_observed=years) + cls.no_estimated_holidays = Niger(years=years, islamic_show_estimated=False) + cls.optional_holidays = Niger(categories=OPTIONAL, years=years) + cls.optional_holidays_non_observed = Niger( + categories=OPTIONAL, years=years, observed=False + ) + + def test_country_aliases(self): + self.assertAliases(Niger, NE, NER) + + def test_no_holidays(self): + self.assertNoHolidays(Niger(years=1959)) + + def test_new_years_day(self): + name = "Jour de l'An" + name_observed = f"{name} (observé)" + self.assertHolidayName(name, (f"{year}-01-01" for year in range(1960, 2050))) + obs_dt = ( + "2012-01-02", + "2017-01-02", + "2023-01-02", + ) + self.assertHolidayName(name_observed, obs_dt) + self.assertNoNonObservedHoliday(obs_dt) + self.assertNoHolidayName(name_observed, range(1960, 1998)) + + def test_easter_monday(self): + name = "Lundi de Pâques" + self.assertHolidayName( + name, + "2020-04-13", + "2021-04-05", + "2022-04-18", + "2023-04-10", + "2024-04-01", + "2025-04-21", + ) + self.assertHolidayName(name, range(1960, 2050)) + + def test_concord_day(self): + name = "Fête nationale de la Concorde" + name_observed = f"{name} (observé)" + self.assertHolidayName(name, (f"{year}-04-24" for year in range(1995, 2050))) + self.assertNoHolidayName(name, range(1960, 1995)) + obs_dt = ( + "2011-04-25", + "2016-04-25", + "2022-04-25", + ) + self.assertHolidayName(name_observed, obs_dt) + self.assertNoNonObservedHolidayName(name, obs_dt) + self.assertNoHolidayName(name_observed, range(1960, 1998)) + + def test_international_labor_day(self): + name = "Journée internationale du travail" + name_observed = f"{name} (observé)" + self.assertHolidayName(name, (f"{year}-05-01" for year in range(1960, 2050))) + obs_dt = ( + "2011-05-02", + "2016-05-02", + "2022-05-02", + ) + self.assertHolidayName(name_observed, obs_dt) + self.assertNoNonObservedHoliday(obs_dt) + self.assertNoHolidayName(name_observed, range(1960, 1998)) + + def test_ascension_day(self): + name = "Ascension" + self.assertNoHolidayName(name) + self.assertHolidayName( + name, + self.optional_holidays, + "2020-05-21", + "2021-05-13", + "2022-05-26", + "2023-05-18", + "2024-05-09", + "2025-05-29", + ) + self.assertHolidayName(name, self.optional_holidays, range(1960, 2050)) + + def test_whit_monday(self): + name = "Lundi de Pentecôte" + self.assertNoHolidayName(name) + self.assertHolidayName( + name, + self.optional_holidays, + "2020-06-01", + "2021-05-24", + "2022-06-06", + "2023-05-29", + "2024-05-20", + "2025-06-09", + ) + self.assertHolidayName(name, self.optional_holidays, range(1960, 2050)) + + def test_cnsp_coup_anniversary(self): + name = "Anniversaire du coup d'État du CNSP" + name_observed = f"{name} (observé)" + self.assertHolidayName(name, (f"{year}-07-26" for year in range(2024, 2050))) + self.assertNoHolidayName(name, range(1960, 2024)) + obs_dt = ( + "2026-07-27", + "2037-07-27", + ) + self.assertHolidayName(name_observed, obs_dt) + self.assertNoNonObservedHoliday(obs_dt) + self.assertNoHolidayName(name_observed, range(1960, 2024)) + + def test_independence_day(self): + name_1 = "Jour de l'indépendance" + name_2 = "L'anniversaire de la proclamation de l'indépendance" + name_observed = f"{name_2} (observé)" + self.assertHolidayName(name_1, "1960-08-03") + self.assertNoHolidayName(name_1, range(1961, 2050)) + self.assertHolidayName(name_2, (f"{year}-08-03" for year in range(1961, 2050))) + self.assertNoHolidayName(name_2, 1960) + obs_dt = ( + "2008-08-04", + "2014-08-04", + "2025-08-04", + ) + self.assertHolidayName(name_observed, obs_dt) + self.assertNoNonObservedHoliday(obs_dt) + self.assertNoHolidayName(name_observed, range(1960, 1998)) + + def test_assumption_day(self): + name = "Assomption" + name_observed = f"{name} (observé)" + self.assertNoHolidayName(name) + self.assertHolidayName( + name, self.optional_holidays, (f"{year}-08-15" for year in range(1960, 2050)) + ) + obs_dt = ( + "2010-08-16", + "2021-08-16", + ) + self.assertHolidayName(name_observed, self.optional_holidays, obs_dt) + self.assertNoNonObservedHoliday(self.optional_holidays_non_observed, obs_dt) + self.assertNoHolidayName(name_observed, self.optional_holidays, range(1960, 1998)) + + def test_all_saints_day(self): + name = "Toussaint" + name_observed = f"{name} (observé)" + self.assertNoHolidayName(name) + self.assertHolidayName( + name, self.optional_holidays, (f"{year}-11-01" for year in range(1960, 2050)) + ) + obs_dt = ( + "2009-11-02", + "2015-11-02", + "2020-11-02", + ) + self.assertHolidayName(name_observed, self.optional_holidays, obs_dt) + self.assertNoNonObservedHoliday(self.optional_holidays_non_observed, obs_dt) + self.assertNoHolidayName(name_observed, self.optional_holidays, range(1960, 1998)) + + def test_national_day(self): + name = "Fête nationale" + name_observed = f"{name} (observé)" + self.assertHolidayName(name, (f"{year}-12-18" for year in range(1960, 2050))) + obs_dt = ( + "2011-12-19", + "2016-12-19", + "2022-12-19", + ) + self.assertHolidayName(name_observed, obs_dt) + self.assertNoNonObservedHoliday(obs_dt) + self.assertNoHolidayName(name_observed, range(1960, 1998)) + + def test_christmas_day(self): + name = "Noël" + name_observed = f"{name} (observé)" + self.assertHolidayName(name, (f"{year}-12-25" for year in range(1960, 2050))) + obs_dt = ( + "2011-12-26", + "2016-12-26", + "2022-12-26", + ) + self.assertHolidayName(name_observed, obs_dt) + self.assertNoNonObservedHoliday(obs_dt) + self.assertNoHolidayName(name_observed, range(1960, 1998)) + + def test_islamic_new_year(self): + name = "Jour de l'An musulman" + self.assertHolidayName( + name, + self.no_estimated_holidays, + "2020-08-21", + "2021-08-10", + "2022-07-30", + "2023-07-19", + "2024-07-06", + "2025-06-27", + ) + self.assertHolidayName(name, self.no_estimated_holidays, range(1960, 2050)) + obs_dt = ( + "2004-02-23", + "2011-11-28", + ) + self.assertHolidayName(f"{name} (observé)", self.no_estimated_holidays, obs_dt) + self.assertNoNonObservedHoliday(obs_dt) + + def test_prophets_birthday(self): + name = "Mouloud" + self.assertHolidayName( + name, + self.no_estimated_holidays, + "2020-10-29", + "2021-10-18", + "2022-10-08", + "2023-09-27", + "2024-09-16", + "2025-09-05", + ) + self.assertHolidayName(name, self.no_estimated_holidays, range(1960, 2050)) + obs_dt = ( + "2004-05-03", + "2012-02-06", + "2019-11-11", + ) + self.assertHolidayName(f"{name} (observé)", self.no_estimated_holidays, obs_dt) + self.assertNoNonObservedHoliday(obs_dt) + + def test_laylat_al_qadr(self): + name = "Laylat al-Qadr" + self.assertHolidayName( + name, + self.no_estimated_holidays, + "2020-05-20", + "2021-05-09", + "2022-04-28", + "2023-04-18", + "2024-04-06", + "2025-03-27", + ) + self.assertHolidayName(name, self.no_estimated_holidays, range(1960, 2050)) + obs_dt = ( + "2000-12-25", + "2008-09-29", + "2013-08-05", + "2021-05-10", + ) + self.assertHolidayName(f"{name} (observé)", self.no_estimated_holidays, obs_dt) + + def test_eid_al_fitr(self): + name = "Korité" + self.assertHolidayName( + name, + self.no_estimated_holidays, + "2020-05-23", + "2021-05-12", + "2022-05-01", + "2023-04-21", + "2024-04-09", + "2025-03-30", + ) + self.assertHolidayName(name, self.no_estimated_holidays, range(1960, 2050)) + obs_dt = ( + "2004-11-15", + "2012-08-20", + "2022-05-02", + "2025-03-31", + ) + self.assertHolidayName(f"{name} (observé)", self.no_estimated_holidays, obs_dt) + self.assertNoNonObservedHoliday(obs_dt) + + def test_eid_al_adha(self): + name = "Tabaski" + self.assertHolidayName( + name, + self.no_estimated_holidays, + "2020-07-31", + "2021-07-20", + "2022-07-10", + "2023-06-28", + "2024-06-16", + "2025-06-07", + ) + self.assertHolidayName(name, self.no_estimated_holidays, range(1960, 2050)) + + def test_day_after_eid_al_adha(self): + name = "Lendemain de la Tabaski" + self.assertHolidayName( + name, + self.no_estimated_holidays, + "2020-08-01", + "2021-07-21", + "2022-07-11", + "2023-06-29", + "2024-06-17", + "2025-06-08", + ) + self.assertHolidayName(name, self.no_estimated_holidays, range(1960, 2050)) + obs_dt = ( + "2009-11-30", + "2017-09-04", + "2025-06-09", + ) + self.assertHolidayName(f"{name} (observé)", self.no_estimated_holidays, obs_dt) + self.assertNoNonObservedHoliday(obs_dt) + + def test_l10n_default(self): + self.assertLocalizedHolidays( + ("2025-01-01", "Jour de l'An"), + ("2025-03-27", "Laylat al-Qadr"), + ("2025-03-30", "Korité"), + ("2025-03-31", "Korité (observé)"), + ("2025-04-21", "Lundi de Pâques"), + ("2025-04-24", "Fête nationale de la Concorde"), + ("2025-05-01", "Journée internationale du travail"), + ("2025-05-29", "Ascension"), + ("2025-06-07", "Tabaski"), + ("2025-06-08", "Lendemain de la Tabaski"), + ("2025-06-09", "Lendemain de la Tabaski (observé); Lundi de Pentecôte"), + ("2025-06-27", "Jour de l'An musulman"), + ("2025-07-26", "Anniversaire du coup d'État du CNSP"), + ("2025-08-03", "L'anniversaire de la proclamation de l'indépendance"), + ("2025-08-04", "L'anniversaire de la proclamation de l'indépendance (observé)"), + ("2025-08-15", "Assomption"), + ("2025-09-05", "Mouloud"), + ("2025-11-01", "Toussaint"), + ("2025-12-18", "Fête nationale"), + ("2025-12-25", "Noël"), + ) + + def test_l10n_en_us(self): + self.assertLocalizedHolidays( + "en_US", + ("2025-01-01", "New Year's Day"), + ("2025-03-27", "Laylat al-Qadr"), + ("2025-03-30", "Eid al-Fitr"), + ("2025-03-31", "Eid al-Fitr (observed)"), + ("2025-04-21", "Easter Monday"), + ("2025-04-24", "National Concord Day"), + ("2025-05-01", "International Labor Day"), + ("2025-05-29", "Ascension"), + ("2025-06-07", "Eid al-Adha"), + ("2025-06-08", "Day after Eid al-Adha"), + ("2025-06-09", "Day after Eid al-Adha (observed); Whit Monday"), + ("2025-06-27", "Islamic New Year"), + ("2025-07-26", "Anniversary of the CNSP Coup"), + ("2025-08-03", "Anniversary of the Proclamation of Independence"), + ("2025-08-04", "Anniversary of the Proclamation of Independence (observed)"), + ("2025-08-15", "Assumption Day"), + ("2025-09-05", "Prophet's Birthday"), + ("2025-11-01", "All Saints' Day"), + ("2025-12-18", "National Day"), + ("2025-12-25", "Christmas Day"), + )