Repository: vacanza/python-holidays

Issue:
Add United Republic of Tanzania holidays
Links:
  - https://en.wikipedia.org/wiki/Public_holidays_in_Tanzania
  - https://www.timeanddate.com/holidays/tanzania/


Discussion:

Resolving patch:
diff --git a/holidays/countries/__init__.py b/holidays/countries/__init__.py
--- a/holidays/countries/__init__.py
+++ b/holidays/countries/__init__.py
@@ -129,6 +129,7 @@
 from .sweden import Sweden, SE, SWE
 from .switzerland import Switzerland, CH, CHE
 from .taiwan import Taiwan, TW, TWN
+from .tanzania import Tanzania, TZ, TZA
 from .thailand import Thailand, TH, THA
 from .tunisia import Tunisia, TN, TUN
 from .turkey import Turkey, TR, TUR
diff --git a/holidays/countries/tanzania.py b/holidays/countries/tanzania.py
new file mode 100644
--- /dev/null
+++ b/holidays/countries/tanzania.py
@@ -0,0 +1,296 @@
+#  python-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: dr-prodigy <dr.prodigy.github@gmail.com> (c) 2017-2023
+#           ryanss <ryanssdev@icloud.com> (c) 2014-2017
+#  Website: https://github.com/dr-prodigy/python-holidays
+#  License: MIT (see LICENSE file)
+
+from gettext import gettext as tr
+
+from holidays.calendars import _CustomIslamicCalendar
+from holidays.calendars.gregorian import JAN, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC
+from holidays.constants import BANK, PUBLIC
+from holidays.groups import ChristianHolidays, InternationalHolidays, IslamicHolidays
+from holidays.holiday_base import HolidayBase
+
+
+class Tanzania(HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays):
+    """
+    References:
+    - https://old.tanzlii.org/tz/legislation/act/1962/48/  # 1962
+    - https://old.tanzlii.org/tz/legislation/act/1964/52/  # 1964
+    - https://old.tanzlii.org/tz/legislation/act/1966/39/  # 1966
+    - https://www.parliament.go.tz/polis/uploads/bills/acts/1566639469-The%20Written%20Laws%20(Miscellaneous%20Amendments)%20Act,%201993.pdf  # 1993  # noqa: E501
+    - https://www.parliament.go.tz/polis/uploads/bills/acts/1566638051-The%20Written%20Laws%20(Miscellaneous%20Amendments)%20(No.%202)%20Act,%201994.pdf  # 1994  # noqa: E501
+    - http://parliament.go.tz/polis/uploads/bills/acts/1454076376-ActNo-25-2002.pdf  # 2002
+    - https://en.wikipedia.org/wiki/Public_holidays_in_Tanzania
+    - http://mytanzaniatimes.blogspot.com/2014/08/holiday-nane-nane-farmers-day-in.html
+    - https://www.theeastafrican.co.ke/tea/business/tanzania-declares-public-holiday-on-census-day-3918836  # noqa: E501
+    - https://www.dw.com/en/samia-suluhu-hassan-who-is-tanzanias-new-president/a-56932264
+
+    Checked With:
+    - https://www.bot.go.tz/webdocs/Other/2023%20public%20holidays.pdf  # 2023
+    - https://www.bot.go.tz/webdocs/Other/PUBLIC%20HOLIDAYS%202022.pdf  # 2022
+    - https://www.bot.go.tz/webdocs/Other/PUBLIC%20HOLIDAYS%202021.pdf  # 2021
+    - https://www.bot.go.tz/webdocs/Other/PUBLIC%20HOLIDAYS%202020.pdf  # 2020
+    - https://issamichuzi.blogspot.com/2017/11/sikukuu-za-kitaifa-zenye-mapumziko-kwa.html  # 2018
+    - https://www.timeanddate.com/holidays/tanzania/ (from 2013 onwards)
+
+    Limitations:
+
+    - Only works from 1994 onwards due to the lack of sources for certain legislation:
+        Government Notices No. 79 of 1977
+        Government Notices No. 300 of 1985
+        Government Notices No. 296 of 1994
+
+    - Exact Islamic holidays dates are only available for 2013-2023; the rest are estimates.
+    """
+
+    country = "TZ"
+    supported_categories = {BANK, PUBLIC}
+    default_language = "sw"
+    estimated_label = tr("%s* (*makisio)")
+    supported_languages = ("en_US", "sw")
+
+    # Special Holidays.
+
+    # John Pombe Magufuli Inauguration Day.
+    john_magufuli_inauguration = tr("Sikukuu ya Kuapishwa kwa John Pombe Magufuli")
+
+    # Tanzania General Election Day.
+    tz_election_day = tr("Sikukuu ya Uchaguzi Mkuu wa Tanzania")
+
+    # National Population and Housing Census Day.
+    phc_census_day = tr("Siku ya Sensa ya Kitaifa ya Watu na Makazi")
+
+    # John Pombe Magufuli's Funeral.
+    john_magufuli_funeral = tr("Mazishi cha John Pombe Magufuli")
+
+    special_public_holidays = {
+        2002: (AUG, 25, phc_census_day),
+        2015: (NOV, 5, john_magufuli_inauguration),
+        2020: (OCT, 28, tz_election_day),
+        2021: (
+            (MAR, 22, john_magufuli_funeral),
+            (MAR, 25, john_magufuli_funeral),
+        ),
+        2022: (AUG, 23, phc_census_day),
+    }
+
+    def __init__(self, *args, **kwargs):
+        ChristianHolidays.__init__(self)
+        InternationalHolidays.__init__(self)
+        IslamicHolidays.__init__(self, calendar=TanzaniaIslamicCalendar())
+        super().__init__(*args, **kwargs)
+
+    def _populate_bank_holidays(self):
+        # Written Law (Miscellaneous Amendments) (No. 2) Act, 1994.
+        if self._year <= 1993:
+            return None
+
+        # Sikukuu ya Pasaka.
+        # Status: In-Use.
+        # Only observed by financial institutions.
+
+        # Easter Sunday.
+        self._add_easter_sunday(tr("Sikukuu ya Pasaka"))
+
+    def _populate_public_holidays(self):
+        # Written Law (Miscellaneous Amendments) (No. 2) Act, 1994.
+        if self._year <= 1993:
+            return None
+
+        # In-lieus ("Badala ya %s") are observed on Monday should it fall on the weekends.
+        # Abrogated in Public Holidays Ordinance  No. 28 of 1966.
+        # Reinstituted in Written Law (Miscellaneous Amendments) (No. 2) Act, 1994.
+        # Claimed to be abrogated again on an unspecified date.
+
+        # Fixed Date Holidays.
+
+        # Mwaka Mpya.
+        # Status: In-Use.
+        # Abrogated in Public Holidays Ordinance No. 28 of 1966.
+        # Reinstituted prior to the Written Law (Miscellaneous Amendments) (No. 1) Act, 1993.
+
+        # New Year's Day.
+        self._add_new_years_day(tr("Mwaka Mpya"))
+
+        # Mapinduzi ya Zanzibar.
+        # Status: In-Use.
+        # Commemorates the fall of the Sultanate of Zanzibar on Jan 12, 1964.
+
+        # Zanzibar Revolution Day.
+        self._add_holiday_jan_12(tr("Mapinduzi ya Zanzibar"))
+
+        # Siku ya kumbukumbu ya Rais wa Kwanza wa Serikali ya Mapinduzi Zanzibar
+        # Sheikh Abeid Amani Karume.
+        # Status: In-Use.
+        # Commemorates the death of Abeid Amani Karume on Apr 7, 1972.
+        # Assumed to start via Government Notices 79 of 1977.
+
+        self._add_holiday_apr_7(
+            # The Sheikh Abeid Amani Karume Day.
+            tr(
+                "Siku ya kumbukumbu ya Rais wa Kwanza wa Serikali ya Mapinduzi Zanzibar "
+                "Sheikh Abeid Amani Karume"
+            )
+        )
+
+        # Muungano wa Tanganyika na Zanzibar.
+        # Status: In-Use.
+        # Commemorates the creation of the United Republic of Tanzania on Apr 26, 1964.
+
+        # Union Celebrations.
+        self._add_holiday_apr_26(tr("Muungano wa Tanganyika na Zanzibar"))
+
+        # Sikukuu ya Wafanyakazi.
+        # Status: In-Use.
+
+        # Worker's Day.
+        self._add_labor_day(tr("Sikukuu ya Wafanyakazi"))
+
+        # Sabasaba.
+        # Status: In-Use.
+        # Celebrates the formation of Tanganyika African National Union party on Jul 7, 1954.
+        # First started in the Public Holidays Ordinance No. 57 of 1964.
+        # Abrogated in 1993 (need official source on this)
+        # Reinstituted via Government Notices 296 of 1994.
+
+        # International Trade Fair.
+        self._add_holiday_jul_7(tr("Sabasaba"))
+
+        # Siku ya Wakulima.
+        # Status: In-Use.
+        # Also known as Nane Nane.
+        # Started via Government Notices 296 of 1994 to replace Sabasaba.
+
+        # Peasants Day.
+        self._add_holiday_aug_8(tr("Siku ya Wakulima"))
+
+        # Kumbukumbu ya Mwalimu Nyerere.
+        # Status: In-Use.
+        # Commemorates the death of Julius Kambarage Nyerere on Oct 14, 1999.
+        # Adopted in Written Law (Miscellaneous Amendments) (No. 3) Act, 2002.
+
+        if self._year >= 2003:
+            # The Mwalimu Nyerere Day.
+            self._add_holiday_oct_14(tr("Kumbukumbu ya Mwalimu Nyerere"))
+
+        # Uhuru na Jamhuri.
+        # Status: In-Use.
+        # Commemorates the Independence of Tanganyika from the United Kingdom on Dec 9, 1961.
+
+        # Independence and Republic Day.
+        self._add_holiday_dec_9(tr("Uhuru na Jamhuri"))
+
+        # Kuzaliwa Kristo.
+        # Status: In-Use.
+
+        # Christmas Day.
+        self._add_christmas_day(tr("Kuzaliwa Kristo"))
+
+        # Siku ya Kupeana Zawadi.
+        # Status: In-Use.
+        # Abrogated in Public Holidays Ordinance No. 28 of 1966.
+        # Reinstituted in Written Law (Miscellaneous Amendments) (No. 1) Act, 1993.
+
+        # Boxing Day.
+        self._add_christmas_day_two(tr("Siku ya Kupeana Zawadi"))
+
+        # Christian Calendar Holidays.
+
+        # Ijumaa Kuu.
+        # Status: In-Use.
+
+        # Good Friday.
+        self._add_good_friday(tr("Ijumaa Kuu"))
+
+        # Jumatatu ya Pasaka.
+        # Status: In-Use.
+
+        # Easter Monday.
+        self._add_easter_monday(tr("Jumatatu ya Pasaka"))
+
+        # Islamic Calendar Holidays.
+
+        # Eid El-Fitry.
+        # Status: In-Use.
+        # Used to be celebrated for 2 days in the 1964 and 1966 amendments.
+
+        # Eid al-Fitr.
+        self._add_eid_al_fitr_day(tr("Eid El-Fitry"))
+
+        # Eid El-Hajj.
+        # Status: In-Use.
+        # Used to be celebrated for 2 days in the 1964 amendments.
+
+        # Eid al-Adha.
+        self._add_eid_al_adha_day(tr("Eid El-Hajj"))
+
+        # Maulidi.
+        # Status: In-Use.
+
+        # Maulid Day.
+        self._add_mawlid_day(tr("Maulidi"))
+
+        # Defunct Holidays.
+
+        # 5th Day of February ??? (Name Unavailable)
+        # Status: Defunct.
+        # Abrogated in Written Law (Miscellaneous Amendments) (No. 1) Act, 1993.
+
+
+class TZ(Tanzania):
+    pass
+
+
+class TZA(Tanzania):
+    pass
+
+
+class TanzaniaIslamicCalendar(_CustomIslamicCalendar):
+    EID_AL_ADHA_DATES = {
+        2013: (OCT, 15),
+        2014: (OCT, 5),
+        2015: (SEP, 23),
+        2016: (SEP, 16),
+        2017: (SEP, 2),
+        2018: (AUG, 22),
+        2019: (AUG, 13),
+        2020: (JUL, 31),
+        2021: (JUL, 21),
+        2022: (JUL, 10),
+        2023: (JUN, 29),
+    }
+
+    EID_AL_FITR_DATES = {
+        2013: (AUG, 8),
+        2014: (JUL, 29),
+        2015: (JUL, 18),
+        2016: (JUL, 7),
+        2017: (JUN, 26),
+        2018: (JUN, 15),
+        2019: (JUN, 5),
+        2020: (MAY, 24),
+        2021: (MAY, 14),
+        2022: (MAY, 3),
+        2023: (APR, 22),
+    }
+
+    MAWLID_DATES = {
+        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, 19),
+        2022: (OCT, 9),
+        2023: (SEP, 28),
+    }
diff --git a/holidays/registry.py b/holidays/registry.py
--- a/holidays/registry.py
+++ b/holidays/registry.py
@@ -135,6 +135,7 @@
     "sweden": ("Sweden", "SE", "SWE"),
     "switzerland": ("Switzerland", "CH", "CHE"),
     "taiwan": ("Taiwan", "TW", "TWN"),
+    "tanzania": ("Tanzania", "TZ", "TZA"),
     "thailand": ("Thailand", "TH", "THA"),
     "tunisia": ("Tunisia", "TN", "TUN"),
     "turkey": ("Turkey", "TR", "TUR"),


Test patch:
diff --git a/tests/countries/test_tanzania.py b/tests/countries/test_tanzania.py
new file mode 100644
--- /dev/null
+++ b/tests/countries/test_tanzania.py
@@ -0,0 +1,200 @@
+#  python-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: dr-prodigy <dr.prodigy.github@gmail.com> (c) 2017-2023
+#           ryanss <ryanssdev@icloud.com> (c) 2014-2017
+#  Website: https://github.com/dr-prodigy/python-holidays
+#  License: MIT (see LICENSE file)
+
+from holidays.constants import BANK, PUBLIC
+from holidays.countries.tanzania import Tanzania, TZ, TZA
+from tests.common import TestCase
+
+
+class TestTanzania(TestCase):
+    @classmethod
+    def setUpClass(cls):
+        super().setUpClass(Tanzania, years=range(1994, 2077))
+
+    def test_country_aliases(self):
+        self.assertCountryAliases(Tanzania, TZ, TZA)
+
+    def test_no_holidays(self):
+        self.assertNoHolidays(Tanzania(years=1993))
+        self.assertNoHolidays(Tanzania(years=1993, categories=(BANK,)))
+
+    def test_special_holidays(self):
+        self.assertHoliday(
+            "2002-08-25",
+            "2015-11-05",
+            "2020-10-28",
+            "2021-03-22",
+            "2021-03-25",
+            "2022-08-23",
+        )
+
+    def test_2018_all(self):
+        self.assertHolidays(
+            Tanzania(categories=(BANK, PUBLIC), years=2018),
+            ("2018-01-01", "Mwaka Mpya"),
+            ("2018-01-12", "Mapinduzi ya Zanzibar"),
+            ("2018-03-30", "Ijumaa Kuu"),
+            ("2018-04-01", "Sikukuu ya Pasaka"),
+            ("2018-04-02", "Jumatatu ya Pasaka"),
+            (
+                "2018-04-07",
+                (
+                    "Siku ya kumbukumbu ya Rais wa Kwanza wa Serikali ya Mapinduzi Zanzibar "
+                    "Sheikh Abeid Amani Karume"
+                ),
+            ),
+            ("2018-04-26", "Muungano wa Tanganyika na Zanzibar"),
+            ("2018-05-01", "Sikukuu ya Wafanyakazi"),
+            ("2018-06-15", "Eid El-Fitry"),
+            ("2018-07-07", "Sabasaba"),
+            ("2018-08-08", "Siku ya Wakulima"),
+            ("2018-08-22", "Eid El-Hajj"),
+            ("2018-10-14", "Kumbukumbu ya Mwalimu Nyerere"),
+            ("2018-11-21", "Maulidi"),
+            ("2018-12-09", "Uhuru na Jamhuri"),
+            ("2018-12-25", "Kuzaliwa Kristo"),
+            ("2018-12-26", "Siku ya Kupeana Zawadi"),
+        )
+
+    def test_2020_all(self):
+        self.assertHolidays(
+            Tanzania(categories=(BANK, PUBLIC), years=2020),
+            ("2020-01-01", "Mwaka Mpya"),
+            ("2020-01-12", "Mapinduzi ya Zanzibar"),
+            (
+                "2020-04-07",
+                (
+                    "Siku ya kumbukumbu ya Rais wa Kwanza wa Serikali ya Mapinduzi Zanzibar "
+                    "Sheikh Abeid Amani Karume"
+                ),
+            ),
+            ("2020-04-10", "Ijumaa Kuu"),
+            ("2020-04-12", "Sikukuu ya Pasaka"),
+            ("2020-04-13", "Jumatatu ya Pasaka"),
+            ("2020-04-26", "Muungano wa Tanganyika na Zanzibar"),
+            ("2020-05-01", "Sikukuu ya Wafanyakazi"),
+            ("2020-05-24", "Eid El-Fitry"),
+            ("2020-07-07", "Sabasaba"),
+            ("2020-07-31", "Eid El-Hajj"),
+            ("2020-08-08", "Siku ya Wakulima"),
+            ("2020-10-14", "Kumbukumbu ya Mwalimu Nyerere"),
+            ("2020-10-28", "Sikukuu ya Uchaguzi Mkuu wa Tanzania"),
+            ("2020-10-29", "Maulidi"),
+            ("2020-12-09", "Uhuru na Jamhuri"),
+            ("2020-12-25", "Kuzaliwa Kristo"),
+            ("2020-12-26", "Siku ya Kupeana Zawadi"),
+        )
+
+    def test_2021_all(self):
+        self.assertHolidays(
+            Tanzania(categories=(BANK, PUBLIC), years=2021),
+            ("2021-01-01", "Mwaka Mpya"),
+            ("2021-01-12", "Mapinduzi ya Zanzibar"),
+            ("2021-03-22", "Mazishi cha John Pombe Magufuli"),
+            ("2021-03-25", "Mazishi cha John Pombe Magufuli"),
+            ("2021-04-02", "Ijumaa Kuu"),
+            ("2021-04-04", "Sikukuu ya Pasaka"),
+            ("2021-04-05", "Jumatatu ya Pasaka"),
+            (
+                "2021-04-07",
+                (
+                    "Siku ya kumbukumbu ya Rais wa Kwanza wa Serikali ya Mapinduzi Zanzibar "
+                    "Sheikh Abeid Amani Karume"
+                ),
+            ),
+            ("2021-04-26", "Muungano wa Tanganyika na Zanzibar"),
+            ("2021-05-01", "Sikukuu ya Wafanyakazi"),
+            ("2021-05-14", "Eid El-Fitry"),
+            ("2021-07-07", "Sabasaba"),
+            ("2021-07-21", "Eid El-Hajj"),
+            ("2021-08-08", "Siku ya Wakulima"),
+            ("2021-10-14", "Kumbukumbu ya Mwalimu Nyerere"),
+            ("2021-10-19", "Maulidi"),
+            ("2021-12-09", "Uhuru na Jamhuri"),
+            ("2021-12-25", "Kuzaliwa Kristo"),
+            ("2021-12-26", "Siku ya Kupeana Zawadi"),
+        )
+
+    def test_2022_all(self):
+        self.assertHolidays(
+            Tanzania(categories=(BANK, PUBLIC), years=2022),
+            ("2022-01-01", "Mwaka Mpya"),
+            ("2022-01-12", "Mapinduzi ya Zanzibar"),
+            (
+                "2022-04-07",
+                (
+                    "Siku ya kumbukumbu ya Rais wa Kwanza wa Serikali ya Mapinduzi Zanzibar "
+                    "Sheikh Abeid Amani Karume"
+                ),
+            ),
+            ("2022-04-15", "Ijumaa Kuu"),
+            ("2022-04-17", "Sikukuu ya Pasaka"),
+            ("2022-04-18", "Jumatatu ya Pasaka"),
+            ("2022-04-26", "Muungano wa Tanganyika na Zanzibar"),
+            ("2022-05-01", "Sikukuu ya Wafanyakazi"),
+            ("2022-05-03", "Eid El-Fitry"),
+            ("2022-07-07", "Sabasaba"),
+            ("2022-07-10", "Eid El-Hajj"),
+            ("2022-08-08", "Siku ya Wakulima"),
+            ("2022-08-23", "Siku ya Sensa ya Kitaifa ya Watu na Makazi"),
+            ("2022-10-09", "Maulidi"),
+            ("2022-10-14", "Kumbukumbu ya Mwalimu Nyerere"),
+            ("2022-12-09", "Uhuru na Jamhuri"),
+            ("2022-12-25", "Kuzaliwa Kristo"),
+            ("2022-12-26", "Siku ya Kupeana Zawadi"),
+        )
+
+    def test_l10n_default(self):
+        self.assertLocalizedHolidays(
+            ("2023-01-01", "Mwaka Mpya"),
+            ("2023-01-12", "Mapinduzi ya Zanzibar"),
+            (
+                "2023-04-07",
+                (
+                    "Ijumaa Kuu; Siku ya kumbukumbu ya Rais wa Kwanza wa Serikali "
+                    "ya Mapinduzi Zanzibar Sheikh Abeid Amani Karume"
+                ),
+            ),
+            ("2023-04-09", "Sikukuu ya Pasaka"),
+            ("2023-04-10", "Jumatatu ya Pasaka"),
+            ("2023-04-22", "Eid El-Fitry"),
+            ("2023-04-26", "Muungano wa Tanganyika na Zanzibar"),
+            ("2023-05-01", "Sikukuu ya Wafanyakazi"),
+            ("2023-06-29", "Eid El-Hajj"),
+            ("2023-07-07", "Sabasaba"),
+            ("2023-08-08", "Siku ya Wakulima"),
+            ("2023-09-28", "Maulidi"),
+            ("2023-10-14", "Kumbukumbu ya Mwalimu Nyerere"),
+            ("2023-12-09", "Uhuru na Jamhuri"),
+            ("2023-12-25", "Kuzaliwa Kristo"),
+            ("2023-12-26", "Siku ya Kupeana Zawadi"),
+        )
+
+    def test_l10n_en_us(self):
+        self.assertLocalizedHolidays(
+            "en_US",
+            ("2023-01-01", "New Year's Day"),
+            ("2023-01-12", "Zanzibar Revolution Day"),
+            ("2023-04-07", "Good Friday; The Sheikh Abeid Amani Karume Day"),
+            ("2023-04-09", "Easter Sunday"),
+            ("2023-04-10", "Easter Monday"),
+            ("2023-04-22", "Eid al-Fitr"),
+            ("2023-04-26", "Union Celebrations"),
+            ("2023-05-01", "Worker's Day"),
+            ("2023-06-29", "Eid al-Adha"),
+            ("2023-07-07", "International Trade Fair"),
+            ("2023-08-08", "Peasants Day"),
+            ("2023-09-28", "Maulid Day"),
+            ("2023-10-14", "The Mwalimu Nyerere Day"),
+            ("2023-12-09", "Independence and Republic Day"),
+            ("2023-12-25", "Christmas Day"),
+            ("2023-12-26", "Boxing Day"),
+        )