holidays 0.81__py3-none-any.whl → 0.82__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/calendars/__init__.py +1 -0
- holidays/calendars/burmese.py +319 -0
- holidays/calendars/hebrew.py +2 -2
- holidays/calendars/thai.py +49 -2
- holidays/countries/__init__.py +10 -0
- holidays/countries/afghanistan.py +7 -5
- holidays/countries/algeria.py +89 -24
- holidays/countries/antarctica.py +58 -0
- holidays/countries/bouvet_island.py +31 -0
- holidays/countries/brazil.py +1 -1
- holidays/countries/british_indian_ocean_territory.py +31 -0
- holidays/countries/bulgaria.py +6 -1
- holidays/countries/chile.py +9 -8
- holidays/countries/cuba.py +3 -4
- holidays/countries/djibouti.py +1 -1
- holidays/countries/heard_island_and_mcdonald_islands.py +31 -0
- holidays/countries/hungary.py +4 -5
- holidays/countries/india.py +6 -0
- holidays/countries/japan.py +22 -18
- holidays/countries/jordan.py +6 -3
- holidays/countries/kuwait.py +6 -3
- holidays/countries/malaysia.py +14 -3
- holidays/countries/myanmar.py +195 -0
- holidays/countries/north_korea.py +161 -0
- holidays/countries/norway.py +23 -8
- holidays/countries/oman.py +6 -2
- holidays/countries/paraguay.py +70 -23
- holidays/countries/portugal.py +5 -6
- holidays/countries/qatar.py +5 -2
- holidays/countries/rwanda.py +6 -1
- holidays/countries/saudi_arabia.py +6 -5
- holidays/countries/serbia.py +5 -0
- holidays/countries/south_africa.py +96 -53
- holidays/countries/south_korea.py +6 -1
- holidays/countries/spain.py +4 -4
- holidays/countries/sudan.py +6 -3
- holidays/countries/switzerland.py +169 -3
- holidays/countries/taiwan.py +22 -2
- holidays/countries/tanzania.py +6 -1
- holidays/countries/thailand.py +21 -0
- holidays/countries/tonga.py +6 -1
- holidays/countries/trinidad_and_tobago.py +6 -1
- holidays/countries/united_arab_emirates.py +9 -2
- holidays/countries/united_states.py +16 -0
- holidays/countries/uruguay.py +6 -1
- holidays/countries/vietnam.py +6 -1
- holidays/countries/yemen.py +6 -3
- holidays/groups/__init__.py +1 -0
- holidays/groups/balinese_saka.py +1 -1
- holidays/groups/buddhist.py +1 -1
- holidays/groups/burmese.py +273 -0
- holidays/groups/chinese.py +25 -0
- holidays/groups/custom.py +8 -2
- holidays/groups/eastern.py +24 -0
- holidays/groups/hebrew.py +16 -14
- holidays/groups/hindu.py +15 -13
- holidays/groups/islamic.py +43 -48
- holidays/groups/mongolian.py +1 -1
- holidays/groups/sinhala.py +4 -9
- holidays/groups/tibetan.py +3 -4
- holidays/holiday_base.py +5 -4
- holidays/ical.py +6 -4
- holidays/locale/ar/LC_MESSAGES/DZ.mo +0 -0
- holidays/locale/ca/LC_MESSAGES/ES.mo +0 -0
- holidays/locale/en_IN/LC_MESSAGES/IN.mo +0 -0
- holidays/locale/en_US/LC_MESSAGES/BR.mo +0 -0
- holidays/locale/en_US/LC_MESSAGES/DZ.mo +0 -0
- holidays/locale/en_US/LC_MESSAGES/ES.mo +0 -0
- holidays/locale/en_US/LC_MESSAGES/IN.mo +0 -0
- holidays/locale/en_US/LC_MESSAGES/JP.mo +0 -0
- holidays/locale/en_US/LC_MESSAGES/KP.mo +0 -0
- holidays/locale/en_US/LC_MESSAGES/MM.mo +0 -0
- holidays/locale/en_US/LC_MESSAGES/PY.mo +0 -0
- holidays/locale/en_US/LC_MESSAGES/US.mo +0 -0
- holidays/locale/es/LC_MESSAGES/ES.mo +0 -0
- holidays/locale/es/LC_MESSAGES/PY.mo +0 -0
- holidays/locale/fr/LC_MESSAGES/DZ.mo +0 -0
- holidays/locale/hi/LC_MESSAGES/IN.mo +0 -0
- holidays/locale/ja/LC_MESSAGES/JP.mo +0 -0
- holidays/locale/ko_KP/LC_MESSAGES/KP.mo +0 -0
- holidays/locale/my/LC_MESSAGES/MM.mo +0 -0
- holidays/locale/pt_BR/LC_MESSAGES/BR.mo +0 -0
- holidays/locale/th/LC_MESSAGES/JP.mo +0 -0
- holidays/locale/th/LC_MESSAGES/MM.mo +0 -0
- holidays/locale/th/LC_MESSAGES/US.mo +0 -0
- holidays/locale/uk/LC_MESSAGES/BR.mo +0 -0
- holidays/locale/uk/LC_MESSAGES/ES.mo +0 -0
- holidays/locale/uk/LC_MESSAGES/PY.mo +0 -0
- holidays/no_holiday_base.py +21 -0
- holidays/registry.py +6 -0
- holidays/utils.py +5 -5
- holidays/version.py +1 -1
- {holidays-0.81.dist-info → holidays-0.82.dist-info}/METADATA +47 -5
- {holidays-0.81.dist-info → holidays-0.82.dist-info}/RECORD +98 -83
- {holidays-0.81.dist-info → holidays-0.82.dist-info}/licenses/CONTRIBUTORS +2 -0
- {holidays-0.81.dist-info → holidays-0.82.dist-info}/WHEEL +0 -0
- {holidays-0.81.dist-info → holidays-0.82.dist-info}/licenses/LICENSE +0 -0
- {holidays-0.81.dist-info → holidays-0.82.dist-info}/top_level.txt +0 -0
holidays/calendars/__init__.py
CHANGED
|
@@ -14,6 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
from holidays.calendars.balinese_saka import _BalineseSakaLunar
|
|
16
16
|
from holidays.calendars.buddhist import _BuddhistLunisolar, _CustomBuddhistHolidays
|
|
17
|
+
from holidays.calendars.burmese import _BurmeseLunisolar
|
|
17
18
|
from holidays.calendars.chinese import _ChineseLunisolar, _CustomChineseHolidays
|
|
18
19
|
from holidays.calendars.custom import _CustomCalendar
|
|
19
20
|
from holidays.calendars.gregorian import GREGORIAN_CALENDAR
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
# holidays
|
|
2
|
+
# --------
|
|
3
|
+
# A fast, efficient Python library for generating country, province and state
|
|
4
|
+
# specific sets of holidays on the fly. It aims to make determining whether a
|
|
5
|
+
# specific date is a holiday as fast and flexible as possible.
|
|
6
|
+
#
|
|
7
|
+
# Authors: Vacanza Team and individual contributors (see CONTRIBUTORS file)
|
|
8
|
+
# dr-prodigy <dr.prodigy.github@gmail.com> (c) 2017-2023
|
|
9
|
+
# ryanss <ryanssdev@icloud.com> (c) 2014-2017
|
|
10
|
+
# Website: https://github.com/vacanza/holidays
|
|
11
|
+
# License: MIT (see LICENSE file)
|
|
12
|
+
|
|
13
|
+
from datetime import date
|
|
14
|
+
from functools import cache
|
|
15
|
+
from typing import Optional
|
|
16
|
+
|
|
17
|
+
from holidays.calendars.gregorian import _timedelta
|
|
18
|
+
|
|
19
|
+
MO = 1954168.050623 # Beginning of 0 ME for MMT.
|
|
20
|
+
SY = 1577917828.0 / 4320000.0 # Solar year (365.2587565 days).
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class _BurmeseLunisolar:
|
|
24
|
+
"""Burmese Lunisolar calendar.
|
|
25
|
+
|
|
26
|
+
References:
|
|
27
|
+
* [Algorithm, Program and Calculation of Myanmar Calendar](https://web.archive.org/web/20250510011425/http://cool-emerald.blogspot.com/2013/06/algorithm-program-and-calculation-of.html)
|
|
28
|
+
"""
|
|
29
|
+
|
|
30
|
+
START_DATE = date(1939, 3, 20) # 1 Late Tagu 1301 Burmese Era.
|
|
31
|
+
START_YEAR = 1939 # 1301 Burmese Era.
|
|
32
|
+
END_YEAR = 2100 # 1463 Burmese Era.
|
|
33
|
+
|
|
34
|
+
LITTLE_WATAT_YEARS_GREGORIAN = {
|
|
35
|
+
1939,
|
|
36
|
+
1948,
|
|
37
|
+
1955,
|
|
38
|
+
1958,
|
|
39
|
+
1966,
|
|
40
|
+
1972,
|
|
41
|
+
1974,
|
|
42
|
+
1982,
|
|
43
|
+
1988,
|
|
44
|
+
1993,
|
|
45
|
+
1999,
|
|
46
|
+
2004,
|
|
47
|
+
2012,
|
|
48
|
+
2018,
|
|
49
|
+
2020,
|
|
50
|
+
2029,
|
|
51
|
+
2034,
|
|
52
|
+
2039,
|
|
53
|
+
2045,
|
|
54
|
+
2050,
|
|
55
|
+
2056,
|
|
56
|
+
2061,
|
|
57
|
+
2069,
|
|
58
|
+
2075,
|
|
59
|
+
2077,
|
|
60
|
+
2086,
|
|
61
|
+
2091,
|
|
62
|
+
2096,
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
BIG_WATAT_YEARS_GREGORIAN = {
|
|
66
|
+
1942,
|
|
67
|
+
1945,
|
|
68
|
+
1950,
|
|
69
|
+
1953,
|
|
70
|
+
1961,
|
|
71
|
+
1964,
|
|
72
|
+
1969,
|
|
73
|
+
1977,
|
|
74
|
+
1980,
|
|
75
|
+
1985,
|
|
76
|
+
1991,
|
|
77
|
+
1996,
|
|
78
|
+
2001,
|
|
79
|
+
2007,
|
|
80
|
+
2010,
|
|
81
|
+
2015,
|
|
82
|
+
2023,
|
|
83
|
+
2026,
|
|
84
|
+
2031,
|
|
85
|
+
2037,
|
|
86
|
+
2042,
|
|
87
|
+
2048,
|
|
88
|
+
2053,
|
|
89
|
+
2058,
|
|
90
|
+
2064,
|
|
91
|
+
2067,
|
|
92
|
+
2072,
|
|
93
|
+
2080,
|
|
94
|
+
2083,
|
|
95
|
+
2088,
|
|
96
|
+
2094,
|
|
97
|
+
2099,
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
@staticmethod
|
|
101
|
+
def jdn_to_gregorian(jdn: int) -> date:
|
|
102
|
+
"""Convert Julian Day Number to Gregorian date.
|
|
103
|
+
|
|
104
|
+
Args:
|
|
105
|
+
jdn: Julian Day Number.
|
|
106
|
+
|
|
107
|
+
Returns:
|
|
108
|
+
Gregorian date.
|
|
109
|
+
"""
|
|
110
|
+
j = jdn - 1721119
|
|
111
|
+
y, j = divmod(4 * j - 1, 146097)
|
|
112
|
+
d = j // 4
|
|
113
|
+
j, d = divmod(4 * d + 3, 1461)
|
|
114
|
+
d = (d + 4) // 4
|
|
115
|
+
m, d = divmod(5 * d - 3, 153)
|
|
116
|
+
d = (d + 5) // 5
|
|
117
|
+
y = 100 * y + j
|
|
118
|
+
if m < 10:
|
|
119
|
+
m += 3
|
|
120
|
+
else:
|
|
121
|
+
m -= 9
|
|
122
|
+
y += 1
|
|
123
|
+
|
|
124
|
+
return date(y, m, d)
|
|
125
|
+
|
|
126
|
+
@cache
|
|
127
|
+
def _get_start_date(self, year: int) -> Optional[date]:
|
|
128
|
+
if year < self.START_YEAR or year > self.END_YEAR:
|
|
129
|
+
return None
|
|
130
|
+
|
|
131
|
+
delta_days = 354 * (year - self.START_YEAR)
|
|
132
|
+
for iter_year in range(self.START_YEAR, year):
|
|
133
|
+
if iter_year in self.LITTLE_WATAT_YEARS_GREGORIAN:
|
|
134
|
+
delta_days += 30
|
|
135
|
+
elif iter_year in self.BIG_WATAT_YEARS_GREGORIAN:
|
|
136
|
+
delta_days += 31
|
|
137
|
+
|
|
138
|
+
return _timedelta(self.START_DATE, delta_days)
|
|
139
|
+
|
|
140
|
+
def thingyan_dates(self, year: int) -> tuple[Optional[date], Optional[date]]:
|
|
141
|
+
"""Calculate key dates of Thingyan (Myanmar New Year festival) - Akya day
|
|
142
|
+
and Atat day.
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
year:
|
|
146
|
+
Gregorian year.
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
Akya day date, Atat day date.
|
|
150
|
+
|
|
151
|
+
"""
|
|
152
|
+
if year < self.START_YEAR or year > self.END_YEAR:
|
|
153
|
+
return None, None
|
|
154
|
+
|
|
155
|
+
ja = SY * (year - 638) + MO
|
|
156
|
+
jk = (ja - 2.169918982) if year >= 1950 else (ja - 2.1675)
|
|
157
|
+
|
|
158
|
+
return self.jdn_to_gregorian(round(jk)), self.jdn_to_gregorian(round(ja))
|
|
159
|
+
|
|
160
|
+
def kason_full_moon_date(self, year: int) -> Optional[date]:
|
|
161
|
+
"""Calculate the Gregorian date of Full Moon Day of Kason.
|
|
162
|
+
|
|
163
|
+
15th day of 2nd month (Kason).
|
|
164
|
+
|
|
165
|
+
To calculate, we use the following time delta:
|
|
166
|
+
|
|
167
|
+
* All years:
|
|
168
|
+
29 [1] + 15 - 1 = 43.
|
|
169
|
+
|
|
170
|
+
Args:
|
|
171
|
+
year:
|
|
172
|
+
Gregorian year.
|
|
173
|
+
|
|
174
|
+
Returns:
|
|
175
|
+
Gregorian date of Full Moon Day of Kason.
|
|
176
|
+
`None` if the Gregorian year is out of supported range.
|
|
177
|
+
"""
|
|
178
|
+
if not (start_date := self._get_start_date(year)):
|
|
179
|
+
return None
|
|
180
|
+
|
|
181
|
+
return _timedelta(start_date, +43)
|
|
182
|
+
|
|
183
|
+
def waso_full_moon_date(self, year: int) -> Optional[date]:
|
|
184
|
+
"""Calculate the Gregorian date of Full Moon Day of Waso.
|
|
185
|
+
|
|
186
|
+
15th day of 4th month (Waso).
|
|
187
|
+
|
|
188
|
+
To calculate, we use the following time delta:
|
|
189
|
+
|
|
190
|
+
* All years:
|
|
191
|
+
Year_length - 266 [4-12] + 15 - 1 = Year_length - 252.
|
|
192
|
+
|
|
193
|
+
Args:
|
|
194
|
+
year:
|
|
195
|
+
Gregorian year.
|
|
196
|
+
|
|
197
|
+
Returns:
|
|
198
|
+
Gregorian date of Full Moon Day of Waso.
|
|
199
|
+
`None` if the Gregorian year is out of supported range.
|
|
200
|
+
"""
|
|
201
|
+
if not (next_year_start_date := self._get_start_date(year + 1)):
|
|
202
|
+
return None
|
|
203
|
+
|
|
204
|
+
return _timedelta(next_year_start_date, -252)
|
|
205
|
+
|
|
206
|
+
def thadingyut_full_moon_date(self, year: int) -> Optional[date]:
|
|
207
|
+
"""Calculate the Gregorian date of Full Moon Day of Thadingyut.
|
|
208
|
+
|
|
209
|
+
15th day of 7th month (Thadingyut).
|
|
210
|
+
|
|
211
|
+
To calculate, we use the following time delta:
|
|
212
|
+
|
|
213
|
+
* All years:
|
|
214
|
+
Year_length - 177 [7-12] + 15 - 1 = Year_length - 163.
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
year:
|
|
218
|
+
Gregorian year.
|
|
219
|
+
|
|
220
|
+
Returns:
|
|
221
|
+
Gregorian date of Full Moon Day of Thadingyut.
|
|
222
|
+
`None` if the Gregorian year is out of supported range.
|
|
223
|
+
"""
|
|
224
|
+
if not (next_year_start_date := self._get_start_date(year + 1)):
|
|
225
|
+
return None
|
|
226
|
+
|
|
227
|
+
return _timedelta(next_year_start_date, -163)
|
|
228
|
+
|
|
229
|
+
def tazaungmon_waxing_moon_date(self, year: int) -> Optional[date]:
|
|
230
|
+
"""Calculate the Gregorian date of 1st Waxing Day of Tazaungmon.
|
|
231
|
+
|
|
232
|
+
1st day of 8th month (Tazaungmon).
|
|
233
|
+
|
|
234
|
+
To calculate, we use the following time delta:
|
|
235
|
+
|
|
236
|
+
* All years:
|
|
237
|
+
Year_length - 148 [8-12] + 1 - 1 = Year_length - 148.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
year:
|
|
241
|
+
Gregorian year.
|
|
242
|
+
|
|
243
|
+
Returns:
|
|
244
|
+
Gregorian date of 1st Waxing Day of Tazaungmon.
|
|
245
|
+
`None` if the Gregorian year is out of supported range.
|
|
246
|
+
"""
|
|
247
|
+
if not (next_year_start_date := self._get_start_date(year + 1)):
|
|
248
|
+
return None
|
|
249
|
+
|
|
250
|
+
return _timedelta(next_year_start_date, -148)
|
|
251
|
+
|
|
252
|
+
def tazaungmon_full_moon_date(self, year: int) -> Optional[date]:
|
|
253
|
+
"""Calculate the Gregorian date of Full Moon Day of Tazaungmon.
|
|
254
|
+
|
|
255
|
+
15th day of 8th month (Tazaungmon).
|
|
256
|
+
|
|
257
|
+
To calculate, we use the following time delta:
|
|
258
|
+
|
|
259
|
+
* All years:
|
|
260
|
+
Year_length - 148 [8-12] + 15 - 1 = Year_length - 134.
|
|
261
|
+
|
|
262
|
+
Args:
|
|
263
|
+
year:
|
|
264
|
+
Gregorian year.
|
|
265
|
+
|
|
266
|
+
Returns:
|
|
267
|
+
Gregorian date of Full Moon Day of Tazaungmon.
|
|
268
|
+
`None` if the Gregorian year is out of supported range.
|
|
269
|
+
"""
|
|
270
|
+
if not (next_year_start_date := self._get_start_date(year + 1)):
|
|
271
|
+
return None
|
|
272
|
+
|
|
273
|
+
return _timedelta(next_year_start_date, -134)
|
|
274
|
+
|
|
275
|
+
def pyatho_waxing_moon_date(self, year: int) -> Optional[date]:
|
|
276
|
+
"""Calculate the Gregorian date of 1st Waxing Day of Pyatho.
|
|
277
|
+
|
|
278
|
+
1st day of 10th month (Pyatho).
|
|
279
|
+
|
|
280
|
+
To calculate, we use the following time delta:
|
|
281
|
+
|
|
282
|
+
* All years:
|
|
283
|
+
Year_length - 89 [10-12] + 1 - 1 = Year_length - 89.
|
|
284
|
+
|
|
285
|
+
Args:
|
|
286
|
+
year:
|
|
287
|
+
Gregorian year.
|
|
288
|
+
|
|
289
|
+
Returns:
|
|
290
|
+
Gregorian date of 1st Waxing Day of Pyatho.
|
|
291
|
+
`None` if the Gregorian year is out of supported range.
|
|
292
|
+
"""
|
|
293
|
+
if not (next_year_start_date := self._get_start_date(year + 1)):
|
|
294
|
+
return None
|
|
295
|
+
|
|
296
|
+
return _timedelta(next_year_start_date, -89)
|
|
297
|
+
|
|
298
|
+
def tabaung_full_moon_date(self, year: int) -> Optional[date]:
|
|
299
|
+
"""Calculate the Gregorian date of Full Moon Day of Tabaung.
|
|
300
|
+
|
|
301
|
+
15th day of 12th month (Tabaung).
|
|
302
|
+
|
|
303
|
+
To calculate, we use the following time delta:
|
|
304
|
+
|
|
305
|
+
* All years:
|
|
306
|
+
Year_length - 30 [12] + 15 - 1 = Year_length - 16.
|
|
307
|
+
|
|
308
|
+
Args:
|
|
309
|
+
year:
|
|
310
|
+
Gregorian year.
|
|
311
|
+
|
|
312
|
+
Returns:
|
|
313
|
+
Gregorian date of Full Moon Day of Tabaung.
|
|
314
|
+
`None` if the Gregorian year is out of supported range.
|
|
315
|
+
"""
|
|
316
|
+
if not (next_year_start_date := self._get_start_date(year + 1)):
|
|
317
|
+
return None
|
|
318
|
+
|
|
319
|
+
return _timedelta(next_year_start_date, -16)
|
holidays/calendars/hebrew.py
CHANGED
|
@@ -1602,8 +1602,8 @@ class _HebrewLunisolar:
|
|
|
1602
1602
|
dt = getattr(self, f"{holiday}_DATES", {}).get(year, ())
|
|
1603
1603
|
return date(year, *dt) if dt else None
|
|
1604
1604
|
|
|
1605
|
-
def hanukkah_date(self, year: int) -> set[
|
|
1606
|
-
return {
|
|
1605
|
+
def hanukkah_date(self, year: int) -> set[date]:
|
|
1606
|
+
return {dt for y in (year - 1, year) if (dt := self._get_holiday(HANUKKAH, y)) is not None}
|
|
1607
1607
|
|
|
1608
1608
|
def israel_independence_date(self, year: int) -> Optional[date]:
|
|
1609
1609
|
return self._get_holiday(INDEPENDENCE_DAY, year)
|
holidays/calendars/thai.py
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
# License: MIT (see LICENSE file)
|
|
12
12
|
|
|
13
13
|
from datetime import date
|
|
14
|
-
from functools import
|
|
14
|
+
from functools import cache
|
|
15
15
|
from typing import Optional
|
|
16
16
|
|
|
17
17
|
from holidays.calendars.gregorian import _timedelta
|
|
@@ -100,6 +100,8 @@ class _ThaiLunisolar:
|
|
|
100
100
|
References:
|
|
101
101
|
* <https://web.archive.org/web/20241016080156/https://www.ninenik.com/แนวทางฟังก์ชั่น_php_อย่างง่ายกับการหาวันข้างขึ้นข้างแรม-1021.html>
|
|
102
102
|
* <https://web.archive.org/web/20250119171416/https://www.myhora.com/ปฏิทิน/ปฏิทิน-พ.ศ.2560.aspx>
|
|
103
|
+
* <https://web.archive.org/web/20250302100842/https://calendar.kunthet.com/#/>
|
|
104
|
+
* [2025 Khmer Lunar Calendar](https://web.archive.org/web/20250921045847/https://static1.squarespace.com/static/67722f65f2908e531b5f326d/t/678a87776503cc3f8bc538ac/1737131904673/2025Calendar-compressed.pdf)
|
|
103
105
|
|
|
104
106
|
Example:
|
|
105
107
|
|
|
@@ -293,7 +295,7 @@ class _ThaiLunisolar:
|
|
|
293
295
|
f"Unknown calendar name: {calendar}. Use `KHMER_CALENDAR` or `THAI_CALENDAR`."
|
|
294
296
|
)
|
|
295
297
|
|
|
296
|
-
@
|
|
298
|
+
@cache
|
|
297
299
|
def _get_start_date(self, year: int) -> Optional[date]:
|
|
298
300
|
"""Calculate the start date of that particular Thai Lunar Calendar Year.
|
|
299
301
|
|
|
@@ -320,6 +322,51 @@ class _ThaiLunisolar:
|
|
|
320
322
|
|
|
321
323
|
return _timedelta(_ThaiLunisolar.START_DATE, delta_days)
|
|
322
324
|
|
|
325
|
+
@cache
|
|
326
|
+
def buddhist_sabbath_dates(self, year: int) -> set[date]:
|
|
327
|
+
"""Return all Buddhist Sabbath (Uposatha) days in a given Gregorian year.
|
|
328
|
+
|
|
329
|
+
This function works independently of the calendar system in use,
|
|
330
|
+
whether `THAI_CALENDAR` or `KHMER_CALENDAR`.
|
|
331
|
+
|
|
332
|
+
Args:
|
|
333
|
+
year:
|
|
334
|
+
The Gregorian year.
|
|
335
|
+
|
|
336
|
+
Returns:
|
|
337
|
+
A set of `date` objects representing all Buddhist Sabbath days in the specified
|
|
338
|
+
Gregorian year. Returns an empty set if the year is outside the supported range.
|
|
339
|
+
"""
|
|
340
|
+
start_date = self._get_start_date(year)
|
|
341
|
+
if not start_date:
|
|
342
|
+
return set()
|
|
343
|
+
|
|
344
|
+
# Initializes Thai lunar month lengths.
|
|
345
|
+
months = [29, 30] * 6
|
|
346
|
+
if year in _ThaiLunisolar.ATHIKAMAT_YEARS_GREGORIAN:
|
|
347
|
+
months.insert(7, 30)
|
|
348
|
+
elif year in _ThaiLunisolar.ATHIKAWAN_YEARS_GREGORIAN:
|
|
349
|
+
months[6] += 1
|
|
350
|
+
# Includes first two months of the next Thai lunar year to ensure all Buddhist Sabbaths
|
|
351
|
+
# in the Gregorian year are captured.
|
|
352
|
+
months.extend([29, 30])
|
|
353
|
+
|
|
354
|
+
buddhist_sabbaths: set[date] = set()
|
|
355
|
+
day_cursor = start_date
|
|
356
|
+
for month_days in months:
|
|
357
|
+
if day_cursor.year > year:
|
|
358
|
+
break
|
|
359
|
+
# Buddhist Sabbaths: 8 Waxing, 15 Waxing, 8 Waning, 14/15 Waning.
|
|
360
|
+
for offset in (7, 14, 22, month_days - 1):
|
|
361
|
+
buddhist_sabbath = _timedelta(day_cursor, offset)
|
|
362
|
+
if buddhist_sabbath.year == year:
|
|
363
|
+
buddhist_sabbaths.add(buddhist_sabbath)
|
|
364
|
+
elif buddhist_sabbath.year > year:
|
|
365
|
+
break
|
|
366
|
+
day_cursor = _timedelta(day_cursor, month_days)
|
|
367
|
+
|
|
368
|
+
return buddhist_sabbaths
|
|
369
|
+
|
|
323
370
|
def makha_bucha_date(self, year: int, calendar=None) -> Optional[date]:
|
|
324
371
|
"""Calculate the estimated Gregorian date of Makha Bucha.
|
|
325
372
|
|
holidays/countries/__init__.py
CHANGED
|
@@ -20,6 +20,7 @@ from holidays.countries.american_samoa import AmericanSamoa, AS, ASM, HolidaysAS
|
|
|
20
20
|
from holidays.countries.andorra import Andorra, AD, AND
|
|
21
21
|
from holidays.countries.angola import Angola, AO, AGO
|
|
22
22
|
from holidays.countries.anguilla import Anguilla, AI, AIA
|
|
23
|
+
from holidays.countries.antarctica import Antarctica, AQ, ATA
|
|
23
24
|
from holidays.countries.antigua_and_barbuda import AntiguaAndBarbuda, AG, ATG
|
|
24
25
|
from holidays.countries.argentina import Argentina, AR, ARG
|
|
25
26
|
from holidays.countries.armenia import Armenia, AM, ARM
|
|
@@ -41,7 +42,9 @@ from holidays.countries.bolivia import Bolivia, BO, BOL
|
|
|
41
42
|
from holidays.countries.bonaire_sint_eustatius_and_saba import BonaireSintEustatiusAndSaba, BQ, BES
|
|
42
43
|
from holidays.countries.bosnia_and_herzegovina import BosniaAndHerzegovina, BA, BIH
|
|
43
44
|
from holidays.countries.botswana import Botswana, BW, BWA
|
|
45
|
+
from holidays.countries.bouvet_island import BouvetIsland, BV, BVT
|
|
44
46
|
from holidays.countries.brazil import Brazil, BR, BRA
|
|
47
|
+
from holidays.countries.british_indian_ocean_territory import BritishIndianOceanTerritory, IO, IOT
|
|
45
48
|
from holidays.countries.british_virgin_islands import BritishVirginIslands, VG, VGB
|
|
46
49
|
from holidays.countries.brunei import Brunei, BN, BRN
|
|
47
50
|
from holidays.countries.bulgaria import Bulgaria, BG, BLG
|
|
@@ -111,6 +114,11 @@ from holidays.countries.guinea import Guinea, GN, GIN
|
|
|
111
114
|
from holidays.countries.guinea_bissau import GuineaBissau, GW, GNB
|
|
112
115
|
from holidays.countries.guyana import Guyana, GY, GUY
|
|
113
116
|
from holidays.countries.haiti import Haiti, HT, HTI
|
|
117
|
+
from holidays.countries.heard_island_and_mcdonald_islands import (
|
|
118
|
+
HeardIslandAndMcDonaldIslands,
|
|
119
|
+
HM,
|
|
120
|
+
HMD,
|
|
121
|
+
)
|
|
114
122
|
from holidays.countries.honduras import Honduras, HN, HND
|
|
115
123
|
from holidays.countries.hongkong import HongKong, HK, HKG
|
|
116
124
|
from holidays.countries.hungary import Hungary, HU, HUN
|
|
@@ -163,6 +171,7 @@ from holidays.countries.montenegro import Montenegro, ME, MNE
|
|
|
163
171
|
from holidays.countries.montserrat import Montserrat, MS, MSR
|
|
164
172
|
from holidays.countries.morocco import Morocco, MA, MOR
|
|
165
173
|
from holidays.countries.mozambique import Mozambique, MZ, MOZ
|
|
174
|
+
from holidays.countries.myanmar import Myanmar, MM, MMR
|
|
166
175
|
from holidays.countries.namibia import Namibia, NA, NAM
|
|
167
176
|
from holidays.countries.nauru import Nauru, NR, NRU
|
|
168
177
|
from holidays.countries.nepal import Nepal, NP, NPL
|
|
@@ -174,6 +183,7 @@ from holidays.countries.niger import Niger, NE, NER
|
|
|
174
183
|
from holidays.countries.nigeria import Nigeria, NG, NGA
|
|
175
184
|
from holidays.countries.niue import Niue, NU, NIU
|
|
176
185
|
from holidays.countries.norfolk_island import NorfolkIsland, NF, NFK
|
|
186
|
+
from holidays.countries.north_korea import NorthKorea, KP, PRK
|
|
177
187
|
from holidays.countries.north_macedonia import NorthMacedonia, MK, MKD
|
|
178
188
|
from holidays.countries.northern_mariana_islands import NorthernMarianaIslands, MP, MNP, HolidaysMP
|
|
179
189
|
from holidays.countries.norway import Norway, NO, NOR
|
|
@@ -23,7 +23,7 @@ class Afghanistan(HolidayBase, InternationalHolidays, IslamicHolidays, PersianCa
|
|
|
23
23
|
|
|
24
24
|
References:
|
|
25
25
|
* <https://en.wikipedia.org/wiki/Public_holidays_in_Afghanistan>
|
|
26
|
-
* <https://web.archive.org/web/
|
|
26
|
+
* <https://web.archive.org/web/20250903162748/https://www.timeanddate.com/holidays/afghanistan>
|
|
27
27
|
* <https://en.wikipedia.org/wiki/Workweek_and_weekend>
|
|
28
28
|
"""
|
|
29
29
|
|
|
@@ -131,16 +131,17 @@ class AfghanistanIslamicHolidays(_CustomIslamicHolidays):
|
|
|
131
131
|
2021: (AUG, 19),
|
|
132
132
|
}
|
|
133
133
|
|
|
134
|
-
EID_AL_ADHA_DATES_CONFIRMED_YEARS = (2014,
|
|
134
|
+
EID_AL_ADHA_DATES_CONFIRMED_YEARS = (2014, 2025)
|
|
135
135
|
EID_AL_ADHA_DATES = {
|
|
136
136
|
2014: (OCT, 5),
|
|
137
137
|
2016: (SEP, 13),
|
|
138
138
|
2017: (SEP, 2),
|
|
139
139
|
2018: (AUG, 22),
|
|
140
140
|
2024: (JUN, 17),
|
|
141
|
+
2025: (JUN, 7),
|
|
141
142
|
}
|
|
142
143
|
|
|
143
|
-
EID_AL_FITR_DATES_CONFIRMED_YEARS = (2014,
|
|
144
|
+
EID_AL_FITR_DATES_CONFIRMED_YEARS = (2014, 2025)
|
|
144
145
|
EID_AL_FITR_DATES = {
|
|
145
146
|
2014: (JUL, 29),
|
|
146
147
|
2015: (JUL, 18),
|
|
@@ -150,7 +151,7 @@ class AfghanistanIslamicHolidays(_CustomIslamicHolidays):
|
|
|
150
151
|
2023: (APR, 22),
|
|
151
152
|
}
|
|
152
153
|
|
|
153
|
-
MAWLID_DATES_CONFIRMED_YEARS = (2014,
|
|
154
|
+
MAWLID_DATES_CONFIRMED_YEARS = (2014, 2025)
|
|
154
155
|
MAWLID_DATES = {
|
|
155
156
|
2014: (JAN, 14),
|
|
156
157
|
2015: ((JAN, 3), (DEC, 24)),
|
|
@@ -160,9 +161,10 @@ class AfghanistanIslamicHolidays(_CustomIslamicHolidays):
|
|
|
160
161
|
2019: (NOV, 10),
|
|
161
162
|
2021: (OCT, 19),
|
|
162
163
|
2024: (SEP, 16),
|
|
164
|
+
2025: (SEP, 5),
|
|
163
165
|
}
|
|
164
166
|
|
|
165
|
-
RAMADAN_BEGINNING_DATES_CONFIRMED_YEARS = (2014,
|
|
167
|
+
RAMADAN_BEGINNING_DATES_CONFIRMED_YEARS = (2014, 2025)
|
|
166
168
|
RAMADAN_BEGINNING_DATES = {
|
|
167
169
|
2014: (JUN, 29),
|
|
168
170
|
2016: (JUN, 7),
|
holidays/countries/algeria.py
CHANGED
|
@@ -10,27 +10,50 @@
|
|
|
10
10
|
# Website: https://github.com/vacanza/holidays
|
|
11
11
|
# License: MIT (see LICENSE file)
|
|
12
12
|
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
13
15
|
from gettext import gettext as tr
|
|
16
|
+
from typing import TYPE_CHECKING
|
|
14
17
|
|
|
15
18
|
from holidays.calendars.gregorian import THU, FRI, SAT, SUN
|
|
16
|
-
from holidays.
|
|
19
|
+
from holidays.constants import CHRISTIAN, HEBREW, PUBLIC
|
|
20
|
+
from holidays.groups import (
|
|
21
|
+
ChristianHolidays,
|
|
22
|
+
HebrewCalendarHolidays,
|
|
23
|
+
InternationalHolidays,
|
|
24
|
+
IslamicHolidays,
|
|
25
|
+
)
|
|
17
26
|
from holidays.holiday_base import HolidayBase
|
|
18
27
|
|
|
28
|
+
if TYPE_CHECKING:
|
|
29
|
+
from datetime import date
|
|
30
|
+
|
|
19
31
|
|
|
20
|
-
class Algeria(
|
|
32
|
+
class Algeria(
|
|
33
|
+
HolidayBase, ChristianHolidays, HebrewCalendarHolidays, InternationalHolidays, IslamicHolidays
|
|
34
|
+
):
|
|
21
35
|
"""Algeria holidays.
|
|
22
36
|
|
|
23
37
|
References:
|
|
24
38
|
* <https://en.wikipedia.org/wiki/Public_holidays_in_Algeria>
|
|
25
|
-
*
|
|
39
|
+
* [Loi n° 63-278 du 26 juillet 1963](https://web.archive.org/web/20250903142053/https://drive.google.com/file/d/1rWkxBEjs9aNkbiTTRXBET3Qo_3HQOJR9/view)
|
|
40
|
+
* [Ordonnance n° 68-419 du 26 juin 1968](https://web.archive.org/web/20250903142828/https://drive.google.com/file/d/1fMGyGVnunGkACWhm0tICANEZqao2pOV3/view)
|
|
41
|
+
* [Loi n° 05-06 du 17 Rabie El Aoeul 1426](https://web.archive.org/web/20250903143453/https://drive.google.com/file/d/1AXISrPGJzgDO8G3uB1TyICdtnOYW6ewm/view)
|
|
42
|
+
* [Loi n° 18-12 du 18 Chaoual 1439](https://web.archive.org/web/20250903141752/https://drive.google.com/file/d/1qxcrF3J-SUXmLdGZLVF0gdrN0aQWwykb/view)
|
|
43
|
+
* [Loi n° 23-10 du 8 Dhou El Hidja 1444](https://web.archive.org/web/20250903141052/https://drive.google.com/file/d/1hZJtxofzjFAphOX09dGGtvHxl6IN5aNz/view)
|
|
26
44
|
* <https://web.archive.org/web/20241231091630/https://www.thenationalnews.com/mena/2021/12/07/when-is-the-weekend-in-the-arab-world/>
|
|
45
|
+
* <https://web.archive.org/web/20250903160618/https://www.lemonde.fr/afrique/article/2018/01/12/en-algerie-le-nouvel-an-berbere-ferie-pour-la-premiere-fois_5241028_3212.html>
|
|
27
46
|
"""
|
|
28
47
|
|
|
29
48
|
country = "DZ"
|
|
30
49
|
default_language = "ar"
|
|
31
50
|
# %s (estimated).
|
|
32
51
|
estimated_label = tr("%s (المقدرة)")
|
|
52
|
+
# Loi n° 63-278 du 26 juillet 1963.
|
|
53
|
+
start_year = 1964
|
|
54
|
+
supported_categories = (CHRISTIAN, HEBREW, PUBLIC)
|
|
33
55
|
supported_languages = ("ar", "en_US", "fr")
|
|
56
|
+
weekend = {FRI, SAT}
|
|
34
57
|
|
|
35
58
|
def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
|
|
36
59
|
"""
|
|
@@ -39,24 +62,28 @@ class Algeria(HolidayBase, InternationalHolidays, IslamicHolidays):
|
|
|
39
62
|
Whether to add "estimated" label to Islamic holidays name
|
|
40
63
|
if holiday date is estimated.
|
|
41
64
|
"""
|
|
65
|
+
ChristianHolidays.__init__(self)
|
|
66
|
+
HebrewCalendarHolidays.__init__(self)
|
|
42
67
|
InternationalHolidays.__init__(self)
|
|
43
68
|
IslamicHolidays.__init__(self, show_estimated=islamic_show_estimated)
|
|
44
69
|
super().__init__(*args, **kwargs)
|
|
45
70
|
|
|
46
|
-
def
|
|
71
|
+
def _get_weekend(self, dt: date) -> set[int]:
|
|
47
72
|
# The resting days are Friday and Saturday since 2009.
|
|
48
73
|
# Previously, these were on Thursday and Friday as implemented in 1976.
|
|
49
|
-
if
|
|
50
|
-
|
|
51
|
-
elif
|
|
52
|
-
|
|
74
|
+
if dt.year >= 2009:
|
|
75
|
+
return {FRI, SAT}
|
|
76
|
+
elif dt.year >= 1976:
|
|
77
|
+
return {THU, FRI}
|
|
53
78
|
else:
|
|
54
|
-
|
|
79
|
+
return {SAT, SUN}
|
|
55
80
|
|
|
81
|
+
def _populate_public_holidays(self):
|
|
56
82
|
# New Year's Day.
|
|
57
83
|
self._add_new_years_day(tr("رأس السنة الميلادية"))
|
|
58
84
|
|
|
59
|
-
#
|
|
85
|
+
# First Celebrated in 2018.
|
|
86
|
+
# Reaffirmed via Loi n° 18-12 du 18 Chaoual 1439.
|
|
60
87
|
if self._year >= 2018:
|
|
61
88
|
# Amazigh New Year.
|
|
62
89
|
self._add_holiday_jan_12(tr("رأس السنة الأمازيغية"))
|
|
@@ -64,13 +91,17 @@ class Algeria(HolidayBase, InternationalHolidays, IslamicHolidays):
|
|
|
64
91
|
# Labor Day.
|
|
65
92
|
self._add_labor_day(tr("عيد العمال"))
|
|
66
93
|
|
|
67
|
-
|
|
94
|
+
# Name changed in Loi n° 05-06 du 17 Rabie El Aoeul 1426.
|
|
95
|
+
self._add_holiday_jul_5(
|
|
68
96
|
# Independence Day.
|
|
69
|
-
|
|
97
|
+
tr("عيد الاستقلال")
|
|
98
|
+
if self._year >= 2005
|
|
99
|
+
# Independence and National Liberation Front Day.
|
|
100
|
+
else tr("عيد الاستقلال وجبهة التحرير الوطني")
|
|
101
|
+
)
|
|
70
102
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
self._add_holiday_nov_1(tr("عيد الثورة"))
|
|
103
|
+
# Revolution Day.
|
|
104
|
+
self._add_holiday_nov_1(tr("عيد الثورة"))
|
|
74
105
|
|
|
75
106
|
# Islamic New Year.
|
|
76
107
|
self._add_islamic_new_year_day(tr("رأس السنة الهجرية"))
|
|
@@ -82,18 +113,52 @@ class Algeria(HolidayBase, InternationalHolidays, IslamicHolidays):
|
|
|
82
113
|
self._add_mawlid_day(tr("عيد المولد النبوي"))
|
|
83
114
|
|
|
84
115
|
# Eid al-Fitr.
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
self._add_eid_al_fitr_day_two(
|
|
116
|
+
name = tr("عيد الفطر")
|
|
117
|
+
self._add_eid_al_fitr_day(name)
|
|
118
|
+
self._add_eid_al_fitr_day_two(name)
|
|
119
|
+
# Added via Loi n° 23-10 du 8 Dhou El Hidja 1444.
|
|
88
120
|
if self._year >= 2024:
|
|
89
|
-
self._add_eid_al_fitr_day_three(
|
|
121
|
+
self._add_eid_al_fitr_day_three(name)
|
|
90
122
|
|
|
91
123
|
# Eid al-Adha.
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
if self._year >=
|
|
96
|
-
self.
|
|
124
|
+
name = tr("عيد الأضحى")
|
|
125
|
+
self._add_eid_al_adha_day(name)
|
|
126
|
+
# Added via Ordonnance n° 68-419 du 26 juin 1968.
|
|
127
|
+
if self._year >= 1969:
|
|
128
|
+
self._add_eid_al_adha_day_two(name)
|
|
129
|
+
# Added via Loi n° 23-10 du 8 Dhou El Hidja 1444.
|
|
130
|
+
if self._year >= 2023:
|
|
131
|
+
self._add_eid_al_adha_day_three(name)
|
|
132
|
+
|
|
133
|
+
def _populate_christian_holidays(self):
|
|
134
|
+
# As outlined in Loi n° 63-278 du 26 juillet 1963.
|
|
135
|
+
|
|
136
|
+
# Easter Monday.
|
|
137
|
+
self._add_easter_monday(tr("إثنين الفصح"))
|
|
138
|
+
|
|
139
|
+
# Ascension Day.
|
|
140
|
+
self._add_ascension_thursday(tr("عيد الصعود"))
|
|
141
|
+
|
|
142
|
+
# Whit Monday.
|
|
143
|
+
self._add_whit_monday(tr("إثنين العنصرة"))
|
|
144
|
+
|
|
145
|
+
# Assumption Day.
|
|
146
|
+
self._add_assumption_of_mary_day(tr("عيد انتقال السيدة العذراء"))
|
|
147
|
+
|
|
148
|
+
# Christmas Day.
|
|
149
|
+
self._add_christmas_day(tr("عيد الميلاد"))
|
|
150
|
+
|
|
151
|
+
def _populate_hebrew_holidays(self):
|
|
152
|
+
# As outlined in Loi n° 63-278 du 26 juillet 1963.
|
|
153
|
+
|
|
154
|
+
# Rosh Hashanah.
|
|
155
|
+
self._add_rosh_hashanah(tr("رأس السنة العبرية"))
|
|
156
|
+
|
|
157
|
+
# Yom Kippur.
|
|
158
|
+
self._add_yom_kippur(tr("يوم الغفران"))
|
|
159
|
+
|
|
160
|
+
# Pesach.
|
|
161
|
+
self._add_passover(tr("عيد الفصح اليهودي"))
|
|
97
162
|
|
|
98
163
|
|
|
99
164
|
class DZ(Algeria):
|