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

Update US holidays: add federal holidays as GOVERNMENT category #2297

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 4 commits
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
16 changes: 8 additions & 8 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ All other default values are highlighted with bold:
- AS
- Can also be loaded as country US, subdivision AS
-
- UNOFFICIAL
- GOVERNMENT, UNOFFICIAL
* - Andorra
- AD
- Parishes: 02, 03, 04, 05, 06, 07, 08
Expand Down Expand Up @@ -485,7 +485,7 @@ All other default values are highlighted with bold:
- GU
- Can also be loaded as country US, subdivision GU
-
- UNOFFICIAL
- GOVERNMENT, UNOFFICIAL
* - Guatemala
- GT
-
Expand Down Expand Up @@ -720,7 +720,7 @@ All other default values are highlighted with bold:
- MP
- Can also be loaded as country US, subdivision MP
-
- UNOFFICIAL
- GOVERNMENT, UNOFFICIAL
* - North Macedonia
- MK
-
Expand Down Expand Up @@ -780,7 +780,7 @@ All other default values are highlighted with bold:
- PR
- Can also be loaded as country US, subdivision PR
-
- UNOFFICIAL
- GOVERNMENT, UNOFFICIAL
* - Romania
- RO
-
Expand Down Expand Up @@ -930,17 +930,17 @@ All other default values are highlighted with bold:
- UM
- Can also be loaded as country US, subdivision UM
-
- UNOFFICIAL
- GOVERNMENT, UNOFFICIAL
* - United States of America (the)
- US
- States and territories: AK, AL, AR, AS, AZ, CA, CO, CT, DC, DE, FL, GA, GU, HI, IA, ID, IL, IN, KS, KY, LA, MA, MD, ME, MI, MN, MO, MP, MS, MT, NC, ND, NE, NH, NJ, NM, NV, NY, OH, OK, OR, PA, PR, RI, SC, SD, TN, TX, UM, UT, VA, VI, VT, WA, WI, WV, WY
-
- UNOFFICIAL
- GOVERNMENT, UNOFFICIAL
* - United States Virgin Islands (the)
-
- See Virgin Islands (U.S.)
-
- UNOFFICIAL
-
* - Uruguay
- UY
-
Expand Down Expand Up @@ -975,7 +975,7 @@ All other default values are highlighted with bold:
- VI
- Can also be loaded as country US, subdivision VI
-
- UNOFFICIAL
- GOVERNMENT, UNOFFICIAL
* - Zambia
- ZM
-
Expand Down
8 changes: 6 additions & 2 deletions holidays/countries/american_samoa.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# Website: https://github.com/vacanza/holidays
# License: MIT (see LICENSE file)

from holidays.constants import PUBLIC, UNOFFICIAL
from holidays.constants import GOVERNMENT, PUBLIC, UNOFFICIAL
from holidays.countries.united_states import US


Expand All @@ -20,13 +20,17 @@ class HolidaysAS(US):
# https://en.wikipedia.org/wiki/ISO_3166-2:US#Subdivisions_included_in_ISO_3166-1

country = "AS"
supported_categories = (PUBLIC, UNOFFICIAL)
supported_categories = (GOVERNMENT, PUBLIC, UNOFFICIAL)
subdivisions = () # Override US subdivisions.

def _populate_public_holidays(self) -> None:
self.subdiv = "AS"
super()._populate_public_holidays()

def _populate_government_holidays(self) -> None:
self.subdiv = "AS"
super()._populate_government_holidays()

def _populate_unofficial_holidays(self) -> None:
self.subdiv = "AS"
super()._populate_unofficial_holidays()
Expand Down
8 changes: 6 additions & 2 deletions holidays/countries/guam.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# Website: https://github.com/vacanza/holidays
# License: MIT (see LICENSE file)

from holidays.constants import PUBLIC, UNOFFICIAL
from holidays.constants import GOVERNMENT, PUBLIC, UNOFFICIAL
from holidays.countries.united_states import US


Expand All @@ -20,13 +20,17 @@ class HolidaysGU(US):
# https://en.wikipedia.org/wiki/ISO_3166-2:US#Subdivisions_included_in_ISO_3166-1

country = "GU"
supported_categories = (PUBLIC, UNOFFICIAL)
supported_categories = (GOVERNMENT, PUBLIC, UNOFFICIAL)
subdivisions = () # Override US subdivisions.

def _populate_public_holidays(self) -> None:
self.subdiv = "GU"
super()._populate_public_holidays()

def _populate_government_holidays(self) -> None:
self.subdiv = "GU"
super()._populate_government_holidays()

def _populate_unofficial_holidays(self) -> None:
self.subdiv = "GU"
super()._populate_unofficial_holidays()
Expand Down
8 changes: 6 additions & 2 deletions holidays/countries/northern_mariana_islands.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# Website: https://github.com/vacanza/holidays
# License: MIT (see LICENSE file)

from holidays.constants import PUBLIC, UNOFFICIAL
from holidays.constants import GOVERNMENT, PUBLIC, UNOFFICIAL
from holidays.countries.united_states import US


Expand All @@ -20,13 +20,17 @@ class HolidaysMP(US):
# https://en.wikipedia.org/wiki/ISO_3166-2:US#Subdivisions_included_in_ISO_3166-1

country = "MP"
supported_categories = (PUBLIC, UNOFFICIAL)
supported_categories = (GOVERNMENT, PUBLIC, UNOFFICIAL)
subdivisions = () # Override US subdivisions.

def _populate_public_holidays(self) -> None:
self.subdiv = "MP"
super()._populate_public_holidays()

def _populate_government_holidays(self) -> None:
self.subdiv = "MP"
super()._populate_government_holidays()

def _populate_unofficial_holidays(self) -> None:
self.subdiv = "MP"
super()._populate_unofficial_holidays()
Expand Down
8 changes: 6 additions & 2 deletions holidays/countries/puerto_rico.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
# Website: https://github.com/vacanza/holidays
# License: MIT (see LICENSE file)

from holidays.constants import PUBLIC, UNOFFICIAL
from holidays.constants import GOVERNMENT, PUBLIC, UNOFFICIAL
from holidays.countries.united_states import US


Expand All @@ -20,13 +20,17 @@ class HolidaysPR(US):
# https://en.wikipedia.org/wiki/ISO_3166-2:US#Subdivisions_included_in_ISO_3166-1

country = "PR"
supported_categories = (PUBLIC, UNOFFICIAL)
supported_categories = (GOVERNMENT, PUBLIC, UNOFFICIAL)
subdivisions = () # Override US subdivisions.

def _populate_public_holidays(self) -> None:
self.subdiv = "PR"
super()._populate_public_holidays()

def _populate_government_holidays(self) -> None:
self.subdiv = "PR"
super()._populate_government_holidays()

def _populate_unofficial_holidays(self) -> None:
self.subdiv = "PR"
super()._populate_unofficial_holidays()
Expand Down
104 changes: 69 additions & 35 deletions holidays/countries/united_states.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
from typing import Union

from holidays.calendars.gregorian import MON, TUE, WED, THU, FRI, SAT, SUN
from holidays.constants import PUBLIC, UNOFFICIAL
from holidays.constants import GOVERNMENT, PUBLIC, UNOFFICIAL
from holidays.groups import ChristianHolidays, InternationalHolidays
from holidays.observed_holiday_base import (
ObservedHolidayBase,
Expand All @@ -35,6 +35,9 @@ class UnitedStates(ObservedHolidayBase, ChristianHolidays, InternationalHolidays
"""
https://en.wikipedia.org/wiki/Public_holidays_in_the_United_States

Federal holidays:
- https://www.opm.gov/policy-data-oversight/pay-leave/federal-holidays/

For Northern Mariana Islands (subdivision MP):
- https://governor.gov.mp/archived-news/executive-actions-archive/memorandum-2022-legal-holidays/
- https://webcache.googleusercontent.com/search?q=cache:C17_7FBgPtQJ:https://governor.gov.mp/archived-news/executive-actions-archive/memorandum-2022-legal-holidays/&hl=en&gl=sg&strip=1&vwsrc=0
Expand Down Expand Up @@ -86,7 +89,7 @@ class UnitedStates(ObservedHolidayBase, ChristianHolidays, InternationalHolidays
"""

country = "US"
supported_categories = (PUBLIC, UNOFFICIAL)
supported_categories = (GOVERNMENT, PUBLIC, UNOFFICIAL)
observed_label = "%s (observed)"
subdivisions: Union[tuple[()], tuple[str, ...]] = (
"AK", # Alaska.
Expand Down Expand Up @@ -161,20 +164,29 @@ def __init__(self, *args, **kwargs):
kwargs.setdefault("observed_rule", SAT_TO_PREV_FRI + SUN_TO_NEXT_MON)
super().__init__(*args, **kwargs)

def _populate_public_holidays(self):
def _populate_common(self, is_federal: bool = False):
# New Year's Day
if self._year >= 1871:
name = "New Year's Day"
self._add_observed(self._add_new_years_day(name))
self._add_observed(self._next_year_new_years_day, name=name)

if is_federal:
# Birthday of Martin Luther King, Jr.
if self._year >= 1986:
self._add_holiday_3rd_mon_of_jan("Birthday of Martin Luther King, Jr.")

# Washington's Birthday
if self._year >= 1879:
name = "Washington's Birthday"
if self._year >= 1971:
self._add_holiday_3rd_mon_of_feb(name)
else:
self._add_holiday_feb_22(name)

# Memorial Day
if self._year >= 1888:
name = "Memorial Day"
if self._year >= 1971:
self._add_holiday_last_mon_of_may(name)
else:
self._add_holiday_may_30(name)
if self._year >= 1971:
self._add_holiday_last_mon_of_may("Memorial Day")

# Juneteenth Day
if self._year >= 2021:
Expand All @@ -188,6 +200,11 @@ def _populate_public_holidays(self):
if self._year >= 1894:
self._add_holiday_1st_mon_of_sep("Labor Day")

if is_federal:
# Columbus Day
if self._year >= 1971:
self._add_holiday_2nd_mon_of_oct("Columbus Day")

# Veterans Day
if self._year >= 1938:
name = "Veterans Day" if self._year >= 1954 else "Armistice Day"
Expand All @@ -196,14 +213,21 @@ def _populate_public_holidays(self):
else:
self._add_observed(self._add_remembrance_day(name))

# Thanksgiving
# Thanksgiving Day
if self._year >= 1871:
self._add_holiday_4th_thu_of_nov("Thanksgiving")
self._add_holiday_4th_thu_of_nov("Thanksgiving Day")

# Christmas Day
if self._year >= 1871:
self._add_observed(self._add_christmas_day("Christmas Day"))

def _populate_public_holidays(self):
self._populate_common()

# Memorial Day
if 1888 <= self._year <= 1970:
self._add_holiday_may_30("Memorial Day")

def _add_christmas_eve_holiday(self):
# Christmas Eve
# If on Friday, observed on Thursday
Expand Down Expand Up @@ -325,11 +349,12 @@ def _populate_subdiv_al_public_holidays(self):
self._add_holiday_3rd_mon_of_jan("Martin Luther King, Jr & Robert E. Lee's Birthday")

# Washington's Birthday
name = "George Washington & Thomas Jefferson's Birthday"
if self._year >= 1971:
self._add_holiday_3rd_mon_of_feb(name)
else:
self._add_holiday_feb_22(name)
if self._year >= 1879:
name = "George Washington & Thomas Jefferson's Birthday"
if self._year >= 1971:
self._add_holiday_3rd_mon_of_feb(name)
else:
self._add_holiday_feb_22(name)

# Confederate Memorial Day
if self._year >= 1866:
Expand Down Expand Up @@ -357,11 +382,12 @@ def _populate_subdiv_ar_public_holidays(self):
)

# Washington's Birthday
name = "George Washington's Birthday and Daisy Gatson Bates Day"
if self._year >= 1971:
self._add_holiday_3rd_mon_of_feb(name)
else:
self._add_holiday_feb_22(name)
if self._year >= 1879:
name = "George Washington's Birthday and Daisy Gatson Bates Day"
if self._year >= 1971:
self._add_holiday_3rd_mon_of_feb(name)
else:
self._add_holiday_feb_22(name)

def _populate_subdiv_as_public_holidays(self):
# American Samoa Flag Day
Expand Down Expand Up @@ -494,10 +520,11 @@ def _populate_subdiv_ga_public_holidays(self):
)

# Washington's Birthday
self._add_holiday(
"Washington's Birthday",
self._get_observed_date(self._christmas_day, rule=GA_IN_WASHINGTON_BIRTHDAY),
)
if self._year >= 1879:
self._add_holiday(
"Washington's Birthday",
self._get_observed_date(self._christmas_day, rule=GA_IN_WASHINGTON_BIRTHDAY),
)

def _populate_subdiv_gu_public_holidays(self):
# Guam Discovery Day
Expand Down Expand Up @@ -588,10 +615,11 @@ def _populate_subdiv_in_public_holidays(self):
self._add_holiday_1_day_past_4th_thu_of_nov("Lincoln's Birthday")

# Washington's Birthday
self._add_holiday(
"Washington's Birthday",
self._get_observed_date(self._christmas_day, rule=GA_IN_WASHINGTON_BIRTHDAY),
)
if self._year >= 1879:
self._add_holiday(
"Washington's Birthday",
self._get_observed_date(self._christmas_day, rule=GA_IN_WASHINGTON_BIRTHDAY),
)

def _populate_subdiv_ks_public_holidays(self):
# Christmas Eve
Expand Down Expand Up @@ -881,7 +909,8 @@ def _populate_subdiv_pr_public_holidays(self):
self._add_epiphany_day("Epiphany")

# Washington's Birthday
self._add_holiday_3rd_mon_of_feb("Presidents' Day")
if self._year >= 1971:
self._add_holiday_3rd_mon_of_feb("Presidents' Day")

# Emancipation Day
self._add_observed(self._add_holiday_mar_22("Emancipation Day"), rule=SUN_TO_NEXT_MON)
Expand Down Expand Up @@ -1024,11 +1053,12 @@ def _populate_subdiv_vi_public_holidays(self):
self._add_epiphany_day("Three Kings Day")

# Washington's Birthday
name = "Presidents' Day"
if self._year >= 1971:
self._add_holiday_3rd_mon_of_feb(name)
else:
self._add_holiday_feb_22(name)
if self._year >= 1879:
name = "Presidents' Day"
if self._year >= 1971:
self._add_holiday_3rd_mon_of_feb(name)
else:
self._add_holiday_feb_22(name)

# Transfer Day
self._add_holiday_mar_31("Transfer Day")
Expand Down Expand Up @@ -1111,6 +1141,10 @@ def _populate_subdiv_wy_public_holidays(self):
if self._year >= 1971:
self._add_holiday_3rd_mon_of_feb("President's Day")

def _populate_government_holidays(self):
# Federal holidays in the United States.
self._populate_common(is_federal=True)

def _populate_unofficial_holidays(self):
# Very common celebrated cultural days, but no official observance.
# Due to its nature, no in-lieus are observed.
Expand Down
Loading