holidays 0.48__py3-none-any.whl → 0.49__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 (46) hide show
  1. holidays/__init__.py +1 -1
  2. holidays/calendars/gregorian.py +22 -7
  3. holidays/calendars/persian.py +3 -2
  4. holidays/calendars/thai.py +24 -20
  5. holidays/countries/angola.py +2 -2
  6. holidays/countries/aruba.py +2 -3
  7. holidays/countries/cambodia.py +7 -8
  8. holidays/countries/canada.py +2 -1
  9. holidays/countries/curacao.py +3 -4
  10. holidays/countries/finland.py +2 -2
  11. holidays/countries/hongkong.py +398 -133
  12. holidays/countries/israel.py +13 -13
  13. holidays/countries/italy.py +2 -4
  14. holidays/countries/japan.py +17 -6
  15. holidays/countries/jersey.py +2 -2
  16. holidays/countries/laos.py +7 -23
  17. holidays/countries/madagascar.py +2 -3
  18. holidays/countries/malaysia.py +545 -235
  19. holidays/countries/netherlands.py +2 -3
  20. holidays/countries/new_zealand.py +5 -5
  21. holidays/countries/saudi_arabia.py +2 -3
  22. holidays/countries/south_korea.py +17 -4
  23. holidays/countries/sweden.py +2 -3
  24. holidays/countries/switzerland.py +2 -3
  25. holidays/financial/__init__.py +1 -0
  26. holidays/financial/ice_futures_europe.py +47 -0
  27. holidays/financial/ny_stock_exchange.py +17 -4
  28. holidays/groups/chinese.py +2 -3
  29. holidays/groups/christian.py +18 -19
  30. holidays/groups/islamic.py +2 -2
  31. holidays/groups/persian.py +2 -2
  32. holidays/helpers.py +9 -3
  33. holidays/holiday_base.py +18 -15
  34. holidays/locale/en_US/LC_MESSAGES/MY.mo +0 -0
  35. holidays/locale/en_US/LC_MESSAGES/MY.po +250 -0
  36. holidays/locale/ms_MY/LC_MESSAGES/MY.mo +0 -0
  37. holidays/locale/ms_MY/LC_MESSAGES/MY.po +250 -0
  38. holidays/mixins.py +31 -0
  39. holidays/observed_holiday_base.py +25 -13
  40. holidays/registry.py +1 -0
  41. {holidays-0.48.dist-info → holidays-0.49.dist-info}/METADATA +7 -4
  42. {holidays-0.48.dist-info → holidays-0.49.dist-info}/RECORD +46 -40
  43. {holidays-0.48.dist-info → holidays-0.49.dist-info}/AUTHORS +0 -0
  44. {holidays-0.48.dist-info → holidays-0.49.dist-info}/LICENSE +0 -0
  45. {holidays-0.48.dist-info → holidays-0.49.dist-info}/WHEEL +0 -0
  46. {holidays-0.48.dist-info → holidays-0.49.dist-info}/top_level.txt +0 -0
@@ -10,6 +10,8 @@
10
10
  # Website: https://github.com/vacanza/python-holidays
11
11
  # License: MIT (see LICENSE file)
12
12
 
13
+ from gettext import gettext as tr
14
+
13
15
  from holidays.calendars import (
14
16
  _CustomBuddhistHolidays,
15
17
  _CustomChineseHolidays,
@@ -60,8 +62,32 @@ class Malaysia(
60
62
  StaticHolidays,
61
63
  ):
62
64
  country = "MY"
63
- observed_label = "%s (in lieu)"
65
+ default_language = "ms_MY"
66
+ # %s (estimated).
67
+ estimated_label = tr("%s (anggaran)")
68
+ # %s (in lieu).
69
+ observed_label = tr("Cuti %s")
70
+ # %s (observed, estimated).
71
+ observed_estimated_label = tr("Cuti %s (anggaran)")
64
72
  subdivisions = (
73
+ "01",
74
+ "02",
75
+ "03",
76
+ "04",
77
+ "05",
78
+ "06",
79
+ "07",
80
+ "08",
81
+ "09",
82
+ "10",
83
+ "11",
84
+ "12",
85
+ "13",
86
+ "14",
87
+ "15",
88
+ "16",
89
+ )
90
+ _deprecated_subdivisions = (
65
91
  "JHR",
66
92
  "KDH",
67
93
  "KTN",
@@ -79,53 +105,41 @@ class Malaysia(
79
105
  "SWK",
80
106
  "TRG",
81
107
  )
108
+ subdivisions_aliases = {
109
+ "Johor": "01",
110
+ "Kedah": "02",
111
+ "Kelantan": "03",
112
+ "Melaka": "04",
113
+ "Negeri Sembilan": "05",
114
+ "Pahang": "06",
115
+ "Pulau Pinang": "07",
116
+ "Perak": "08",
117
+ "Perlis": "09",
118
+ "Selangor": "10",
119
+ "Terengganu": "11",
120
+ "Sabah": "12",
121
+ "Sarawak": "13",
122
+ "WP Kuala Lumpur": "14",
123
+ "WP Labuan": "15",
124
+ "WP Putrajaya": "16",
125
+ }
126
+ supported_languages = ("en_US", "ms_MY")
82
127
 
83
128
  def __init__(self, *args, **kwargs):
84
129
  """
85
- An subclass of :py:class:`HolidayBase` representing public holidays in
86
- Malaysia.
87
-
88
- If ``subdiv`` for a state is not supplied, only nationwide holidays are
89
- returned. The following ``subdiv`` state codes are used (ISO 3166-2
90
- subdivision codes are not yet supported):
91
-
92
- - JHR: Johor
93
- - KDH: Kedah
94
- - KTN: Kelantan
95
- - MLK: Melaka
96
- - NSN: Negeri Sembilan
97
- - PHG: Pahang
98
- - PRK: Perak
99
- - PLS: Perlis
100
- - PNG: Pulau Pinang
101
- - SBH: Sabah
102
- - SWK: Sarawak
103
- - SGR: Selangor
104
- - TRG: Terengganu
105
- - KUL: FT Kuala Lumpur
106
- - LBN: FT Labuan
107
- - PJY: FT Putrajaya
108
-
109
- Limitations:
110
-
111
- - Prior to 2021: holidays are not accurate.
112
- - 2027 and later: Thaipusam dates are are estimated, and so denoted.
113
-
114
- Section 3 of Malaysian Holidays Act:
130
+ References:
131
+ - `Holidays Act 1951 <https://www.kabinet.gov.my/bkpp/pdf/akta_warta/1951_12_31_act369.pdf>`_ # noqa: E501
132
+ - `Holidays Ordinance (Sabah Cap. 56) <https://sagc.sabah.gov.my/sites/default/files/law/HolidaysOrdinance.pdf>`_ # noqa: E501
133
+ - `Public Holidays Ordinance (Sarawak Cap. 8) <https://www.kabinet.gov.my/bkpp/pdf/akta_warta/sarawak_public_holidays_ord_chapter8.pdf>`_ # noqa: E501
134
+ - `Wikipedia <https://en.wikipedia.org/wiki/Public_holidays_in_Malaysia>`_
135
+ - https://www.nst.com.my/news/nation/2020/03/571660/agongs-birthday-moved-june-6-june-8 # noqa: E501
136
+ - https://www.nst.com.my/news/nation/2024/02/1014012/melaka-cm-suggests-declaring-feb-20-federal-public-holiday-mark # noqa: E501
137
+
138
+ Section 3 of Holidays Act 1951:
115
139
  "If any day specified in the Schedule falls on Sunday then the day following shall be
116
140
  a public holiday and if such day is already a public holiday, then the day following
117
141
  shall be a public holiday".
118
- In Johor and Kedah it's Friday -> Sunday,
119
- in Kelantan and Terengganu it's Saturday -> Sunday
120
-
121
- Reference: `Wikipedia
122
- <https://en.wikipedia.org/wiki/Public_holidays_in_Malaysia>`__
123
-
124
- Country created by: `Eden <https://github.com/jusce17>`__
125
-
126
- Country maintained by: `Mike Borsetti <https://github.com/mborsetti>`__
127
-
128
- See parameters and usage in :py:class:`HolidayBase`.
142
+ In Johor and Kedah it's Friday to Sunday, in Kelantan and Terengganu - Saturday to Sunday.
129
143
  """
130
144
  BuddhistCalendarHolidays.__init__(self, cls=MalaysiaBuddhistHolidays, show_estimated=True)
131
145
  ChineseCalendarHolidays.__init__(self, cls=MalaysiaChineseHolidays, show_estimated=True)
@@ -136,259 +150,430 @@ class Malaysia(
136
150
  StaticHolidays.__init__(self, cls=MalaysiaStaticHolidays)
137
151
  kwargs.setdefault("observed_rule", SUN_TO_NEXT_WORKDAY)
138
152
  super().__init__(*args, **kwargs)
153
+ self.dts_observed = set()
139
154
 
140
155
  def _populate_public_holidays(self):
141
- dts_observed = set()
156
+ if self._year <= 1951:
157
+ return None
142
158
 
143
- # Chinese New Year (one day in the States of Kelantan and Terengganu,
144
- # two days in the other States).
145
- dts_observed.add(self._add_chinese_new_years_day("Chinese New Year"))
146
- # The second day of Chinese New Year is not a federal holiday in
147
- # Kelantan and Terengganu. However, it is gazetted as a state holiday
148
- # in both states, effectively making it a nationwide holiday.
149
- dts_observed.add(self._add_chinese_new_years_day_two("Chinese New Year Holiday"))
159
+ # This must be done for every `_populate_public_holidays()` call.
160
+ # Otherwise, 2006/2007 Eid al-Adha observance would be miscalculated.
161
+ self.dts_observed = set()
150
162
 
151
- # Vesak Day.
152
- dts_observed.add(self._add_vesak_may("Vesak Day"))
163
+ # Chinese New Year.
164
+ self.dts_observed.add(self._add_chinese_new_years_day(tr("Tahun Baharu Cina")))
153
165
 
154
- # Labour Day.
155
- dts_observed.add(self._add_labor_day("Labour Day"))
166
+ self.dts_observed.add(
167
+ # Chinese New Year (Second Day).
168
+ self._add_chinese_new_years_day_two(tr("Tahun Baharu Cina (Hari Kedua)"))
169
+ )
156
170
 
157
- # Birthday of [His Majesty] the Yang di-Pertuan Agong.
158
- name = "Birthday of SPB Yang di-Pertuan Agong"
159
- if self._year <= 2017:
160
- dts_observed.add(self._add_holiday_1st_sat_of_jun(name))
161
- elif self._year == 2018:
162
- dts_observed.add(self._add_holiday_sep_9(name))
171
+ # Vesak Day.
172
+ self.dts_observed.add(self._add_vesak_may(tr("Hari Wesak")))
173
+
174
+ if self._year >= 1973:
175
+ # Labor Day.
176
+ self.dts_observed.add(self._add_labor_day(tr("Hari Pekerja")))
177
+
178
+ # Birthday of HM Yang di-Pertuan Agong.
179
+ name = tr("Hari Keputeraan Rasmi Seri Paduka Baginda Yang di-Pertuan Agong")
180
+ if self._year <= 2016:
181
+ self.dts_observed.add(self._add_holiday_1st_sat_of_jun(name))
182
+ elif self._year <= 2019:
183
+ self.dts_observed.add(self._add_holiday_sep_9(name))
163
184
  elif self._year == 2020:
164
- # https://www.nst.com.my/news/nation/2020/03/571660/agongs-birthday-moved-june-6-june-8
165
- dts_observed.add(self._add_holiday_jun_8(name))
185
+ self.dts_observed.add(self._add_holiday_jun_8(name))
166
186
  else:
167
- dts_observed.add(self._add_holiday_1st_mon_of_jun(name))
187
+ self.dts_observed.add(self._add_holiday_1st_mon_of_jun(name))
168
188
 
169
- # Hari Kebangsaan or National Day.
170
- dts_observed.add(self._add_holiday_aug_31("National Day"))
189
+ # National Day.
190
+ self.dts_observed.add(self._add_holiday_aug_31(tr("Hari Kebangsaan")))
171
191
 
172
- # Malaysia Day.
173
192
  if self._year >= 2010:
174
- dts_observed.add(self._add_holiday_sep_16("Malaysia Day"))
193
+ # Malaysia Day.
194
+ self.dts_observed.add(self._add_holiday_sep_16(tr("Hari Malaysia")))
195
+
196
+ # Christmas Day.
197
+ self.dts_observed.add(self._add_christmas_day(tr("Hari Krismas")))
198
+
199
+ if self._year >= 1995:
200
+ # Islamic New Year.
201
+ self._add_islamic_new_year_day(tr("Awal Muharam"))
202
+
203
+ # Prophet Muhammad's Birthday.
204
+ self.dts_observed.update(self._add_mawlid_day(tr("Hari Keputeraan Nabi Muhammad S.A.W.")))
205
+
206
+ # Eid al-Fitr.
207
+ self.dts_observed.update(self._add_eid_al_fitr_day(tr("Hari Raya Puasa")))
208
+
209
+ # Eid al-Fitr (Second Day).
210
+ self.dts_observed.update(self._add_eid_al_fitr_day_two(tr("Hari Raya Puasa (Hari Kedua)")))
211
+
212
+ # Eid al-Adha.
213
+ self.dts_observed.update(self._add_eid_al_adha_day(tr("Hari Raya Qurban")))
214
+
215
+ def _populate_subdiv_holidays(self):
216
+ if self._year <= 1951:
217
+ return None
218
+
219
+ deprecated_mapping = {
220
+ "JHR": "01",
221
+ "KDH": "02",
222
+ "KTN": "03",
223
+ "KUL": "14",
224
+ "LBN": "15",
225
+ "MLK": "04",
226
+ "NSN": "05",
227
+ "PHG": "06",
228
+ "PJY": "16",
229
+ "PLS": "09",
230
+ "PNG": "07",
231
+ "PRK": "08",
232
+ "SBH": "12",
233
+ "SGR": "10",
234
+ "SWK": "13",
235
+ "TRG": "11",
236
+ }
237
+ self.subdiv = deprecated_mapping.get(self.subdiv, self.subdiv)
238
+
239
+ if self.subdiv and self.subdiv not in {"13", "15"}:
240
+ # Deepavali.
241
+ self.dts_observed.add(self._add_diwali(tr("Hari Deepavali")))
242
+
243
+ super()._populate_subdiv_holidays()
244
+
245
+ if self.subdiv in {"01", "02"}:
246
+ self._observed_rule = FRI_TO_NEXT_WORKDAY
247
+ self.weekend = {FRI, SAT}
248
+ elif self.subdiv in {"03", "11"}:
249
+ self._observed_rule = SAT_TO_NEXT_WORKDAY
250
+ self.weekend = {FRI, SAT}
175
251
 
176
- # Deepavali (Diwali).
177
- if self.subdiv != "SWK":
178
- dts_observed.add(self._add_diwali("Deepavali"))
252
+ if self.observed:
253
+ self._populate_observed(self.dts_observed)
179
254
 
180
- # Christmas day.
181
- dts_observed.add(self._add_christmas_day("Christmas Day"))
255
+ def _populate_subdiv_01_public_holidays(self):
256
+ # Thaipusam.
257
+ self.dts_observed.add(self._add_thaipusam(tr("Hari Thaipusam")))
182
258
 
183
- # Birthday of the Prophet Muhammad (s.a.w.).
184
- # a.k.a. Hari Keputeraan Nabi Muhammad (Sabah Act)
185
- dts_observed.update(
186
- self._add_mawlid_day("Maulidur Rasul (Birthday of the Prophet Muhammad)")
187
- )
259
+ if self._year >= 2015:
260
+ # Birthday of the Sultan of Johor.
261
+ self._add_holiday_mar_23(tr("Hari Keputeraan Sultan Johor"))
188
262
 
189
- # Hari Raya Puasa (2 days).
190
- # aka Eid al-Fitr;
191
- # exact date of observance is announced yearly
192
- name = "Hari Raya Puasa"
193
- dts_observed.update(self._add_eid_al_fitr_day(name))
194
- dts_observed.update(self._add_eid_al_fitr_day_two(f"Second day of {name}"))
263
+ if self._year >= 2011:
264
+ # The Sultan of Johor Hol.
265
+ self._add_hari_hol_johor(tr("Hari Hol Almarhum Sultan Iskandar"))
195
266
 
196
- # Arafat Day.
197
- if self.subdiv == "TRG":
198
- dts_observed.update(self._add_arafah_day("Arafat Day"))
199
-
200
- # Hari Raya Haji.
201
- name = "Hari Raya Haji"
202
- dts_observed.update(self._add_eid_al_adha_day(name))
203
- if self.subdiv in {"KDH", "KTN", "PLS", "TRG"}:
204
- dts_observed.update(self._add_eid_al_adha_day_two(name))
205
-
206
- # New Year's Day
207
- if self.subdiv in {
208
- "KUL",
209
- "LBN",
210
- "MLK",
211
- "NSN",
212
- "PHG",
213
- "PJY",
214
- "PNG",
215
- "PRK",
216
- "SBH",
217
- "SGR",
218
- "SWK",
219
- }:
220
- dts_observed.add(self._add_new_years_day("New Year's Day"))
221
-
222
- # Isra and Mi'raj.
223
- if self.subdiv in {"KDH", "NSN", "PLS"} or (self.subdiv == "TRG" and self._year >= 2020):
224
- dts_observed.update(self._add_isra_and_miraj_day("Isra and Mi'raj"))
267
+ # Beginning of Ramadan.
268
+ self.dts_observed.update(self._add_ramadan_beginning_day(tr("Awal Ramadan")))
269
+
270
+ def _populate_subdiv_02_public_holidays(self):
271
+ if self._year >= 2022:
272
+ # Thaipusam.
273
+ self.dts_observed.add(self._add_thaipusam(tr("Hari Thaipusam")))
274
+
275
+ if self._year >= 2018:
276
+ # Birthday of The Sultan of Kedah.
277
+ name = tr("Hari Keputeraan Sultan Kedah")
278
+ if self._year == 2024:
279
+ self._add_holiday_jun_30(name)
280
+ else:
281
+ self._add_holiday_3rd_sun_of_jun(name)
282
+
283
+ # Isra' and Mi'raj.
284
+ self.dts_observed.update(self._add_isra_and_miraj_day(tr("Israk dan Mikraj")))
225
285
 
226
286
  # Beginning of Ramadan.
227
- if self.subdiv in {"JHR", "KDH", "MLK"}:
228
- dts_observed.update(self._add_ramadan_beginning_day("Beginning of Ramadan"))
287
+ self.dts_observed.update(self._add_ramadan_beginning_day(tr("Awal Ramadan")))
288
+
289
+ # Eid al-Adha (Second Day).
290
+ self.dts_observed.update(
291
+ self._add_eid_al_adha_day_two(tr("Hari Raya Qurban (Hari Kedua)"))
292
+ )
293
+
294
+ def _populate_subdiv_03_public_holidays(self):
295
+ if self._year >= 2010:
296
+ # Birthday of the Sultan of Kelantan.
297
+ name = tr("Hari Keputeraan Sultan Kelantan")
298
+ if self._year >= 2023:
299
+ self._add_holiday_sep_29(name)
300
+ self._add_holiday_sep_30(name)
301
+ elif self._year >= 2012:
302
+ self._add_holiday_nov_11(name)
303
+ self._add_holiday_nov_12(name)
304
+ else:
305
+ self._add_holiday_mar_30(name)
306
+ self._add_holiday_mar_31(name)
229
307
 
230
308
  # Nuzul Al-Quran Day.
231
- if self.subdiv in {"KTN", "KUL", "LBN", "PHG", "PJY", "PLS", "PNG", "PRK", "SGR", "TRG"}:
232
- dts_observed.update(self._add_nuzul_al_quran_day("Nuzul Al-Quran Day"))
309
+ self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran")))
233
310
 
234
- # Thaipusam.
235
- if self.subdiv in {"JHR", "KUL", "NSN", "PJY", "PNG", "PRK", "SGR"}:
236
- dts_observed.add(self._add_thaipusam("Thaipusam"))
311
+ if self._year >= 2023:
312
+ # Arafat Day.
313
+ self.dts_observed.update(self._add_arafah_day(tr("Hari Arafah")))
237
314
 
238
- # Federal Territory Day.
239
- if self.subdiv in {"KUL", "LBN", "PJY"} and self._year >= 1974:
240
- dts_observed.add(self._add_holiday_feb_1("Federal Territory Day"))
315
+ # Eid al-Adha (Second Day).
316
+ self.dts_observed.update(
317
+ self._add_eid_al_adha_day_two(tr("Hari Raya Qurban (Hari Kedua)"))
318
+ )
241
319
 
242
- # State holidays (single state)
320
+ def _populate_subdiv_04_public_holidays(self):
321
+ # New Year's Day.
322
+ self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu")))
243
323
 
244
- if self.subdiv == "MLK":
245
- if self._year >= 1989:
246
- dts_observed.add(
247
- self._add_holiday_apr_15("Declaration of Malacca as a Historical City")
324
+ if self._year >= 2024:
325
+ self.dts_observed.add(
326
+ # Declaration of Independence Day.
327
+ self._add_holiday_feb_20(tr("Hari Pengisytiharan Tarikh Kemerdekaan"))
328
+ )
329
+ elif self._year >= 1989:
330
+ self.dts_observed.add(
331
+ self._add_holiday_apr_15(
332
+ # Declaration of Malacca as a Historical City.
333
+ tr("Hari Perisytiharan Melaka Sebagai Bandaraya Bersejarah")
248
334
  )
335
+ )
249
336
 
250
- name = "Birthday of the Governor of Malacca"
251
- dts_observed.add(
252
- self._add_holiday_aug_24(name)
253
- if self._year >= 2020
254
- else self._add_holiday_2nd_fri_of_oct(name)
337
+ # Birthday of the Governor of Malacca.
338
+ name = tr("Hari Jadi Yang di-Pertua Negeri Melaka")
339
+ self.dts_observed.add(
340
+ self._add_holiday_aug_24(name)
341
+ if self._year >= 2020
342
+ else self._add_holiday_2nd_fri_of_oct(name)
343
+ )
344
+
345
+ # Beginning of Ramadan.
346
+ self.dts_observed.update(self._add_ramadan_beginning_day(tr("Awal Ramadan")))
347
+
348
+ def _populate_subdiv_05_public_holidays(self):
349
+ # New Year's Day.
350
+ self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu")))
351
+
352
+ # Thaipusam.
353
+ self.dts_observed.add(self._add_thaipusam(tr("Hari Thaipusam")))
354
+
355
+ if self._year >= 2009:
356
+ self.dts_observed.add(
357
+ self._add_holiday_jan_14(
358
+ # Birthday of the Sultan of Negeri Sembilan.
359
+ tr("Hari Keputeraan Yang di-Pertuan Besar Negeri Sembilan")
360
+ )
255
361
  )
256
362
 
257
- elif self.subdiv == "NSN" and self._year >= 2009:
258
- dts_observed.add(self._add_holiday_jan_14("Birthday of the Sultan of Negeri Sembilan"))
363
+ # Isra' and Mi'raj.
364
+ self.dts_observed.update(self._add_isra_and_miraj_day(tr("Israk dan Mikraj")))
365
+
366
+ def _populate_subdiv_06_public_holidays(self):
367
+ # New Year's Day.
368
+ self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu")))
259
369
 
260
- elif self.subdiv == "PHG" and self._year >= 1975:
261
- name = "Hari Hol of Pahang"
262
- dts_observed.add(
370
+ if self._year >= 1975:
371
+ # The Sultan of Pahang Hol.
372
+ name = tr("Hari Hol Sultan Pahang")
373
+ self.dts_observed.add(
263
374
  self._add_holiday_may_22(name)
264
- if self._year >= 2021
375
+ if self._year >= 2020
265
376
  else self._add_holiday_may_7(name)
266
377
  )
267
378
 
268
- name = "Birthday of the Sultan of Pahang"
269
- dts_observed.add(
379
+ # Birthday of the Sultan of Pahang.
380
+ name = tr("Hari Keputeraan Sultan Pahang")
381
+ self.dts_observed.add(
270
382
  self._add_holiday_jul_30(name)
271
383
  if self._year >= 2019
272
384
  else self._add_holiday_oct_24(name)
273
385
  )
274
386
 
275
- elif self.subdiv == "PNG":
276
- if self._year >= 2009:
277
- dts_observed.add(self._add_holiday_jul_7("George Town Heritage Day"))
387
+ # Nuzul Al-Quran Day.
388
+ self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran")))
278
389
 
279
- dts_observed.add(
280
- self._add_holiday_2nd_sat_of_jul("Birthday of the Governor of Penang")
390
+ def _populate_subdiv_07_public_holidays(self):
391
+ # New Year's Day.
392
+ self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu")))
393
+
394
+ # Thaipusam.
395
+ self.dts_observed.add(self._add_thaipusam(tr("Hari Thaipusam")))
396
+
397
+ if self._year >= 2009:
398
+ self.dts_observed.add(
399
+ # George Town Heritage Day.
400
+ self._add_holiday_jul_7(tr("Hari Ulang Tahun Perisytiharan Tapak Warisan Dunia"))
281
401
  )
282
402
 
283
- elif self.subdiv == "PLS" and self._year >= 2000:
284
- name = "Birthday of The Raja of Perlis"
285
- dts_observed.add(
403
+ self.dts_observed.add(
404
+ # Birthday of the Governor of Penang.
405
+ self._add_holiday_2nd_sat_of_jul(tr("Hari Jadi Yang di-Pertua Negeri Pulau Pinang"))
406
+ )
407
+
408
+ # Nuzul Al-Quran Day.
409
+ self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran")))
410
+
411
+ def _populate_subdiv_08_public_holidays(self):
412
+ # New Year's Day.
413
+ self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu")))
414
+
415
+ # Thaipusam.
416
+ self.dts_observed.add(self._add_thaipusam(tr("Hari Thaipusam")))
417
+
418
+ # Birthday of the Sultan of Perak.
419
+ name = tr("Hari Keputeraan Sultan Perak")
420
+ if self._year >= 2018:
421
+ self._add_holiday_1st_fri_of_nov(name)
422
+ else:
423
+ self._add_holiday_nov_27(name)
424
+
425
+ # Nuzul Al-Quran Day.
426
+ self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran")))
427
+
428
+ def _populate_subdiv_09_public_holidays(self):
429
+ if self._year >= 2000:
430
+ # Birthday of the Raja of Perlis.
431
+ name = tr("Hari Ulang Tahun Keputeraan Raja Perlis")
432
+ self.dts_observed.add(
286
433
  self._add_holiday_jul_17(name)
287
- if self._year >= 2018
434
+ if 2018 <= self._year <= 2021
288
435
  else self._add_holiday_may_17(name)
289
436
  )
290
437
 
291
- elif self.subdiv == "SGR":
292
- dts_observed.add(self._add_holiday_dec_11("Birthday of The Sultan of Selangor"))
438
+ # Isra' and Mi'raj.
439
+ self.dts_observed.update(self._add_isra_and_miraj_day(tr("Israk dan Mikraj")))
293
440
 
294
- elif self.subdiv == "SWK":
295
- # Dayak Festival Day (the first day of June) and the following day.
296
- dts_observed.add(self._add_holiday_jun_1("Gawai Dayak"))
297
- dts_observed.add(self._add_holiday_jun_2("Gawai Dayak (Second day)"))
441
+ # Nuzul Al-Quran Day.
442
+ self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran")))
298
443
 
299
- # Birthday of Tuan Yang Terutama Yang di-Pertua Negeri Sarawak
300
- # (the second Saturday of October).
301
- dts_observed.add(
302
- self._add_holiday_2nd_sat_of_oct("Birthday of the Governor of Sarawak")
303
- )
444
+ # Eid al-Adha (Second Day).
445
+ self.dts_observed.update(
446
+ self._add_eid_al_adha_day_two(tr("Hari Raya Qurban (Hari Kedua)"))
447
+ )
448
+
449
+ def _populate_subdiv_10_public_holidays(self):
450
+ # New Year's Day.
451
+ self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu")))
304
452
 
305
- # Sarawak Independence Day
306
- if self._year >= 2017:
307
- dts_observed.add(self._add_holiday_jul_22("Sarawak Day"))
453
+ # Thaipusam.
454
+ self.dts_observed.add(self._add_thaipusam(tr("Hari Thaipusam")))
455
+
456
+ # Birthday of The Sultan of Selangor.
457
+ self.dts_observed.add(self._add_holiday_dec_11(tr("Hari Keputeraan Sultan Selangor")))
458
+
459
+ # Nuzul Al-Quran Day.
460
+ self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran")))
308
461
 
309
- elif self.subdiv == "TRG" and self._year >= 2000:
310
- dts_observed.add(
462
+ def _populate_subdiv_11_public_holidays(self):
463
+ if self._year >= 2000:
464
+ self.dts_observed.add(
311
465
  self._add_holiday_mar_4(
312
- "Anniversary of the Installation of the Sultan of Terengganu"
466
+ # Anniversary of the Installation of the Sultan of Terengganu.
467
+ tr("Hari Ulang Tahun Pertabalan Sultan Terengganu")
313
468
  )
314
469
  )
315
470
 
316
- dts_observed.add(self._add_holiday_apr_26("Birthday of the Sultan of Terengganu"))
471
+ self.dts_observed.add(
472
+ # Birthday of the Sultan of Terengganu.
473
+ self._add_holiday_apr_26(tr("Hari Keputeraan Sultan Terengganu"))
474
+ )
317
475
 
318
- if self.subdiv in {"JHR", "KDH"}:
319
- self._observed_rule = FRI_TO_NEXT_WORKDAY
320
- self.weekend = {FRI, SAT}
321
- elif self.subdiv in {"KTN", "TRG"}:
322
- self._observed_rule = SAT_TO_NEXT_WORKDAY
323
- self.weekend = {FRI, SAT}
476
+ if self._year >= 2020:
477
+ # Isra' and Mi'raj.
478
+ self.dts_observed.update(self._add_isra_and_miraj_day(tr("Israk dan Mikraj")))
324
479
 
325
- if self.observed:
326
- self._populate_observed(dts_observed)
480
+ # Nuzul Al-Quran Day.
481
+ self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran")))
327
482
 
328
- # Special cases observed from previous year.
329
- if self._year == 2007 and self.subdiv not in {"JHR", "KDH", "KTN", "TRG"}:
330
- self._add_holiday_jan_2(self.observed_label % "Hari Raya Haji")
483
+ # Arafat Day.
484
+ self.dts_observed.update(self._add_arafah_day(tr("Hari Arafah")))
331
485
 
332
- if self._year == 2007 and self.subdiv == "TRG":
333
- self._add_holiday_jan_2(self.observed_label % "Arafat Day")
486
+ self.dts_observed.update(
487
+ # Eid al-Adha (Second Day).
488
+ self._add_eid_al_adha_day_two(tr("Hari Raya Qurban (Hari Kedua)"))
489
+ )
334
490
 
335
- # The last two days in May (Pesta Kaamatan).
336
- # (Sarawak Act)
337
- # Day following a Sunday is not a holiday
338
- if self.subdiv in {"LBN", "SBH"}:
339
- self._add_holiday_may_30("Pesta Kaamatan")
340
- self._add_holiday_may_31("Pesta Kaamatan (Second day)")
491
+ def _populate_subdiv_12_public_holidays(self):
492
+ # New Year's Day.
493
+ self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu")))
341
494
 
342
- # Other holidays (decrees etc.)
495
+ # Good Friday.
496
+ self._add_good_friday(tr("Good Friday"))
343
497
 
344
- # Awal Muharram.
345
- self._add_islamic_new_year_day("Awal Muharram (Hijri New Year)")
498
+ # Pesta Kaamatan.
499
+ name = tr("Pesta Kaamatan")
500
+ self._add_holiday_may_30(name)
501
+ self._add_holiday_may_31(name)
346
502
 
347
- # Special holidays (states)
348
- if self._year == 2021 and self.subdiv in {"KUL", "LBN", "PJY"}:
349
- self._add_holiday_dec_3("Malaysia Cup Holiday")
503
+ # Birthday of the Governor of Sabah.
504
+ self._add_holiday_1st_sat_of_oct(tr("Hari Jadi Yang di-Pertua Negeri Sabah"))
350
505
 
351
- if self._year == 2022 and self.subdiv == "KDH":
352
- self._add_holiday_jan_18("Thaipusam")
506
+ if self._year >= 2019:
507
+ # Christmas Eve.
508
+ self._add_christmas_eve(tr("Christmas Eve"))
353
509
 
354
- if self._year == 2022 and self.subdiv in {"JHR", "KDH", "KTN", "TRG"}:
355
- self._add_holiday_may_4("Labour Day Holiday")
510
+ def _populate_subdiv_13_public_holidays(self):
511
+ # New Year's Day.
512
+ self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu")))
356
513
 
357
- # Multiple state holidays.
358
514
  # Good Friday.
359
- if self.subdiv in {"SBH", "SWK"}:
360
- self._add_good_friday("Good Friday")
361
-
362
- # Single state holidays.
363
- if self.subdiv == "JHR":
364
- if self._year >= 2015:
365
- self._add_holiday_mar_23("Birthday of the Sultan of Johor")
366
-
367
- if self._year >= 2011:
368
- self._add_hari_hol_johor("Hari Hol of Sultan Iskandar of Johor")
369
-
370
- elif self.subdiv == "KDH" and self._year >= 2020:
371
- self._add_holiday_3rd_sun_of_jun("Birthday of The Sultan of Kedah")
372
-
373
- elif self.subdiv == "KTN" and self._year >= 2010:
374
- name = "Birthday of the Sultan of Kelantan"
375
- self._add_holiday_nov_11(name)
376
- self._add_holiday_nov_12(name)
377
-
378
- elif self.subdiv == "PRK":
379
- # This Holiday used to be on 27th until 2017
380
- # https://www.officeholidays.com/holidays/malaysia/birthday-of-the-sultan-of-perak
381
- name = "Birthday of the Sultan of Perak"
382
- if self._year >= 2018:
383
- self._add_holiday_1st_fri_of_nov(name)
384
- else:
385
- self._add_holiday_nov_27(name)
515
+ self._add_good_friday(tr("Good Friday"))
516
+
517
+ if self._year >= 1965:
518
+ # Dayak Festival Day.
519
+ name = tr("Perayaan Hari Gawai Dayak")
520
+ self.dts_observed.add(self._add_holiday_jun_1(name))
521
+ self.dts_observed.add(self._add_holiday_jun_2(name))
522
+
523
+ # Birthday of the Governor of Sarawak.
524
+ self._add_holiday_2nd_sat_of_oct(tr("Hari Jadi Yang di-Pertua Negeri Sarawak"))
525
+
526
+ if self._year >= 2017:
527
+ # Sarawak Independence Day.
528
+ self.dts_observed.add(self._add_holiday_jul_22(tr("Hari Kemerdekaan Sarawak")))
529
+
530
+ def _populate_subdiv_14_public_holidays(self):
531
+ # New Year's Day.
532
+ self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu")))
533
+
534
+ # Thaipusam.
535
+ self.dts_observed.add(self._add_thaipusam(tr("Hari Thaipusam")))
536
+
537
+ if self._year >= 1974:
538
+ # Federal Territory Day.
539
+ self.dts_observed.add(self._add_holiday_feb_1(tr("Hari Wilayah Persekutuan")))
540
+
541
+ # Nuzul Al-Quran Day.
542
+ self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran")))
543
+
544
+ def _populate_subdiv_15_public_holidays(self):
545
+ # New Year's Day.
546
+ self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu")))
547
+
548
+ if self._year >= 1974:
549
+ # Federal Territory Day.
550
+ self.dts_observed.add(self._add_holiday_feb_1(tr("Hari Wilayah Persekutuan")))
551
+
552
+ # Pesta Kaamatan.
553
+ name = tr("Pesta Kaamatan")
554
+ self._add_holiday_may_30(name)
555
+ self._add_holiday_may_31(name)
556
+
557
+ if self._year >= 2014:
558
+ # Deepavali.
559
+ self.dts_observed.add(self._add_diwali(tr("Hari Deepavali")))
560
+
561
+ # Nuzul Al-Quran Day.
562
+ self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran")))
563
+
564
+ def _populate_subdiv_16_public_holidays(self):
565
+ # New Year's Day.
566
+ self.dts_observed.add(self._add_new_years_day(tr("Tahun Baharu")))
386
567
 
387
- elif self.subdiv == "SBH":
388
- self._add_holiday_1st_sat_of_oct("Birthday of the Governor of Sabah")
568
+ # Thaipusam.
569
+ self.dts_observed.add(self._add_thaipusam(tr("Hari Thaipusam")))
570
+
571
+ if self._year >= 1974:
572
+ # Federal Territory Day.
573
+ self.dts_observed.add(self._add_holiday_feb_1(tr("Hari Wilayah Persekutuan")))
389
574
 
390
- if self._year >= 2019:
391
- self._add_christmas_eve("Christmas Eve")
575
+ # Nuzul Al-Quran Day.
576
+ self.dts_observed.update(self._add_nuzul_al_quran_day(tr("Hari Nuzul Al-Quran")))
392
577
 
393
578
 
394
579
  class MY(Malaysia):
@@ -556,7 +741,7 @@ class MalaysiaIslamicHolidays(_CustomIslamicHolidays):
556
741
 
557
742
  HARI_HOL_JOHOR_DATES = {
558
743
  2011: (JAN, 12),
559
- 2012: ((JAN, 1), (DEC, 20)),
744
+ 2012: (DEC, 20),
560
745
  2013: (DEC, 10),
561
746
  2014: (NOV, 29),
562
747
  2015: (NOV, 19),
@@ -567,6 +752,7 @@ class MalaysiaIslamicHolidays(_CustomIslamicHolidays):
567
752
  2020: (SEP, 24),
568
753
  2021: (SEP, 13),
569
754
  2022: (SEP, 3),
755
+ 2023: (AUG, 23),
570
756
  2024: (AUG, 11),
571
757
  }
572
758
 
@@ -593,6 +779,7 @@ class MalaysiaIslamicHolidays(_CustomIslamicHolidays):
593
779
  2020: (AUG, 20),
594
780
  2021: (AUG, 10),
595
781
  2022: (JUL, 30),
782
+ 2023: (JUL, 19),
596
783
  2024: (JUL, 7),
597
784
  }
598
785
 
@@ -646,8 +833,10 @@ class MalaysiaIslamicHolidays(_CustomIslamicHolidays):
646
833
  2020: (OCT, 29),
647
834
  2021: (OCT, 19),
648
835
  2022: (OCT, 10),
836
+ 2023: (SEP, 28),
649
837
  2024: (SEP, 16),
650
838
  }
839
+
651
840
  NUZUL_AL_QURAN_DATES = {
652
841
  2001: (DEC, 3),
653
842
  2002: (NOV, 22),
@@ -704,11 +893,132 @@ class MalaysiaIslamicHolidays(_CustomIslamicHolidays):
704
893
 
705
894
 
706
895
  class MalaysiaStaticHolidays:
896
+ # General election additional holiday.
897
+ election_polling_day = tr("Cuti Peristiwa (pilihan raya umum)")
898
+
899
+ # Additional holiday.
900
+ election_additional_holiday = "Cuti Peristiwa"
901
+
902
+ # Eid al-Adha.
903
+ eid_al_adha = tr("Hari Raya Qurban")
904
+
905
+ # Labor Day.
906
+ labor_day = tr("Hari Pekerja")
907
+
908
+ # Malaysia Cup Holiday.
909
+ malaysia_cup_holiday = tr("Cuti Piala Malaysia")
910
+
911
+ # Day of Installation of the 15th Yang di-Pertuan Agong.
912
+ yang_di_pertuan_agong_15_installation = tr("Hari Pertabalan Yang di-Pertuan Agong ke-15")
913
+
914
+ # Day of Installation of the 16th Yang di-Pertuan Agong.
915
+ yang_di_pertuan_agong_16_installation = tr("Hari Pertabalan Yang di-Pertuan Agong ke-16")
916
+
917
+ # Eid al-Fitr (additional holiday).
918
+ eid_al_fitr_additional_holiday = tr("Hari Raya Puasa (pergantian hari)")
919
+
920
+ # Arafat Day.
921
+ arafat_day = tr("Hari Arafah")
922
+
923
+ # Additional holiday in commemoration of the 2017 SEA Games.
924
+ additional_holiday_2017_sea_games = tr("Cuti tambahan sempena memperingati SAT 2017")
925
+
707
926
  special_public_holidays = {
708
- # The years 1955 1959 1995 seems to have the elections
709
- # one weekday but I am not sure if they were marked as
710
- # holidays.
711
- 1999: (NOV, 29, "Malaysia General Election Holiday"),
712
- 2018: (MAY, 9, "Malaysia General Election Holiday"),
713
- 2019: (JUL, 30, "Installation of New King"),
927
+ 1999: (NOV, 29, election_polling_day),
928
+ 2017: (
929
+ (APR, 24, yang_di_pertuan_agong_15_installation),
930
+ (SEP, 4, additional_holiday_2017_sea_games),
931
+ ),
932
+ 2018: (MAY, 9, election_polling_day),
933
+ 2019: (JUL, 30, yang_di_pertuan_agong_16_installation),
934
+ 2022: (
935
+ (NOV, 18, election_polling_day),
936
+ (NOV, 19, election_polling_day),
937
+ (NOV, 28, election_additional_holiday),
938
+ ),
939
+ 2023: (APR, 21, eid_al_fitr_additional_holiday),
940
+ }
941
+
942
+ special_14_public_holidays = {
943
+ 2021: (DEC, 3, malaysia_cup_holiday),
944
+ }
945
+
946
+ special_15_public_holidays = {
947
+ 2021: (DEC, 3, malaysia_cup_holiday),
948
+ }
949
+
950
+ special_16_public_holidays = {
951
+ 2021: (DEC, 3, malaysia_cup_holiday),
952
+ }
953
+
954
+ special_13_public_holidays = {
955
+ 2018: (
956
+ (MAY, 17, election_additional_holiday),
957
+ (MAY, 18, election_additional_holiday),
958
+ ),
959
+ }
960
+
961
+ special_01_public_holidays_observed = {
962
+ 2022: (MAY, 4, labor_day),
963
+ }
964
+
965
+ special_02_public_holidays_observed = {
966
+ 2022: (MAY, 4, labor_day),
967
+ }
968
+
969
+ special_03_public_holidays_observed = {
970
+ 2022: (MAY, 4, labor_day),
971
+ }
972
+
973
+ special_14_public_holidays_observed = {
974
+ 2007: (JAN, 2, eid_al_adha),
975
+ }
976
+
977
+ special_15_public_holidays_observed = {
978
+ 2007: (JAN, 2, eid_al_adha),
979
+ }
980
+
981
+ special_04_public_holidays_observed = {
982
+ 2007: (JAN, 2, eid_al_adha),
983
+ }
984
+
985
+ special_05_public_holidays_observed = {
986
+ 2007: (JAN, 2, eid_al_adha),
987
+ }
988
+
989
+ special_06_public_holidays_observed = {
990
+ 2007: (JAN, 2, eid_al_adha),
991
+ }
992
+
993
+ special_16_public_holidays_observed = {
994
+ 2007: (JAN, 2, eid_al_adha),
995
+ }
996
+
997
+ special_09_public_holidays_observed = {
998
+ 2007: (JAN, 2, eid_al_adha),
999
+ }
1000
+
1001
+ special_07_public_holidays_observed = {
1002
+ 2007: (JAN, 2, eid_al_adha),
1003
+ }
1004
+
1005
+ special_08_public_holidays_observed = {
1006
+ 2007: (JAN, 2, eid_al_adha),
1007
+ }
1008
+
1009
+ special_12_public_holidays_observed = {
1010
+ 2007: (JAN, 2, eid_al_adha),
1011
+ }
1012
+
1013
+ special_10_public_holidays_observed = {
1014
+ 2007: (JAN, 2, eid_al_adha),
1015
+ }
1016
+
1017
+ special_13_public_holidays_observed = {
1018
+ 2007: (JAN, 2, eid_al_adha),
1019
+ }
1020
+
1021
+ special_11_public_holidays_observed = {
1022
+ 2007: (JAN, 2, arafat_day),
1023
+ 2022: (MAY, 4, labor_day),
714
1024
  }