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.
Files changed (98) hide show
  1. holidays/calendars/__init__.py +1 -0
  2. holidays/calendars/burmese.py +319 -0
  3. holidays/calendars/hebrew.py +2 -2
  4. holidays/calendars/thai.py +49 -2
  5. holidays/countries/__init__.py +10 -0
  6. holidays/countries/afghanistan.py +7 -5
  7. holidays/countries/algeria.py +89 -24
  8. holidays/countries/antarctica.py +58 -0
  9. holidays/countries/bouvet_island.py +31 -0
  10. holidays/countries/brazil.py +1 -1
  11. holidays/countries/british_indian_ocean_territory.py +31 -0
  12. holidays/countries/bulgaria.py +6 -1
  13. holidays/countries/chile.py +9 -8
  14. holidays/countries/cuba.py +3 -4
  15. holidays/countries/djibouti.py +1 -1
  16. holidays/countries/heard_island_and_mcdonald_islands.py +31 -0
  17. holidays/countries/hungary.py +4 -5
  18. holidays/countries/india.py +6 -0
  19. holidays/countries/japan.py +22 -18
  20. holidays/countries/jordan.py +6 -3
  21. holidays/countries/kuwait.py +6 -3
  22. holidays/countries/malaysia.py +14 -3
  23. holidays/countries/myanmar.py +195 -0
  24. holidays/countries/north_korea.py +161 -0
  25. holidays/countries/norway.py +23 -8
  26. holidays/countries/oman.py +6 -2
  27. holidays/countries/paraguay.py +70 -23
  28. holidays/countries/portugal.py +5 -6
  29. holidays/countries/qatar.py +5 -2
  30. holidays/countries/rwanda.py +6 -1
  31. holidays/countries/saudi_arabia.py +6 -5
  32. holidays/countries/serbia.py +5 -0
  33. holidays/countries/south_africa.py +96 -53
  34. holidays/countries/south_korea.py +6 -1
  35. holidays/countries/spain.py +4 -4
  36. holidays/countries/sudan.py +6 -3
  37. holidays/countries/switzerland.py +169 -3
  38. holidays/countries/taiwan.py +22 -2
  39. holidays/countries/tanzania.py +6 -1
  40. holidays/countries/thailand.py +21 -0
  41. holidays/countries/tonga.py +6 -1
  42. holidays/countries/trinidad_and_tobago.py +6 -1
  43. holidays/countries/united_arab_emirates.py +9 -2
  44. holidays/countries/united_states.py +16 -0
  45. holidays/countries/uruguay.py +6 -1
  46. holidays/countries/vietnam.py +6 -1
  47. holidays/countries/yemen.py +6 -3
  48. holidays/groups/__init__.py +1 -0
  49. holidays/groups/balinese_saka.py +1 -1
  50. holidays/groups/buddhist.py +1 -1
  51. holidays/groups/burmese.py +273 -0
  52. holidays/groups/chinese.py +25 -0
  53. holidays/groups/custom.py +8 -2
  54. holidays/groups/eastern.py +24 -0
  55. holidays/groups/hebrew.py +16 -14
  56. holidays/groups/hindu.py +15 -13
  57. holidays/groups/islamic.py +43 -48
  58. holidays/groups/mongolian.py +1 -1
  59. holidays/groups/sinhala.py +4 -9
  60. holidays/groups/tibetan.py +3 -4
  61. holidays/holiday_base.py +5 -4
  62. holidays/ical.py +6 -4
  63. holidays/locale/ar/LC_MESSAGES/DZ.mo +0 -0
  64. holidays/locale/ca/LC_MESSAGES/ES.mo +0 -0
  65. holidays/locale/en_IN/LC_MESSAGES/IN.mo +0 -0
  66. holidays/locale/en_US/LC_MESSAGES/BR.mo +0 -0
  67. holidays/locale/en_US/LC_MESSAGES/DZ.mo +0 -0
  68. holidays/locale/en_US/LC_MESSAGES/ES.mo +0 -0
  69. holidays/locale/en_US/LC_MESSAGES/IN.mo +0 -0
  70. holidays/locale/en_US/LC_MESSAGES/JP.mo +0 -0
  71. holidays/locale/en_US/LC_MESSAGES/KP.mo +0 -0
  72. holidays/locale/en_US/LC_MESSAGES/MM.mo +0 -0
  73. holidays/locale/en_US/LC_MESSAGES/PY.mo +0 -0
  74. holidays/locale/en_US/LC_MESSAGES/US.mo +0 -0
  75. holidays/locale/es/LC_MESSAGES/ES.mo +0 -0
  76. holidays/locale/es/LC_MESSAGES/PY.mo +0 -0
  77. holidays/locale/fr/LC_MESSAGES/DZ.mo +0 -0
  78. holidays/locale/hi/LC_MESSAGES/IN.mo +0 -0
  79. holidays/locale/ja/LC_MESSAGES/JP.mo +0 -0
  80. holidays/locale/ko_KP/LC_MESSAGES/KP.mo +0 -0
  81. holidays/locale/my/LC_MESSAGES/MM.mo +0 -0
  82. holidays/locale/pt_BR/LC_MESSAGES/BR.mo +0 -0
  83. holidays/locale/th/LC_MESSAGES/JP.mo +0 -0
  84. holidays/locale/th/LC_MESSAGES/MM.mo +0 -0
  85. holidays/locale/th/LC_MESSAGES/US.mo +0 -0
  86. holidays/locale/uk/LC_MESSAGES/BR.mo +0 -0
  87. holidays/locale/uk/LC_MESSAGES/ES.mo +0 -0
  88. holidays/locale/uk/LC_MESSAGES/PY.mo +0 -0
  89. holidays/no_holiday_base.py +21 -0
  90. holidays/registry.py +6 -0
  91. holidays/utils.py +5 -5
  92. holidays/version.py +1 -1
  93. {holidays-0.81.dist-info → holidays-0.82.dist-info}/METADATA +47 -5
  94. {holidays-0.81.dist-info → holidays-0.82.dist-info}/RECORD +98 -83
  95. {holidays-0.81.dist-info → holidays-0.82.dist-info}/licenses/CONTRIBUTORS +2 -0
  96. {holidays-0.81.dist-info → holidays-0.82.dist-info}/WHEEL +0 -0
  97. {holidays-0.81.dist-info → holidays-0.82.dist-info}/licenses/LICENSE +0 -0
  98. {holidays-0.81.dist-info → holidays-0.82.dist-info}/top_level.txt +0 -0
@@ -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)
@@ -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[Optional[date]]:
1606
- return {self._get_holiday(HANUKKAH, y) for y in (year - 1, year)}
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)
@@ -11,7 +11,7 @@
11
11
  # License: MIT (see LICENSE file)
12
12
 
13
13
  from datetime import date
14
- from functools import lru_cache
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
- @lru_cache
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
 
@@ -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/20250408032244/https://www.timeanddate.com/holidays/afghanistan>
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, 2024)
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, 2024)
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, 2024)
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, 2024)
167
+ RAMADAN_BEGINNING_DATES_CONFIRMED_YEARS = (2014, 2025)
166
168
  RAMADAN_BEGINNING_DATES = {
167
169
  2014: (JUN, 29),
168
170
  2016: (JUN, 7),
@@ -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.groups import InternationalHolidays, IslamicHolidays
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(HolidayBase, InternationalHolidays, IslamicHolidays):
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
- * <https://web.archive.org/web/20250427180223/https://www.horizons.dz/english/archives/amp/12021>
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 _populate_public_holidays(self):
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 self._year >= 2009:
50
- self.weekend = {FRI, SAT}
51
- elif self._year >= 1976:
52
- self.weekend = {THU, FRI}
74
+ if dt.year >= 2009:
75
+ return {FRI, SAT}
76
+ elif dt.year >= 1976:
77
+ return {THU, FRI}
53
78
  else:
54
- self.weekend = {SAT, SUN}
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
- # In January 2018, Algeria declared Yennayer a national holiday.
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
- if self._year >= 1962:
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
- self._add_holiday_jul_5(tr("عيد الإستقلال"))
97
+ tr("عيد الاستقلال")
98
+ if self._year >= 2005
99
+ # Independence and National Liberation Front Day.
100
+ else tr("عيد الاستقلال وجبهة التحرير الوطني")
101
+ )
70
102
 
71
- if self._year >= 1963:
72
- # Revolution Day.
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
- self._add_eid_al_fitr_day(tr("عيد الفطر"))
86
- # Eid al-Fitr Holiday.
87
- self._add_eid_al_fitr_day_two(tr("عطلة عيد الفطر"))
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(tr("عطلة عيد الفطر"))
121
+ self._add_eid_al_fitr_day_three(name)
90
122
 
91
123
  # Eid al-Adha.
92
- self._add_eid_al_adha_day(tr("عيد الأضحى"))
93
- # Eid al-Adha Holiday.
94
- self._add_eid_al_adha_day_two(tr("عطلة عيد الأضحى"))
95
- if self._year >= 2023:
96
- self._add_eid_al_adha_day_three(tr("عطلة عيد الأضحى"))
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):