holidays 0.69__py3-none-any.whl → 0.70__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- holidays/__init__.py +1 -1
- holidays/calendars/__init__.py +1 -1
- holidays/calendars/balinese_saka.py +3 -3
- holidays/calendars/buddhist.py +1 -1
- holidays/calendars/chinese.py +1 -1
- holidays/calendars/custom.py +1 -1
- holidays/calendars/gregorian.py +1 -1
- holidays/calendars/hebrew.py +1 -1
- holidays/calendars/hindu.py +1 -1
- holidays/calendars/islamic.py +161 -1
- holidays/calendars/julian.py +1 -1
- holidays/calendars/julian_revised.py +1 -1
- holidays/calendars/persian.py +1 -1
- holidays/calendars/sinhala.py +1 -1
- holidays/calendars/thai.py +309 -257
- holidays/constants.py +2 -1
- holidays/countries/__init__.py +6 -1
- holidays/countries/afghanistan.py +11 -7
- holidays/countries/albania.py +10 -7
- holidays/countries/algeria.py +10 -10
- holidays/countries/american_samoa.py +6 -4
- holidays/countries/andorra.py +5 -4
- holidays/countries/angola.py +15 -14
- holidays/countries/antigua_and_barbuda.py +145 -0
- holidays/countries/argentina.py +787 -169
- holidays/countries/armenia.py +5 -6
- holidays/countries/aruba.py +11 -9
- holidays/countries/australia.py +21 -20
- holidays/countries/austria.py +3 -1
- holidays/countries/azerbaijan.py +24 -19
- holidays/countries/bahamas.py +13 -11
- holidays/countries/bahrain.py +8 -7
- holidays/countries/bangladesh.py +5 -4
- holidays/countries/barbados.py +11 -9
- holidays/countries/belarus.py +15 -15
- holidays/countries/belgium.py +8 -6
- holidays/countries/belize.py +7 -6
- holidays/countries/bolivia.py +12 -11
- holidays/countries/bosnia_and_herzegovina.py +15 -11
- holidays/countries/botswana.py +8 -6
- holidays/countries/brazil.py +8 -7
- holidays/countries/brunei.py +50 -62
- holidays/countries/bulgaria.py +9 -10
- holidays/countries/burkina_faso.py +8 -5
- holidays/countries/burundi.py +13 -12
- holidays/countries/cambodia.py +15 -24
- holidays/countries/cameroon.py +10 -7
- holidays/countries/canada.py +13 -12
- holidays/countries/chad.py +9 -6
- holidays/countries/chile.py +29 -28
- holidays/countries/china.py +39 -38
- holidays/countries/colombia.py +15 -20
- holidays/countries/congo.py +6 -7
- holidays/countries/costa_rica.py +11 -10
- holidays/countries/croatia.py +8 -5
- holidays/countries/cuba.py +30 -27
- holidays/countries/curacao.py +6 -4
- holidays/countries/cyprus.py +4 -5
- holidays/countries/czechia.py +7 -6
- holidays/countries/denmark.py +5 -6
- holidays/countries/djibouti.py +7 -3
- holidays/countries/dominica.py +18 -16
- holidays/countries/dominican_republic.py +6 -4
- holidays/countries/ecuador.py +5 -4
- holidays/countries/egypt.py +6 -11
- holidays/countries/el_salvador.py +6 -5
- holidays/countries/estonia.py +3 -1
- holidays/countries/eswatini.py +6 -4
- holidays/countries/ethiopia.py +20 -11
- holidays/countries/fiji.py +183 -0
- holidays/countries/finland.py +11 -10
- holidays/countries/france.py +6 -9
- holidays/countries/gabon.py +11 -8
- holidays/countries/georgia.py +7 -7
- holidays/countries/germany.py +11 -11
- holidays/countries/ghana.py +10 -6
- holidays/countries/greece.py +4 -5
- holidays/countries/greenland.py +5 -6
- holidays/countries/guam.py +6 -4
- holidays/countries/guatemala.py +7 -9
- holidays/countries/guernsey.py +37 -34
- holidays/countries/guinea.py +182 -0
- holidays/countries/haiti.py +6 -5
- holidays/countries/honduras.py +8 -4
- holidays/countries/hongkong.py +11 -8
- holidays/countries/hungary.py +26 -23
- holidays/countries/iceland.py +5 -4
- holidays/countries/india.py +14 -10
- holidays/countries/indonesia.py +57 -53
- holidays/countries/iran.py +12 -9
- holidays/countries/ireland.py +5 -4
- holidays/countries/isle_of_man.py +2 -2
- holidays/countries/israel.py +4 -5
- holidays/countries/italy.py +5 -4
- holidays/countries/ivory_coast.py +156 -0
- holidays/countries/jamaica.py +6 -4
- holidays/countries/japan.py +5 -5
- holidays/countries/jersey.py +29 -26
- holidays/countries/jordan.py +9 -6
- holidays/countries/kazakhstan.py +66 -51
- holidays/countries/kenya.py +22 -18
- holidays/countries/kuwait.py +10 -7
- holidays/countries/kyrgyzstan.py +7 -6
- holidays/countries/laos.py +21 -29
- holidays/countries/latvia.py +7 -5
- holidays/countries/lesotho.py +6 -5
- holidays/countries/liechtenstein.py +5 -5
- holidays/countries/lithuania.py +4 -5
- holidays/countries/luxembourg.py +5 -3
- holidays/countries/macau.py +32 -26
- holidays/countries/madagascar.py +5 -4
- holidays/countries/malawi.py +6 -4
- holidays/countries/malaysia.py +24 -18
- holidays/countries/maldives.py +10 -7
- holidays/countries/malta.py +10 -19
- holidays/countries/marshall_islands.py +6 -4
- holidays/countries/mauritania.py +9 -6
- holidays/countries/mexico.py +8 -7
- holidays/countries/moldova.py +6 -4
- holidays/countries/monaco.py +6 -4
- holidays/countries/montenegro.py +10 -7
- holidays/countries/morocco.py +9 -8
- holidays/countries/mozambique.py +3 -1
- holidays/countries/namibia.py +7 -5
- holidays/countries/netherlands.py +6 -6
- holidays/countries/new_zealand.py +3 -1
- holidays/countries/nicaragua.py +6 -5
- holidays/countries/nigeria.py +9 -5
- holidays/countries/north_macedonia.py +9 -5
- holidays/countries/northern_mariana_islands.py +6 -4
- holidays/countries/norway.py +15 -15
- holidays/countries/pakistan.py +41 -17
- holidays/countries/palau.py +13 -11
- holidays/countries/panama.py +9 -8
- holidays/countries/papua_new_guinea.py +25 -21
- holidays/countries/paraguay.py +10 -9
- holidays/countries/peru.py +4 -5
- holidays/countries/philippines.py +25 -21
- holidays/countries/poland.py +6 -5
- holidays/countries/portugal.py +13 -15
- holidays/countries/puerto_rico.py +6 -4
- holidays/countries/qatar.py +172 -0
- holidays/countries/romania.py +6 -4
- holidays/countries/russia.py +6 -4
- holidays/countries/saint_kitts_and_nevis.py +24 -22
- holidays/countries/saint_lucia.py +8 -7
- holidays/countries/samoa.py +7 -6
- holidays/countries/san_marino.py +4 -3
- holidays/countries/saudi_arabia.py +11 -15
- holidays/countries/serbia.py +3 -4
- holidays/countries/seychelles.py +22 -26
- holidays/countries/singapore.py +29 -39
- holidays/countries/slovakia.py +6 -5
- holidays/countries/slovenia.py +7 -6
- holidays/countries/south_africa.py +8 -6
- holidays/countries/south_korea.py +25 -32
- holidays/countries/spain.py +25 -24
- holidays/countries/sri_lanka.py +46 -42
- holidays/countries/sweden.py +20 -19
- holidays/countries/switzerland.py +6 -5
- holidays/countries/taiwan.py +50 -48
- holidays/countries/tanzania.py +28 -27
- holidays/countries/thailand.py +134 -142
- holidays/countries/timor_leste.py +20 -18
- holidays/countries/tonga.py +46 -42
- holidays/countries/tunisia.py +5 -3
- holidays/countries/turkey.py +11 -9
- holidays/countries/tuvalu.py +12 -11
- holidays/countries/ukraine.py +54 -54
- holidays/countries/united_arab_emirates.py +37 -30
- holidays/countries/united_kingdom.py +7 -6
- holidays/countries/united_states.py +50 -55
- holidays/countries/united_states_minor_outlying_islands.py +6 -4
- holidays/countries/united_states_virgin_islands.py +6 -4
- holidays/countries/uruguay.py +10 -9
- holidays/countries/uzbekistan.py +10 -7
- holidays/countries/vanuatu.py +7 -5
- holidays/countries/vatican_city.py +16 -15
- holidays/countries/venezuela.py +11 -14
- holidays/countries/vietnam.py +15 -11
- holidays/countries/zambia.py +8 -6
- holidays/countries/zimbabwe.py +6 -4
- holidays/deprecations/v1_incompatibility.py +1 -1
- holidays/financial/__init__.py +1 -1
- holidays/financial/brasil_bolsa_balcao.py +14 -13
- holidays/financial/european_central_bank.py +7 -6
- holidays/financial/ice_futures_europe.py +7 -6
- holidays/financial/ny_stock_exchange.py +13 -10
- holidays/groups/__init__.py +1 -1
- holidays/groups/balinese_saka.py +1 -1
- holidays/groups/buddhist.py +1 -1
- holidays/groups/chinese.py +1 -1
- holidays/groups/christian.py +1 -1
- holidays/groups/custom.py +1 -1
- holidays/groups/eastern.py +1 -1
- holidays/groups/hebrew.py +1 -1
- holidays/groups/hindu.py +1 -1
- holidays/groups/international.py +1 -1
- holidays/groups/islamic.py +12 -1
- holidays/groups/persian.py +1 -1
- holidays/groups/sinhala.py +1 -1
- holidays/groups/thai.py +1 -7
- holidays/helpers.py +1 -1
- holidays/holiday_base.py +366 -244
- holidays/ical.py +228 -0
- holidays/locale/ar_QA/LC_MESSAGES/QA.mo +0 -0
- holidays/locale/en_CI/LC_MESSAGES/CI.mo +0 -0
- holidays/locale/en_PK/LC_MESSAGES/PK.mo +0 -0
- holidays/locale/en_TL/LC_MESSAGES/TL.mo +0 -0
- holidays/locale/en_US/LC_MESSAGES/AR.mo +0 -0
- holidays/locale/en_US/LC_MESSAGES/CI.mo +0 -0
- holidays/locale/en_US/LC_MESSAGES/GN.mo +0 -0
- holidays/locale/en_US/LC_MESSAGES/PK.mo +0 -0
- holidays/locale/en_US/LC_MESSAGES/QA.mo +0 -0
- holidays/locale/en_US/LC_MESSAGES/TL.mo +0 -0
- holidays/locale/es/LC_MESSAGES/AR.mo +0 -0
- holidays/locale/fr/LC_MESSAGES/CI.mo +0 -0
- holidays/locale/fr/LC_MESSAGES/GN.mo +0 -0
- holidays/locale/hi/LC_MESSAGES/IN.mo +0 -0
- holidays/locale/pt_TL/LC_MESSAGES/TL.mo +0 -0
- holidays/locale/tet/LC_MESSAGES/TL.mo +0 -0
- holidays/locale/th/LC_MESSAGES/TL.mo +0 -0
- holidays/locale/uk/LC_MESSAGES/AR.mo +0 -0
- holidays/locale/ur_PK/LC_MESSAGES/PK.mo +0 -0
- holidays/mixins.py +2 -2
- holidays/observed_holiday_base.py +5 -2
- holidays/registry.py +6 -1
- holidays/utils.py +151 -151
- holidays/version.py +2 -2
- holidays-0.70.dist-info/METADATA +1404 -0
- {holidays-0.69.dist-info → holidays-0.70.dist-info}/RECORD +235 -217
- {holidays-0.69.dist-info → holidays-0.70.dist-info}/WHEEL +1 -1
- holidays-0.69.dist-info/AUTHORS → holidays-0.70.dist-info/licenses/AUTHORS.md +6 -2
- {holidays-0.69.dist-info → holidays-0.70.dist-info/licenses}/LICENSE +1 -1
- holidays-0.69.dist-info/METADATA +0 -1085
- {holidays-0.69.dist-info → holidays-0.70.dist-info}/top_level.txt +0 -0
holidays/holiday_base.py
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# specific sets of holidays on the fly. It aims to make determining whether a
|
|
5
5
|
# specific date is a holiday as fast and flexible as possible.
|
|
6
6
|
#
|
|
7
|
-
# Authors: Vacanza Team and individual contributors (see AUTHORS file)
|
|
7
|
+
# Authors: Vacanza Team and individual contributors (see AUTHORS.md file)
|
|
8
8
|
# dr-prodigy <dr.prodigy.github@gmail.com> (c) 2017-2023
|
|
9
9
|
# ryanss <ryanssdev@icloud.com> (c) 2014-2017
|
|
10
10
|
# Website: https://github.com/vacanza/holidays
|
|
@@ -56,19 +56,19 @@ YearArg = Union[int, Iterable[int]]
|
|
|
56
56
|
|
|
57
57
|
class HolidayBase(dict[date, str]):
|
|
58
58
|
"""
|
|
59
|
-
A dict
|
|
60
|
-
province or state if so initiated); inherits the dict class (so behaves
|
|
61
|
-
similarly to a dict). Dates without a key in the Holiday object are not
|
|
59
|
+
A `dict`-like object containing the holidays for a specific country (and
|
|
60
|
+
province or state if so initiated); inherits the `dict` class (so behaves
|
|
61
|
+
similarly to a `dict`). Dates without a key in the Holiday object are not
|
|
62
62
|
holidays.
|
|
63
63
|
|
|
64
64
|
The key of the object is the date of the holiday and the value is the name
|
|
65
65
|
of the holiday itself. When passing the date as a key, the date can be
|
|
66
66
|
expressed as one of the following formats:
|
|
67
67
|
|
|
68
|
-
* datetime.datetime type;
|
|
69
|
-
* datetime.date types;
|
|
70
|
-
* a float representing a Unix timestamp;
|
|
71
|
-
* or a string of any format (recognized by
|
|
68
|
+
* `datetime.datetime` type;
|
|
69
|
+
* `datetime.date` types;
|
|
70
|
+
* a `float` representing a Unix timestamp;
|
|
71
|
+
* or a string of any format (recognized by `dateutil.parser.parse()`).
|
|
72
72
|
|
|
73
73
|
The key is always returned as a `datetime.date` object.
|
|
74
74
|
|
|
@@ -78,11 +78,12 @@ class HolidayBase(dict[date, str]):
|
|
|
78
78
|
holidays. To pre-populate holidays, instantiate the class with the years
|
|
79
79
|
argument:
|
|
80
80
|
|
|
81
|
-
|
|
81
|
+
us_holidays = holidays.US(years=2020)
|
|
82
82
|
|
|
83
|
-
It is generally instantiated using the
|
|
83
|
+
It is generally instantiated using the
|
|
84
|
+
[country_holidays()][holidays.utils.country_holidays] function.
|
|
84
85
|
|
|
85
|
-
The key of the
|
|
86
|
+
The key of the `dict`-like `HolidayBase` object is the
|
|
86
87
|
`date` of the holiday, and the value is the name of the holiday itself.
|
|
87
88
|
Dates where a key is not present are not public holidays (or, if
|
|
88
89
|
**observed** is False, days when a public holiday is observed).
|
|
@@ -90,12 +91,12 @@ class HolidayBase(dict[date, str]):
|
|
|
90
91
|
When passing the `date` as a key, the `date` can be expressed in one of the
|
|
91
92
|
following types:
|
|
92
93
|
|
|
93
|
-
*
|
|
94
|
-
*
|
|
95
|
-
* a
|
|
96
|
-
* or a
|
|
94
|
+
* `datetime.date`,
|
|
95
|
+
* `datetime.datetime`,
|
|
96
|
+
* a `str` of any format recognized by `dateutil.parser.parse()`,
|
|
97
|
+
* or a `float` or `int` representing a POSIX timestamp.
|
|
97
98
|
|
|
98
|
-
The key is always returned as a
|
|
99
|
+
The key is always returned as a `datetime.date` object.
|
|
99
100
|
|
|
100
101
|
To maximize speed, the list of public holidays is built on the fly as
|
|
101
102
|
needed, one calendar year at a time. When the object is instantiated
|
|
@@ -108,70 +109,70 @@ class HolidayBase(dict[date, str]):
|
|
|
108
109
|
|
|
109
110
|
Example usage:
|
|
110
111
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
112
|
+
>>> from holidays import country_holidays
|
|
113
|
+
>>> us_holidays = country_holidays('US')
|
|
114
|
+
# For a specific subdivisions (e.g. state or province):
|
|
115
|
+
>>> california_holidays = country_holidays('US', subdiv='CA')
|
|
115
116
|
|
|
116
117
|
The below will cause 2015 holidays to be calculated on the fly:
|
|
117
118
|
|
|
118
|
-
|
|
119
|
-
|
|
119
|
+
>>> from datetime import date
|
|
120
|
+
>>> assert date(2015, 1, 1) in us_holidays
|
|
120
121
|
|
|
121
122
|
This will be faster because 2015 holidays are already calculated:
|
|
122
123
|
|
|
123
|
-
|
|
124
|
+
>>> assert date(2015, 1, 2) not in us_holidays
|
|
124
125
|
|
|
125
|
-
The
|
|
126
|
+
The `HolidayBase` class also recognizes strings of many formats
|
|
126
127
|
and numbers representing a POSIX timestamp:
|
|
127
128
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
>>> assert '2014-01-01' in us_holidays
|
|
130
|
+
>>> assert '1/1/2014' in us_holidays
|
|
131
|
+
>>> assert 1388597445 in us_holidays
|
|
131
132
|
|
|
132
133
|
Show the holiday's name:
|
|
133
134
|
|
|
134
|
-
|
|
135
|
-
|
|
135
|
+
>>> us_holidays.get('2014-01-01')
|
|
136
|
+
"New Year's Day"
|
|
136
137
|
|
|
137
138
|
Check a range:
|
|
138
139
|
|
|
139
|
-
|
|
140
|
-
|
|
140
|
+
>>> us_holidays['2014-01-01': '2014-01-03']
|
|
141
|
+
[datetime.date(2014, 1, 1)]
|
|
141
142
|
|
|
142
143
|
List all 2020 holidays:
|
|
143
144
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
145
|
+
>>> us_holidays = country_holidays('US', years=2020)
|
|
146
|
+
>>> for day in sorted(us_holidays.items()):
|
|
147
|
+
... print(day)
|
|
148
|
+
(datetime.date(2020, 1, 1), "New Year's Day")
|
|
149
|
+
(datetime.date(2020, 1, 20), 'Martin Luther King Jr. Day')
|
|
150
|
+
(datetime.date(2020, 2, 17), "Washington's Birthday")
|
|
151
|
+
(datetime.date(2020, 5, 25), 'Memorial Day')
|
|
152
|
+
(datetime.date(2020, 7, 3), 'Independence Day (observed)')
|
|
153
|
+
(datetime.date(2020, 7, 4), 'Independence Day')
|
|
154
|
+
(datetime.date(2020, 9, 7), 'Labor Day')
|
|
155
|
+
(datetime.date(2020, 10, 12), 'Columbus Day')
|
|
156
|
+
(datetime.date(2020, 11, 11), 'Veterans Day')
|
|
157
|
+
(datetime.date(2020, 11, 26), 'Thanksgiving Day')
|
|
158
|
+
(datetime.date(2020, 12, 25), 'Christmas Day')
|
|
158
159
|
|
|
159
160
|
Some holidays are only present in parts of a country:
|
|
160
161
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
162
|
+
>>> us_pr_holidays = country_holidays('US', subdiv='PR')
|
|
163
|
+
>>> assert '2018-01-06' not in us_holidays
|
|
164
|
+
>>> assert '2018-01-06' in us_pr_holidays
|
|
164
165
|
|
|
165
166
|
Append custom holiday dates by passing one of:
|
|
166
167
|
|
|
167
|
-
* a
|
|
168
|
-
|
|
169
|
-
* a list of dates (as a
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
* or a single date item (of one of the types above); ``'Holiday'`` will be
|
|
168
|
+
* a `dict` with date/name key/value pairs (e.g.
|
|
169
|
+
`{'2010-07-10': 'My birthday!'}`),
|
|
170
|
+
* a list of dates (as a `datetime.date`, `datetime.datetime`,
|
|
171
|
+
`str`, `int`, or `float`); `'Holiday'` will be used as a description,
|
|
172
|
+
* or a single date item (of one of the types above); `'Holiday'` will be
|
|
173
173
|
used as a description:
|
|
174
174
|
|
|
175
|
+
```python
|
|
175
176
|
>>> custom_holidays = country_holidays('US', years=2015)
|
|
176
177
|
>>> custom_holidays.update({'2015-01-01': "New Year's Day"})
|
|
177
178
|
>>> custom_holidays.update(['2015-07-01', '07/04/2015'])
|
|
@@ -179,11 +180,10 @@ class HolidayBase(dict[date, str]):
|
|
|
179
180
|
>>> assert date(2015, 1, 1) in custom_holidays
|
|
180
181
|
>>> assert date(2015, 1, 2) not in custom_holidays
|
|
181
182
|
>>> assert '12/25/2015' in custom_holidays
|
|
183
|
+
```
|
|
182
184
|
|
|
183
185
|
For special (one-off) country-wide holidays handling use
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
.. code-block:: python
|
|
186
|
+
`special_public_holidays`:
|
|
187
187
|
|
|
188
188
|
special_public_holidays = {
|
|
189
189
|
1977: ((JUN, 7, "Silver Jubilee of Elizabeth II"),),
|
|
@@ -204,7 +204,8 @@ class HolidayBase(dict[date, str]):
|
|
|
204
204
|
...
|
|
205
205
|
|
|
206
206
|
For more complex logic, like 4th Monday of January, you can inherit the
|
|
207
|
-
|
|
207
|
+
[HolidayBase][holidays.holiday_base.HolidayBase] class and define your own `_populate()`
|
|
208
|
+
method.
|
|
208
209
|
See documentation for examples.
|
|
209
210
|
"""
|
|
210
211
|
|
|
@@ -265,39 +266,40 @@ class HolidayBase(dict[date, str]):
|
|
|
265
266
|
categories: Optional[CategoryArg] = None,
|
|
266
267
|
) -> None:
|
|
267
268
|
"""
|
|
268
|
-
:
|
|
269
|
-
|
|
269
|
+
Args:
|
|
270
|
+
years:
|
|
271
|
+
The year(s) to pre-calculate public holidays for at instantiation.
|
|
270
272
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
273
|
+
expand:
|
|
274
|
+
Whether the entire year is calculated when one date from that year
|
|
275
|
+
is requested.
|
|
274
276
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
277
|
+
observed:
|
|
278
|
+
Whether to include the dates when public holiday are observed
|
|
279
|
+
(e.g. a holiday falling on a Sunday being observed the
|
|
280
|
+
following Monday). This doesn't work for all countries.
|
|
279
281
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
282
|
+
subdiv:
|
|
283
|
+
The subdivision (e.g. state or province) as a ISO 3166-2 code
|
|
284
|
+
or its alias; not implemented for all countries (see documentation).
|
|
283
285
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
+
prov:
|
|
287
|
+
*deprecated* use `subdiv` instead.
|
|
286
288
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
+
state:
|
|
290
|
+
*deprecated* use `subdiv` instead.
|
|
289
291
|
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
292
|
+
language:
|
|
293
|
+
The language which the returned holiday names will be translated
|
|
294
|
+
into. It must be an ISO 639-1 (2-letter) language code. If the
|
|
295
|
+
language translation is not supported the original holiday names
|
|
296
|
+
will be used.
|
|
295
297
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
+
categories:
|
|
299
|
+
Requested holiday categories.
|
|
298
300
|
|
|
299
|
-
:
|
|
300
|
-
A
|
|
301
|
+
Returns:
|
|
302
|
+
A `HolidayBase` object matching the **country** or **market**.
|
|
301
303
|
"""
|
|
302
304
|
super().__init__()
|
|
303
305
|
|
|
@@ -376,14 +378,14 @@ class HolidayBase(dict[date, str]):
|
|
|
376
378
|
|
|
377
379
|
def __add__(self, other: Union[int, "HolidayBase", "HolidaySum"]) -> "HolidayBase":
|
|
378
380
|
"""Add another dictionary of public holidays creating a
|
|
379
|
-
|
|
381
|
+
[HolidaySum][holidays.holiday_base.HolidaySum] object.
|
|
380
382
|
|
|
381
|
-
:
|
|
382
|
-
|
|
383
|
+
Args:
|
|
384
|
+
other:
|
|
385
|
+
The dictionary of public holiday to be added.
|
|
383
386
|
|
|
384
|
-
:
|
|
385
|
-
A
|
|
386
|
-
added, then :class:`self`.
|
|
387
|
+
Returns:
|
|
388
|
+
A `HolidayBase` object unless the other object cannot be added, then `self`.
|
|
387
389
|
"""
|
|
388
390
|
if isinstance(other, int) and other == 0:
|
|
389
391
|
# Required to sum() list of holidays
|
|
@@ -399,14 +401,21 @@ class HolidayBase(dict[date, str]):
|
|
|
399
401
|
return len(self) > 0
|
|
400
402
|
|
|
401
403
|
def __contains__(self, key: object) -> bool:
|
|
402
|
-
"""
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
*
|
|
407
|
-
*
|
|
408
|
-
|
|
409
|
-
* or a
|
|
404
|
+
"""Check if a given date is a holiday.
|
|
405
|
+
|
|
406
|
+
The method supports the following input types:
|
|
407
|
+
|
|
408
|
+
* `datetime.date`,
|
|
409
|
+
* `datetime.datetime`,
|
|
410
|
+
* a `str` of any format recognized by `dateutil.parser.parse()`,
|
|
411
|
+
* or a `float` or `int` representing a POSIX timestamp.
|
|
412
|
+
|
|
413
|
+
Args:
|
|
414
|
+
key:
|
|
415
|
+
The date to check.
|
|
416
|
+
|
|
417
|
+
Returns:
|
|
418
|
+
`True` if the date is a holiday, `False` otherwise.
|
|
410
419
|
"""
|
|
411
420
|
|
|
412
421
|
if not isinstance(key, (date, datetime, float, int, str)):
|
|
@@ -574,15 +583,21 @@ class HolidayBase(dict[date, str]):
|
|
|
574
583
|
return state
|
|
575
584
|
|
|
576
585
|
def __keytransform__(self, key: DateLike) -> date:
|
|
577
|
-
"""
|
|
586
|
+
"""Convert various date-like formats to `datetime.date`.
|
|
578
587
|
|
|
579
|
-
|
|
580
|
-
*
|
|
581
|
-
*
|
|
582
|
-
|
|
583
|
-
* or a
|
|
588
|
+
The method supports the following input types:
|
|
589
|
+
* `datetime.date`,
|
|
590
|
+
* `datetime.datetime`,
|
|
591
|
+
* a `str` of any format recognized by `dateutil.parser.parse()`,
|
|
592
|
+
* or a `float` or `int` representing a POSIX timestamp
|
|
584
593
|
|
|
585
|
-
|
|
594
|
+
Args:
|
|
595
|
+
key:
|
|
596
|
+
The date-like object to convert.
|
|
597
|
+
|
|
598
|
+
Returns:
|
|
599
|
+
The corresponding `datetime.date` representation.
|
|
600
|
+
"""
|
|
586
601
|
|
|
587
602
|
dt: Optional[date] = None
|
|
588
603
|
# Try to catch `date` and `str` type keys first.
|
|
@@ -729,7 +744,11 @@ class HolidayBase(dict[date, str]):
|
|
|
729
744
|
|
|
730
745
|
@classmethod
|
|
731
746
|
def get_subdivision_aliases(cls) -> dict[str, list]:
|
|
732
|
-
"""Get subdivision aliases.
|
|
747
|
+
"""Get subdivision aliases.
|
|
748
|
+
|
|
749
|
+
Returns:
|
|
750
|
+
A dictionary mapping subdivision aliases to their official ISO 3166-2 codes.
|
|
751
|
+
"""
|
|
733
752
|
subdivision_aliases: dict[str, list[str]] = {s: [] for s in cls.subdivisions}
|
|
734
753
|
for alias, subdivision in cls.subdivisions_aliases.items():
|
|
735
754
|
subdivision_aliases[subdivision].append(alias)
|
|
@@ -856,13 +875,13 @@ class HolidayBase(dict[date, str]):
|
|
|
856
875
|
directly from outside.
|
|
857
876
|
To add holidays to an object, use the update() method.
|
|
858
877
|
|
|
859
|
-
:
|
|
860
|
-
The year to populate with holidays.
|
|
878
|
+
Args:
|
|
879
|
+
year: The year to populate with holidays.
|
|
861
880
|
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
881
|
+
>>> from holidays import country_holidays
|
|
882
|
+
>>> us_holidays = country_holidays('US', years=2020)
|
|
883
|
+
# to add new holidays to the object:
|
|
884
|
+
>>> us_holidays.update(country_holidays('US', years=2021))
|
|
866
885
|
"""
|
|
867
886
|
|
|
868
887
|
if year < self.start_year or year > self.end_year:
|
|
@@ -903,7 +922,16 @@ class HolidayBase(dict[date, str]):
|
|
|
903
922
|
)
|
|
904
923
|
|
|
905
924
|
def append(self, *args: Union[dict[DateLike, str], list[DateLike], DateLike]) -> None:
|
|
906
|
-
"""Alias for
|
|
925
|
+
"""Alias for [update()][holidays.holiday_base.HolidayBase.update] to mimic list type.
|
|
926
|
+
|
|
927
|
+
Args:
|
|
928
|
+
args:
|
|
929
|
+
Holiday data to add. Can be:
|
|
930
|
+
|
|
931
|
+
* A dictionary mapping dates to holiday names.
|
|
932
|
+
* A list of dates (without names).
|
|
933
|
+
* A single date.
|
|
934
|
+
"""
|
|
907
935
|
return self.update(*args)
|
|
908
936
|
|
|
909
937
|
def copy(self):
|
|
@@ -911,64 +939,73 @@ class HolidayBase(dict[date, str]):
|
|
|
911
939
|
return copy.copy(self)
|
|
912
940
|
|
|
913
941
|
def get(self, key: DateLike, default: Union[str, Any] = None) -> Union[str, Any]:
|
|
914
|
-
"""
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
942
|
+
"""Retrieve the holiday name(s) for a given date.
|
|
943
|
+
|
|
944
|
+
If the date is a holiday, returns the holiday name as a string.
|
|
945
|
+
If multiple holidays fall on the same date, their names are joined by a semicolon (`;`).
|
|
946
|
+
If the date is not a holiday, returns the provided `default` value (defaults to `None`).
|
|
947
|
+
|
|
948
|
+
Args:
|
|
949
|
+
key:
|
|
950
|
+
The date expressed in one of the following types:
|
|
951
|
+
|
|
952
|
+
* `datetime.date`,
|
|
953
|
+
* `datetime.datetime`,
|
|
954
|
+
* a `str` of any format recognized by `dateutil.parser.parse()`,
|
|
955
|
+
* or a `float` or `int` representing a POSIX timestamp.
|
|
956
|
+
|
|
957
|
+
default:
|
|
958
|
+
The default value to return if no value is found.
|
|
959
|
+
|
|
960
|
+
Returns:
|
|
961
|
+
The holiday name(s) as a string if the date is a holiday,
|
|
962
|
+
or the `default` value otherwise.
|
|
931
963
|
"""
|
|
932
964
|
return dict.get(self, self.__keytransform__(key), default)
|
|
933
965
|
|
|
934
966
|
def get_list(self, key: DateLike) -> list[str]:
|
|
935
|
-
"""
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
967
|
+
"""Retrieve all holiday names for a given date.
|
|
968
|
+
|
|
969
|
+
Args:
|
|
970
|
+
key:
|
|
971
|
+
The date expressed in one of the following types:
|
|
972
|
+
|
|
973
|
+
* `datetime.date`,
|
|
974
|
+
* `datetime.datetime`,
|
|
975
|
+
* a `str` of any format recognized by `dateutil.parser.parse()`,
|
|
976
|
+
* or a `float` or `int` representing a POSIX timestamp.
|
|
977
|
+
|
|
978
|
+
Returns:
|
|
979
|
+
A list of holiday names if the date is a holiday, otherwise an empty list.
|
|
947
980
|
"""
|
|
948
981
|
return [name for name in self.get(key, "").split(HOLIDAY_NAME_DELIMITER) if name]
|
|
949
982
|
|
|
950
983
|
def get_named(
|
|
951
|
-
self, holiday_name: str, lookup="icontains", split_multiple_names=True
|
|
984
|
+
self, holiday_name: str, lookup: str = "icontains", split_multiple_names: bool = True
|
|
952
985
|
) -> list[date]:
|
|
953
|
-
"""
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
:
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
986
|
+
"""Find all holiday dates matching a given name.
|
|
987
|
+
|
|
988
|
+
The search by default is case-insensitive and includes partial matches.
|
|
989
|
+
|
|
990
|
+
Args:
|
|
991
|
+
holiday_name:
|
|
992
|
+
The holiday's name to try to match.
|
|
993
|
+
|
|
994
|
+
lookup:
|
|
995
|
+
The holiday name lookup type:
|
|
996
|
+
|
|
997
|
+
* contains - case sensitive contains match;
|
|
998
|
+
* exact - case sensitive exact match;
|
|
999
|
+
* startswith - case sensitive starts with match;
|
|
1000
|
+
* icontains - case insensitive contains match;
|
|
1001
|
+
* iexact - case insensitive exact match;
|
|
1002
|
+
* istartswith - case insensitive starts with match;
|
|
1003
|
+
|
|
1004
|
+
split_multiple_names:
|
|
1005
|
+
Either use the exact name for each date or split it by holiday
|
|
1006
|
+
name delimiter.
|
|
1007
|
+
|
|
1008
|
+
Returns:
|
|
972
1009
|
A list of all holiday dates matching the provided holiday name.
|
|
973
1010
|
"""
|
|
974
1011
|
holiday_name_dates = (
|
|
@@ -1006,10 +1043,23 @@ class HolidayBase(dict[date, str]):
|
|
|
1006
1043
|
target_date: DateLike = None,
|
|
1007
1044
|
direction: Literal["forward", "backward"] = "forward",
|
|
1008
1045
|
) -> Optional[tuple[date, str]]:
|
|
1009
|
-
"""
|
|
1010
|
-
|
|
1011
|
-
If
|
|
1046
|
+
"""Find the closest holiday relative to a given date.
|
|
1047
|
+
|
|
1048
|
+
If `direction` is "forward", returns the next holiday after `target_date`.
|
|
1049
|
+
If `direction` is "backward", returns the previous holiday before `target_date`.
|
|
1050
|
+
If `target_date` is not provided, the current date is used.
|
|
1051
|
+
|
|
1052
|
+
Args:
|
|
1053
|
+
target_date:
|
|
1054
|
+
The reference date. If None, defaults to today.
|
|
1055
|
+
|
|
1056
|
+
direction:
|
|
1057
|
+
Search direction, either "forward" (next holiday) or
|
|
1058
|
+
"backward" (previous holiday).
|
|
1012
1059
|
|
|
1060
|
+
Returns:
|
|
1061
|
+
A tuple containing the holiday date and its name, or None if no holiday is found.
|
|
1062
|
+
"""
|
|
1013
1063
|
if direction not in {"backward", "forward"}:
|
|
1014
1064
|
raise AttributeError(f"Unknown direction: {direction}")
|
|
1015
1065
|
|
|
@@ -1032,8 +1082,20 @@ class HolidayBase(dict[date, str]):
|
|
|
1032
1082
|
return None
|
|
1033
1083
|
|
|
1034
1084
|
def get_nth_working_day(self, key: DateLike, n: int) -> date:
|
|
1035
|
-
"""
|
|
1036
|
-
|
|
1085
|
+
"""Find the n-th working day from a given date.
|
|
1086
|
+
|
|
1087
|
+
Moves forward if n is positive, or backward if n is negative.
|
|
1088
|
+
|
|
1089
|
+
Args:
|
|
1090
|
+
key:
|
|
1091
|
+
The starting date.
|
|
1092
|
+
|
|
1093
|
+
n:
|
|
1094
|
+
The number of working days to move. Positive values move forward,
|
|
1095
|
+
negative values move backward.
|
|
1096
|
+
|
|
1097
|
+
Returns:
|
|
1098
|
+
The calculated working day after shifting by n working days.
|
|
1037
1099
|
"""
|
|
1038
1100
|
direction = +1 if n > 0 else -1
|
|
1039
1101
|
dt = self.__keytransform__(key)
|
|
@@ -1044,16 +1106,20 @@ class HolidayBase(dict[date, str]):
|
|
|
1044
1106
|
return dt
|
|
1045
1107
|
|
|
1046
1108
|
def get_working_days_count(self, start: DateLike, end: DateLike) -> int:
|
|
1047
|
-
"""
|
|
1109
|
+
"""Calculate the number of working days between two dates.
|
|
1048
1110
|
|
|
1049
1111
|
The date range works in a closed interval fashion [start, end] so both
|
|
1050
1112
|
endpoints are included.
|
|
1051
1113
|
|
|
1052
|
-
:
|
|
1053
|
-
|
|
1114
|
+
Args:
|
|
1115
|
+
start:
|
|
1116
|
+
The range start date.
|
|
1117
|
+
|
|
1118
|
+
end:
|
|
1119
|
+
The range end date.
|
|
1054
1120
|
|
|
1055
|
-
:
|
|
1056
|
-
The
|
|
1121
|
+
Returns:
|
|
1122
|
+
The total count of working days between the given dates.
|
|
1057
1123
|
"""
|
|
1058
1124
|
dt1 = self.__keytransform__(start)
|
|
1059
1125
|
dt2 = self.__keytransform__(end)
|
|
@@ -1063,55 +1129,83 @@ class HolidayBase(dict[date, str]):
|
|
|
1063
1129
|
return sum(self.is_working_day(_timedelta(dt1, n)) for n in range(days))
|
|
1064
1130
|
|
|
1065
1131
|
def is_working_day(self, key: DateLike) -> bool:
|
|
1066
|
-
"""
|
|
1132
|
+
"""Check if the given date is considered a working day.
|
|
1133
|
+
|
|
1134
|
+
Args:
|
|
1135
|
+
key:
|
|
1136
|
+
The date to check.
|
|
1137
|
+
|
|
1138
|
+
Returns:
|
|
1139
|
+
True if the date is a working day, False if it is a holiday or weekend.
|
|
1140
|
+
"""
|
|
1067
1141
|
dt = self.__keytransform__(key)
|
|
1068
1142
|
return dt in self.weekend_workdays if self._is_weekend(dt) else dt not in self
|
|
1069
1143
|
|
|
1070
1144
|
def pop(self, key: DateLike, default: Union[str, Any] = None) -> Union[str, Any]:
|
|
1071
|
-
"""
|
|
1072
|
-
|
|
1145
|
+
"""Remove a holiday for a given date and return its name.
|
|
1146
|
+
|
|
1147
|
+
If the specified date is a holiday, it will be removed, and its name will
|
|
1148
|
+
be returned. If the date is not a holiday, the provided `default` value
|
|
1149
|
+
will be returned instead.
|
|
1073
1150
|
|
|
1074
|
-
:
|
|
1075
|
-
|
|
1151
|
+
Args:
|
|
1152
|
+
key:
|
|
1153
|
+
The date expressed in one of the following types:
|
|
1076
1154
|
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
* or a :class:`float` or :class:`int` representing a POSIX
|
|
1082
|
-
timestamp.
|
|
1155
|
+
* `datetime.date`,
|
|
1156
|
+
* `datetime.datetime`,
|
|
1157
|
+
* a `str` of any format recognized by `dateutil.parser.parse()`,
|
|
1158
|
+
* or a `float` or `int` representing a POSIX timestamp.
|
|
1083
1159
|
|
|
1084
|
-
|
|
1085
|
-
|
|
1160
|
+
default:
|
|
1161
|
+
The default value to return if no match is found.
|
|
1086
1162
|
|
|
1087
|
-
:
|
|
1088
|
-
The date
|
|
1163
|
+
Returns:
|
|
1164
|
+
The name of the removed holiday if the date was a holiday, otherwise
|
|
1165
|
+
the provided `default` value.
|
|
1089
1166
|
|
|
1090
|
-
:
|
|
1091
|
-
KeyError if date is not a holiday and default is not given.
|
|
1167
|
+
Raises:
|
|
1168
|
+
KeyError: if date is not a holiday and default is not given.
|
|
1092
1169
|
"""
|
|
1093
1170
|
if default is None:
|
|
1094
1171
|
return dict.pop(self, self.__keytransform__(key))
|
|
1095
1172
|
|
|
1096
1173
|
return dict.pop(self, self.__keytransform__(key), default)
|
|
1097
1174
|
|
|
1098
|
-
def pop_named(self,
|
|
1099
|
-
"""Remove
|
|
1100
|
-
|
|
1101
|
-
|
|
1175
|
+
def pop_named(self, holiday_name: str, lookup: str = "icontains") -> list[date]:
|
|
1176
|
+
"""Remove all holidays matching the given name.
|
|
1177
|
+
|
|
1178
|
+
This method removes all dates associated with a holiday name, so they are
|
|
1179
|
+
no longer considered holidays. The search by default is case-insensitive and
|
|
1180
|
+
includes partial matches.
|
|
1102
1181
|
|
|
1103
|
-
:
|
|
1104
|
-
|
|
1182
|
+
Args:
|
|
1183
|
+
holiday_name:
|
|
1184
|
+
The holiday's name to try to match.
|
|
1105
1185
|
|
|
1106
|
-
|
|
1186
|
+
lookup:
|
|
1187
|
+
The holiday name lookup type:
|
|
1188
|
+
|
|
1189
|
+
* contains - case sensitive contains match;
|
|
1190
|
+
* exact - case sensitive exact match;
|
|
1191
|
+
* startswith - case sensitive starts with match;
|
|
1192
|
+
* icontains - case insensitive contains match;
|
|
1193
|
+
* iexact - case insensitive exact match;
|
|
1194
|
+
* istartswith - case insensitive starts with match;
|
|
1195
|
+
|
|
1196
|
+
Returns:
|
|
1107
1197
|
A list of dates removed.
|
|
1108
1198
|
|
|
1109
|
-
:
|
|
1110
|
-
KeyError if date is not a holiday
|
|
1199
|
+
Raises:
|
|
1200
|
+
KeyError: if date is not a holiday.
|
|
1111
1201
|
"""
|
|
1112
|
-
use_exact_name = HOLIDAY_NAME_DELIMITER in
|
|
1113
|
-
if not (
|
|
1114
|
-
|
|
1202
|
+
use_exact_name = HOLIDAY_NAME_DELIMITER in holiday_name
|
|
1203
|
+
if not (
|
|
1204
|
+
dts := self.get_named(
|
|
1205
|
+
holiday_name, lookup=lookup, split_multiple_names=not use_exact_name
|
|
1206
|
+
)
|
|
1207
|
+
):
|
|
1208
|
+
raise KeyError(holiday_name)
|
|
1115
1209
|
|
|
1116
1210
|
popped = []
|
|
1117
1211
|
for dt in dts:
|
|
@@ -1120,38 +1214,55 @@ class HolidayBase(dict[date, str]):
|
|
|
1120
1214
|
popped.append(dt)
|
|
1121
1215
|
|
|
1122
1216
|
# Keep the rest of holidays falling on the same date.
|
|
1123
|
-
if
|
|
1124
|
-
|
|
1217
|
+
if use_exact_name:
|
|
1218
|
+
continue
|
|
1219
|
+
if lookup == "icontains":
|
|
1220
|
+
holiday_name_lower = holiday_name.lower()
|
|
1125
1221
|
holiday_names = [
|
|
1126
|
-
|
|
1127
|
-
for holiday_name in holiday_names
|
|
1128
|
-
if name_lower not in holiday_name.lower()
|
|
1222
|
+
name for name in holiday_names if holiday_name_lower not in name.lower()
|
|
1129
1223
|
]
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1224
|
+
elif lookup == "iexact":
|
|
1225
|
+
holiday_name_lower = holiday_name.lower()
|
|
1226
|
+
holiday_names = [
|
|
1227
|
+
name for name in holiday_names if holiday_name_lower != name.lower()
|
|
1228
|
+
]
|
|
1229
|
+
elif lookup == "istartswith":
|
|
1230
|
+
holiday_name_lower = holiday_name.lower()
|
|
1231
|
+
holiday_names = [
|
|
1232
|
+
name
|
|
1233
|
+
for name in holiday_names
|
|
1234
|
+
if holiday_name_lower != name[: len(holiday_name)].lower()
|
|
1235
|
+
]
|
|
1236
|
+
elif lookup == "contains":
|
|
1237
|
+
holiday_names = [name for name in holiday_names if holiday_name not in name]
|
|
1238
|
+
elif lookup == "exact":
|
|
1239
|
+
holiday_names = [name for name in holiday_names if holiday_name != name]
|
|
1240
|
+
else: # startswith
|
|
1241
|
+
holiday_names = [
|
|
1242
|
+
name for name in holiday_names if holiday_name != name[: len(holiday_name)]
|
|
1243
|
+
]
|
|
1244
|
+
if holiday_names:
|
|
1245
|
+
self[dt] = HOLIDAY_NAME_DELIMITER.join(holiday_names)
|
|
1133
1246
|
|
|
1134
1247
|
return popped
|
|
1135
1248
|
|
|
1136
1249
|
def update( # type: ignore[override]
|
|
1137
1250
|
self, *args: Union[dict[DateLike, str], list[DateLike], DateLike]
|
|
1138
1251
|
) -> None:
|
|
1139
|
-
# TODO: fix arguments; should not be *args (cannot properly Type hint)
|
|
1140
1252
|
"""Update the object, overwriting existing dates.
|
|
1141
1253
|
|
|
1142
|
-
:
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1254
|
+
Args:
|
|
1255
|
+
args:
|
|
1256
|
+
Either another dictionary object where keys are dates and values
|
|
1257
|
+
are holiday names, or a single date (or a list of dates) for which
|
|
1258
|
+
the value will be set to "Holiday".
|
|
1146
1259
|
|
|
1147
|
-
|
|
1260
|
+
Dates can be expressed in one or more of the following types:
|
|
1148
1261
|
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
* or a :class:`float` or :class:`int` representing a POSIX
|
|
1154
|
-
timestamp.
|
|
1262
|
+
* `datetime.date`,
|
|
1263
|
+
* `datetime.datetime`,
|
|
1264
|
+
* a `str` of any format recognized by `dateutil.parser.parse()`,
|
|
1265
|
+
* or a `float` or `int` representing a POSIX timestamp.
|
|
1155
1266
|
"""
|
|
1156
1267
|
for arg in args:
|
|
1157
1268
|
if isinstance(arg, dict):
|
|
@@ -1166,11 +1277,11 @@ class HolidayBase(dict[date, str]):
|
|
|
1166
1277
|
|
|
1167
1278
|
class HolidaySum(HolidayBase):
|
|
1168
1279
|
"""
|
|
1169
|
-
Returns a
|
|
1280
|
+
Returns a `dict`-like object resulting from the addition of two or
|
|
1170
1281
|
more individual dictionaries of public holidays. The original dictionaries
|
|
1171
|
-
are available as a
|
|
1172
|
-
|
|
1173
|
-
together and could become
|
|
1282
|
+
are available as a `list` in the attribute `holidays,` and
|
|
1283
|
+
`country` and `subdiv` attributes are added
|
|
1284
|
+
together and could become `list` s. Holiday names, when different,
|
|
1174
1285
|
are merged. All years are calculated (expanded) for all operands.
|
|
1175
1286
|
"""
|
|
1176
1287
|
|
|
@@ -1189,30 +1300,31 @@ class HolidaySum(HolidayBase):
|
|
|
1189
1300
|
self, h1: Union[HolidayBase, "HolidaySum"], h2: Union[HolidayBase, "HolidaySum"]
|
|
1190
1301
|
) -> None:
|
|
1191
1302
|
"""
|
|
1192
|
-
:
|
|
1193
|
-
|
|
1303
|
+
Args:
|
|
1304
|
+
h1:
|
|
1305
|
+
The first HolidayBase object to add.
|
|
1194
1306
|
|
|
1195
|
-
|
|
1196
|
-
|
|
1307
|
+
h2:
|
|
1308
|
+
The other HolidayBase object to add.
|
|
1197
1309
|
|
|
1198
1310
|
Example:
|
|
1199
1311
|
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
country_holidays('CA') + country_holidays('MX')
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1312
|
+
>>> from holidays import country_holidays
|
|
1313
|
+
>>> nafta_holidays = country_holidays('US', years=2020) + \
|
|
1314
|
+
country_holidays('CA') + country_holidays('MX')
|
|
1315
|
+
>>> dates = sorted(nafta_holidays.items(), key=lambda x: x[0])
|
|
1316
|
+
>>> from pprint import pprint
|
|
1317
|
+
>>> pprint(dates[:10], width=72)
|
|
1318
|
+
[(datetime.date(2020, 1, 1), "Año Nuevo; New Year's Day"),
|
|
1319
|
+
(datetime.date(2020, 1, 20), 'Martin Luther King Jr. Day'),
|
|
1320
|
+
(datetime.date(2020, 2, 3), 'Día de la Constitución'),
|
|
1321
|
+
(datetime.date(2020, 2, 17), "Washington's Birthday"),
|
|
1322
|
+
(datetime.date(2020, 3, 16), 'Natalicio de Benito Juárez'),
|
|
1323
|
+
(datetime.date(2020, 4, 10), 'Good Friday'),
|
|
1324
|
+
(datetime.date(2020, 5, 1), 'Día del Trabajo'),
|
|
1325
|
+
(datetime.date(2020, 5, 25), 'Memorial Day'),
|
|
1326
|
+
(datetime.date(2020, 7, 1), 'Canada Day'),
|
|
1327
|
+
(datetime.date(2020, 7, 3), 'Independence Day (observed)')]
|
|
1216
1328
|
"""
|
|
1217
1329
|
# Store originals in the holidays attribute.
|
|
1218
1330
|
self.holidays = []
|
|
@@ -1260,8 +1372,18 @@ country_holidays('CA') + country_holidays('MX')
|
|
|
1260
1372
|
else:
|
|
1261
1373
|
setattr(self, attr, value)
|
|
1262
1374
|
|
|
1375
|
+
# Retain language if they match and are strings.
|
|
1376
|
+
# If language wasn't assigned, default_language acts as fallback.
|
|
1377
|
+
h1_language = h1.language or h1.default_language
|
|
1378
|
+
h2_language = h2.language or h2.default_language
|
|
1379
|
+
if isinstance(h1_language, str) and h1_language == h2_language:
|
|
1380
|
+
kwargs["language"] = h1_language
|
|
1381
|
+
|
|
1263
1382
|
HolidayBase.__init__(self, **kwargs)
|
|
1264
1383
|
|
|
1384
|
+
# supported_languages is used for iCalExporter language check as well.
|
|
1385
|
+
self.supported_languages = (h1_language,) if h1_language else ()
|
|
1386
|
+
|
|
1265
1387
|
def _populate(self, year):
|
|
1266
1388
|
for operand in self.holidays:
|
|
1267
1389
|
operand._populate(year)
|