Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Burkina Faso holidays #1278

Merged
merged 3 commits into from
Jun 7, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ Available Countries
.. _ISO 3166-2 code: https://en.wikipedia.org/wiki/ISO_3166-2
.. _ISO 639-1 code: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes

We currently support 126 country codes. The standard way to refer to a country
We currently support 127 country codes. The standard way to refer to a country
is by using its `ISO 3166-1 alpha-2 code`_, the same used for domain names, and
for a subdivision its `ISO 3166-2 code`_. Some of the countries support more
than one language for holiday names output.
Expand Down Expand Up @@ -215,6 +215,10 @@ The list of supported countries, their subdivisions and supported languages
- BG
-
- **bg**, en_US
* - Burkina Faso
- BF
-
-
* - Burundi
- BI
-
Expand Down
1 change: 1 addition & 0 deletions holidays/countries/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
from .botswana import Botswana, BW, BWA
from .brazil import Brazil, BR, BRA
from .bulgaria import Bulgaria, BG, BLG
from .burkina_faso import BurkinaFaso, BF, BFA
from .burundi import Burundi, BI, BDI
from .cameroon import Cameroon, CM, CMR
from .canada import Canada, CA, CAN
Expand Down
144 changes: 144 additions & 0 deletions holidays/countries/burkina_faso.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# 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 datetime import date
from datetime import timedelta as td

from holidays.calendars import _CustomIslamicCalendar
from holidays.constants import JAN, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC
from holidays.holiday_base import HolidayBase
from holidays.holiday_groups import ChristianHolidays, InternationalHolidays
from holidays.holiday_groups import IslamicHolidays


class BurkinaFaso(
HolidayBase, ChristianHolidays, InternationalHolidays, IslamicHolidays
):
"""
References:
- https://en.wikipedia.org/wiki/Public_holidays_in_Burkina_Faso
"""

country = "BF"

def __init__(self, *args, **kwargs) -> None:
ChristianHolidays.__init__(self)
InternationalHolidays.__init__(self)
IslamicHolidays.__init__(self, calendar=BurkinaFasoIslamicCalendar())
super().__init__(*args, **kwargs)

def _add_observed(self, dt: date) -> None:
if self.observed and self._is_sunday(dt):
self._add_holiday("%s (Observed)" % self[dt], dt + td(days=+1))

def _populate(self, year):
# On 5 August 1960, Burkina Faso (Republic of Upper Volta at that time)
# gained independence from France.
if year <= 1960:
return None

super()._populate(year)

# New Year's Day.
self._add_observed(self._add_new_years_day("New Year's Day"))

if year >= 1967:
# Revolution Day.
self._add_observed(self._add_holiday("Revolution Day", JAN, 3))

# International Women's Day.
self._add_observed(self._add_womens_day("International Women's Day"))

# Easter Monday.
self._add_easter_monday("Easter Monday")

# Labour Day.
self._add_observed(self._add_labor_day("Labour Day"))

# Ascension Day.
self._add_ascension_thursday("Ascension Day")

# Independence Day.
self._add_observed(self._add_holiday("Independence Day", AUG, 5))

# Assumption Day.
self._add_observed(self._add_assumption_of_mary_day("Assumption Day"))

if year >= 2016:
# Martyrs' Day.
self._add_observed(self._add_holiday("Martyrs' Day", OCT, 31))

# All Saints' Day.
self._add_observed(self._add_all_saints_day("All Saints' Day"))

self._add_observed(
# Proclamation of Independence Day.
self._add_holiday("Proclamation of Independence Day", DEC, 11)
)

# Christmas Day.
self._add_observed(self._add_christmas_day("Christmas Day"))

# Eid al-Fitr.
self._add_eid_al_fitr_day("Eid al-Fitr")

# Eid al-Adha.
self._add_eid_al_adha_day("Eid al-Adha")

# Mawlid.
self._add_mawlid_day("Mawlid")


class BF(BurkinaFaso):
pass


class BFA(BurkinaFaso):
pass


class BurkinaFasoIslamicCalendar(_CustomIslamicCalendar):
EID_AL_ADHA_DATES = {
2014: ((OCT, 5),),
2015: ((SEP, 24),),
2016: ((SEP, 13),),
2017: ((SEP, 2),),
2018: ((AUG, 21),),
2019: ((AUG, 11),),
2020: ((JUL, 31),),
2021: ((JUL, 20),),
2022: ((JUL, 9),),
}

EID_AL_FITR_DATES = {
2014: ((JUL, 29),),
2015: ((JUL, 18),),
2016: ((JUL, 7),),
2017: ((JUN, 26),),
2018: ((JUN, 15),),
2019: ((JUN, 4),),
2020: ((MAY, 24),),
2021: ((MAY, 13),),
2022: ((MAY, 2),),
2023: ((APR, 21),),
}

MAWLID_DATES = {
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),),
}
1 change: 1 addition & 0 deletions holidays/registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"botswana": ("Botswana", "BW", "BWA"),
"brazil": ("Brazil", "BR", "BRA"),
"bulgaria": ("Bulgaria", "BG", "BLG"),
"burkina_faso": ("BurkinaFaso", "BF", "BFA"),
"burundi": ("Burundi", "BI", "BDI"),
"cameroon": ("Cameroon", "CM", "CMR"),
"canada": ("Canada", "CA", "CAN"),
Expand Down
101 changes: 101 additions & 0 deletions tests/countries/test_burkina_faso.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# 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.countries.burkina_faso import BurkinaFaso, BF, BFA
from tests.common import TestCase


class TestBurkinaFaso(TestCase):
@classmethod
def setUpClass(cls):
super().setUpClass(BurkinaFaso)

def test_country_aliases(self):
self.assertCountryAliases(BurkinaFaso, BF, BFA)

def test_no_holidays(self):
self.assertNoHolidays(BurkinaFaso(years=1960))

def test_revolution_day(self):
name = "Revolution Day"
self.assertHolidaysName(
name, (f"{year}-01-03" for year in range(1967, 2050))
)
self.assertNoHolidayName(name, BurkinaFaso(years=range(1961, 1967)))
self.assertNoHoliday(f"{year}-01-03" for year in range(1961, 1967))

def test_martyrs_day(self):
name = "Martyrs' Day"
self.assertHolidaysName(
name, (f"{year}-10-31" for year in range(2016, 2050))
)
self.assertNoHolidayName(name, BurkinaFaso(years=range(1961, 2016)))
self.assertNoHoliday(
f"{year}-10-31"
for year in set(range(1961, 2016)).difference({1979})
)

def test_observed(self):
dt = (
# New Year's Day
"2012-01-02",
"2017-01-02",
"2023-01-02",
# Revolution Day
"2010-01-04",
"2016-01-04",
"2021-01-04",
# International Women's Day
"2015-03-09",
"2020-03-09",
# Labour Day
"2011-05-02",
"2016-05-02",
# Independence Day
"2012-08-06",
"2018-08-06",
# Assumption Day
"2010-08-16",
"2021-08-16",
# All Saints' Day
"2015-11-02",
"2020-11-02",
# Proclamation of Independence Day
"2011-12-12",
"2022-12-12",
# Christmas Day
"2011-12-26",
"2016-12-26",
"2022-12-26",
)
self.assertHoliday(dt)
self.assertNoNonObservedHoliday(dt)

def test_2022(self):
self.assertHolidays(
("2022-01-01", "New Year's Day"),
("2022-01-03", "Revolution Day"),
("2022-03-08", "International Women's Day"),
("2022-04-18", "Easter Monday"),
("2022-05-01", "Labour Day"),
("2022-05-02", "Eid al-Fitr; Labour Day (Observed)"),
("2022-05-26", "Ascension Day"),
("2022-07-09", "Eid al-Adha"),
("2022-08-05", "Independence Day"),
("2022-08-15", "Assumption Day"),
("2022-10-09", "Mawlid"),
("2022-10-31", "Martyrs' Day"),
("2022-11-01", "All Saints' Day"),
("2022-12-11", "Proclamation of Independence Day"),
("2022-12-12", "Proclamation of Independence Day (Observed)"),
("2022-12-25", "Christmas Day"),
("2022-12-26", "Christmas Day (Observed)"),
)