holidays 0.80__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 (142) hide show
  1. holidays/calendars/__init__.py +1 -0
  2. holidays/calendars/burmese.py +319 -0
  3. holidays/calendars/chinese.py +39 -1
  4. holidays/calendars/hebrew.py +2 -2
  5. holidays/calendars/thai.py +49 -2
  6. holidays/countries/__init__.py +16 -0
  7. holidays/countries/afghanistan.py +7 -5
  8. holidays/countries/algeria.py +89 -24
  9. holidays/countries/antarctica.py +58 -0
  10. holidays/countries/bouvet_island.py +31 -0
  11. holidays/countries/brazil.py +1 -1
  12. holidays/countries/british_indian_ocean_territory.py +31 -0
  13. holidays/countries/bulgaria.py +6 -1
  14. holidays/countries/chile.py +9 -8
  15. holidays/countries/china.py +4 -0
  16. holidays/countries/cuba.py +3 -4
  17. holidays/countries/djibouti.py +1 -1
  18. holidays/countries/heard_island_and_mcdonald_islands.py +31 -0
  19. holidays/countries/hongkong.py +5 -1
  20. holidays/countries/hungary.py +4 -5
  21. holidays/countries/india.py +6 -0
  22. holidays/countries/japan.py +22 -18
  23. holidays/countries/jordan.py +6 -3
  24. holidays/countries/kuwait.py +6 -3
  25. holidays/countries/macau.py +9 -0
  26. holidays/countries/malaysia.py +14 -3
  27. holidays/countries/mongolia.py +2 -0
  28. holidays/countries/myanmar.py +195 -0
  29. holidays/countries/north_korea.py +161 -0
  30. holidays/countries/norway.py +23 -8
  31. holidays/countries/oman.py +6 -2
  32. holidays/countries/paraguay.py +70 -23
  33. holidays/countries/philippines.py +11 -2
  34. holidays/countries/portugal.py +5 -6
  35. holidays/countries/qatar.py +5 -2
  36. holidays/countries/rwanda.py +6 -1
  37. holidays/countries/saint_helena_ascension_and_tristan_da_cunha.py +197 -0
  38. holidays/countries/saudi_arabia.py +6 -5
  39. holidays/countries/serbia.py +5 -0
  40. holidays/countries/south_africa.py +96 -53
  41. holidays/countries/south_korea.py +10 -1
  42. holidays/countries/spain.py +26 -4
  43. holidays/countries/sudan.py +118 -0
  44. holidays/countries/switzerland.py +169 -3
  45. holidays/countries/taiwan.py +27 -3
  46. holidays/countries/tajikistan.py +1 -1
  47. holidays/countries/tanzania.py +6 -1
  48. holidays/countries/thailand.py +21 -0
  49. holidays/countries/tonga.py +6 -1
  50. holidays/countries/trinidad_and_tobago.py +6 -1
  51. holidays/countries/united_arab_emirates.py +9 -2
  52. holidays/countries/united_states.py +16 -0
  53. holidays/countries/uruguay.py +6 -1
  54. holidays/countries/vietnam.py +10 -1
  55. holidays/countries/yemen.py +6 -3
  56. holidays/groups/__init__.py +1 -0
  57. holidays/groups/balinese_saka.py +1 -1
  58. holidays/groups/buddhist.py +1 -1
  59. holidays/groups/burmese.py +273 -0
  60. holidays/groups/chinese.py +27 -14
  61. holidays/groups/custom.py +8 -2
  62. holidays/groups/eastern.py +25 -3
  63. holidays/groups/hebrew.py +16 -14
  64. holidays/groups/hindu.py +15 -13
  65. holidays/groups/islamic.py +52 -47
  66. holidays/groups/mongolian.py +1 -1
  67. holidays/groups/sinhala.py +4 -9
  68. holidays/groups/tibetan.py +3 -4
  69. holidays/holiday_base.py +5 -4
  70. holidays/ical.py +6 -4
  71. holidays/locale/ar/LC_MESSAGES/DZ.mo +0 -0
  72. holidays/locale/ar_SD/LC_MESSAGES/SD.mo +0 -0
  73. holidays/locale/ca/LC_MESSAGES/ES.mo +0 -0
  74. holidays/locale/en_GB/LC_MESSAGES/SH.mo +0 -0
  75. holidays/locale/en_HK/LC_MESSAGES/HK.mo +0 -0
  76. holidays/locale/en_IN/LC_MESSAGES/IN.mo +0 -0
  77. holidays/locale/en_MO/LC_MESSAGES/MO.mo +0 -0
  78. holidays/locale/en_PH/LC_MESSAGES/PH.mo +0 -0
  79. holidays/locale/en_US/LC_MESSAGES/BR.mo +0 -0
  80. holidays/locale/en_US/LC_MESSAGES/CN.mo +0 -0
  81. holidays/locale/en_US/LC_MESSAGES/DZ.mo +0 -0
  82. holidays/locale/en_US/LC_MESSAGES/ES.mo +0 -0
  83. holidays/locale/en_US/LC_MESSAGES/HK.mo +0 -0
  84. holidays/locale/en_US/LC_MESSAGES/IN.mo +0 -0
  85. holidays/locale/en_US/LC_MESSAGES/JP.mo +0 -0
  86. holidays/locale/en_US/LC_MESSAGES/KP.mo +0 -0
  87. holidays/locale/en_US/LC_MESSAGES/KR.mo +0 -0
  88. holidays/locale/en_US/LC_MESSAGES/MM.mo +0 -0
  89. holidays/locale/en_US/LC_MESSAGES/MN.mo +0 -0
  90. holidays/locale/en_US/LC_MESSAGES/MO.mo +0 -0
  91. holidays/locale/en_US/LC_MESSAGES/PH.mo +0 -0
  92. holidays/locale/en_US/LC_MESSAGES/PY.mo +0 -0
  93. holidays/locale/en_US/LC_MESSAGES/SD.mo +0 -0
  94. holidays/locale/en_US/LC_MESSAGES/SH.mo +0 -0
  95. holidays/locale/en_US/LC_MESSAGES/TW.mo +0 -0
  96. holidays/locale/en_US/LC_MESSAGES/US.mo +0 -0
  97. holidays/locale/en_US/LC_MESSAGES/VN.mo +0 -0
  98. holidays/locale/es/LC_MESSAGES/ES.mo +0 -0
  99. holidays/locale/es/LC_MESSAGES/PY.mo +0 -0
  100. holidays/locale/fil/LC_MESSAGES/PH.mo +0 -0
  101. holidays/locale/fr/LC_MESSAGES/DZ.mo +0 -0
  102. holidays/locale/hi/LC_MESSAGES/IN.mo +0 -0
  103. holidays/locale/ja/LC_MESSAGES/JP.mo +0 -0
  104. holidays/locale/ko/LC_MESSAGES/KR.mo +0 -0
  105. holidays/locale/ko_KP/LC_MESSAGES/KP.mo +0 -0
  106. holidays/locale/mn/LC_MESSAGES/MN.mo +0 -0
  107. holidays/locale/my/LC_MESSAGES/MM.mo +0 -0
  108. holidays/locale/pt_BR/LC_MESSAGES/BR.mo +0 -0
  109. holidays/locale/pt_MO/LC_MESSAGES/MO.mo +0 -0
  110. holidays/locale/th/LC_MESSAGES/CN.mo +0 -0
  111. holidays/locale/th/LC_MESSAGES/HK.mo +0 -0
  112. holidays/locale/th/LC_MESSAGES/JP.mo +0 -0
  113. holidays/locale/th/LC_MESSAGES/KR.mo +0 -0
  114. holidays/locale/th/LC_MESSAGES/MM.mo +0 -0
  115. holidays/locale/th/LC_MESSAGES/MO.mo +0 -0
  116. holidays/locale/th/LC_MESSAGES/PH.mo +0 -0
  117. holidays/locale/th/LC_MESSAGES/TW.mo +0 -0
  118. holidays/locale/th/LC_MESSAGES/US.mo +0 -0
  119. holidays/locale/th/LC_MESSAGES/VN.mo +0 -0
  120. holidays/locale/uk/LC_MESSAGES/BR.mo +0 -0
  121. holidays/locale/uk/LC_MESSAGES/ES.mo +0 -0
  122. holidays/locale/uk/LC_MESSAGES/PY.mo +0 -0
  123. holidays/locale/vi/LC_MESSAGES/VN.mo +0 -0
  124. holidays/locale/zh_CN/LC_MESSAGES/CN.mo +0 -0
  125. holidays/locale/zh_CN/LC_MESSAGES/HK.mo +0 -0
  126. holidays/locale/zh_CN/LC_MESSAGES/MO.mo +0 -0
  127. holidays/locale/zh_CN/LC_MESSAGES/TW.mo +0 -0
  128. holidays/locale/zh_HK/LC_MESSAGES/HK.mo +0 -0
  129. holidays/locale/zh_MO/LC_MESSAGES/MO.mo +0 -0
  130. holidays/locale/zh_TW/LC_MESSAGES/CN.mo +0 -0
  131. holidays/locale/zh_TW/LC_MESSAGES/TW.mo +0 -0
  132. holidays/no_holiday_base.py +21 -0
  133. holidays/observed_holiday_base.py +1 -1
  134. holidays/registry.py +12 -0
  135. holidays/utils.py +5 -5
  136. holidays/version.py +1 -1
  137. {holidays-0.80.dist-info → holidays-0.82.dist-info}/METADATA +61 -5
  138. {holidays-0.80.dist-info → holidays-0.82.dist-info}/RECORD +142 -121
  139. {holidays-0.80.dist-info → holidays-0.82.dist-info}/licenses/CONTRIBUTORS +2 -0
  140. {holidays-0.80.dist-info → holidays-0.82.dist-info}/WHEEL +0 -0
  141. {holidays-0.80.dist-info → holidays-0.82.dist-info}/licenses/LICENSE +0 -0
  142. {holidays-0.80.dist-info → holidays-0.82.dist-info}/top_level.txt +0 -0
@@ -10,8 +10,10 @@
10
10
  # Website: https://github.com/vacanza/holidays
11
11
  # License: MIT (see LICENSE file)
12
12
 
13
- from datetime import date
13
+ from __future__ import annotations
14
+
14
15
  from gettext import gettext as tr
16
+ from typing import TYPE_CHECKING
15
17
 
16
18
  from holidays.calendars.gregorian import SEP, NOV, DEC
17
19
  from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays
@@ -22,6 +24,9 @@ from holidays.observed_holiday_base import (
22
24
  SUN_TO_NEXT_MON,
23
25
  )
24
26
 
27
+ if TYPE_CHECKING:
28
+ from datetime import date
29
+
25
30
 
26
31
  class Tonga(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays):
27
32
  """Tonga holidays.
@@ -10,8 +10,10 @@
10
10
  # Website: https://github.com/vacanza/holidays
11
11
  # License: MIT (see LICENSE file)
12
12
 
13
- from datetime import date
13
+ from __future__ import annotations
14
+
14
15
  from gettext import gettext as tr
16
+ from typing import TYPE_CHECKING
15
17
 
16
18
  from holidays.calendars import _CustomHinduHolidays, _CustomIslamicHolidays
17
19
  from holidays.calendars.gregorian import MAR, APR, JUN, JUL, OCT, NOV
@@ -29,6 +31,9 @@ from holidays.observed_holiday_base import (
29
31
  WORKDAY_TO_NEXT_WORKDAY,
30
32
  )
31
33
 
34
+ if TYPE_CHECKING:
35
+ from datetime import date
36
+
32
37
 
33
38
  class TrinidadAndTobago(
34
39
  ObservedHolidayBase,
@@ -10,7 +10,10 @@
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 import _CustomIslamicHolidays
16
19
  from holidays.calendars.gregorian import (
@@ -32,6 +35,9 @@ from holidays.constants import GOVERNMENT, OPTIONAL, PUBLIC
32
35
  from holidays.groups import InternationalHolidays, IslamicHolidays, StaticHolidays
33
36
  from holidays.holiday_base import HolidayBase
34
37
 
38
+ if TYPE_CHECKING:
39
+ from datetime import date
40
+
35
41
 
36
42
  class UnitedArabEmirates(HolidayBase, InternationalHolidays, IslamicHolidays, StaticHolidays):
37
43
  """United Arab Emirates holidays.
@@ -79,11 +85,12 @@ class UnitedArabEmirates(HolidayBase, InternationalHolidays, IslamicHolidays, St
79
85
  StaticHolidays.__init__(self, UnitedArabEmiratesStaticHolidays)
80
86
  super().__init__(*args, **kwargs)
81
87
 
82
- def _populate_public_holidays(self):
88
+ def _get_weekend(self, dt: date) -> set[int]:
83
89
  # The resting days are Saturday and Sunday since Jan 1, 2022.
84
90
  # https://web.archive.org/web/20250216144205/https://time.com/6126260/uae-working-days-weekend/
85
- self.weekend = {FRI, SAT} if self._year <= 2021 else {SAT, SUN}
91
+ return {SAT, SUN} if dt.year >= 2022 else {FRI, SAT}
86
92
 
93
+ def _populate_public_holidays(self):
87
94
  # New Year's Day.
88
95
  self._add_new_years_day(tr("رأس السنة الميلادية"))
89
96
 
@@ -1341,6 +1341,22 @@ class UnitedStates(ObservedHolidayBase, ChristianHolidays, InternationalHolidays
1341
1341
  # Saint Patrick's Day.
1342
1342
  self._add_holiday_mar_17(tr("Saint Patrick's Day"))
1343
1343
 
1344
+ # Mother's Day.
1345
+ # Starts to be observed by most US states by 1911.
1346
+ # Officially proclaimed as a National Holiday by President Woodrow Wilson in 1914.
1347
+
1348
+ if self._year >= 1914:
1349
+ # Mother's Day.
1350
+ self._add_holiday_2nd_sun_of_may(tr("Mother's Day"))
1351
+
1352
+ # Father's Day.
1353
+ # First founded in the state of Washington by Sonora Smart Dodd in 1910.
1354
+ # Officially proclaimed as a National Holiday by President Richard Nixon in 1972.
1355
+
1356
+ if self._year >= 1972:
1357
+ # Father's Day.
1358
+ self._add_holiday_3rd_sun_of_jun(tr("Father's Day"))
1359
+
1344
1360
  # Halloween.
1345
1361
  # Halloween began in the US sometime around the 19th century.
1346
1362
 
@@ -10,8 +10,10 @@
10
10
  # Website: https://github.com/vacanza/holidays
11
11
  # License: MIT (see LICENSE file)
12
12
 
13
- from datetime import date
13
+ from __future__ import annotations
14
+
14
15
  from gettext import gettext as tr
16
+ from typing import TYPE_CHECKING
15
17
 
16
18
  from holidays.calendars.gregorian import MAR
17
19
  from holidays.constants import BANK, PUBLIC
@@ -22,6 +24,9 @@ from holidays.observed_holiday_base import (
22
24
  THU_FRI_TO_NEXT_MON,
23
25
  )
24
26
 
27
+ if TYPE_CHECKING:
28
+ from datetime import date
29
+
25
30
 
26
31
  class Uruguay(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, StaticHolidays):
27
32
  """Uruguay holidays.
@@ -10,8 +10,10 @@
10
10
  # Website: https://github.com/vacanza/holidays
11
11
  # License: MIT (see LICENSE file)
12
12
 
13
- from datetime import date
13
+ from __future__ import annotations
14
+
14
15
  from gettext import gettext as tr
16
+ from typing import TYPE_CHECKING
15
17
 
16
18
  from holidays.calendars.chinese import VIETNAMESE_CALENDAR
17
19
  from holidays.calendars.gregorian import (
@@ -39,6 +41,9 @@ from holidays.observed_holiday_base import (
39
41
  SAT_SUN_TO_NEXT_WORKDAY,
40
42
  )
41
43
 
44
+ if TYPE_CHECKING:
45
+ from datetime import date
46
+
42
47
  NATIONAL_DAY_RULE = ObservedRule({MON: +1, TUE: -1, WED: -1, THU: +1, FRI: -1, SAT: -1, SUN: +1})
43
48
 
44
49
 
@@ -54,6 +59,10 @@ class Vietnam(ObservedHolidayBase, ChineseCalendarHolidays, InternationalHoliday
54
59
  """
55
60
 
56
61
  country = "VN"
62
+ # %s (estimated).
63
+ estimated_label = tr("%s (dự kiến)")
64
+ # %s (observed, estimated).
65
+ observed_estimated_label = tr("%s (nghỉ bù, dự kiến)")
57
66
  # %s (observed).
58
67
  observed_label = tr("%s (nghỉ bù)")
59
68
  default_language = "vi"
@@ -10,6 +10,7 @@
10
10
  # Website: https://github.com/vacanza/holidays
11
11
  # License: MIT (see LICENSE file)
12
12
 
13
+ from datetime import date
13
14
  from gettext import gettext as tr
14
15
 
15
16
  from holidays.calendars import _CustomIslamicHolidays
@@ -45,6 +46,7 @@ class Yemen(ObservedHolidayBase, InternationalHolidays, IslamicHolidays):
45
46
  start_year = 1991
46
47
  supported_categories = (PUBLIC, SCHOOL, WORKDAY)
47
48
  supported_languages = ("ar", "en_US")
49
+ weekend = {FRI, SAT}
48
50
 
49
51
  def __init__(self, *args, islamic_show_estimated: bool = True, **kwargs):
50
52
  """
@@ -60,12 +62,13 @@ class Yemen(ObservedHolidayBase, InternationalHolidays, IslamicHolidays):
60
62
  kwargs.setdefault("observed_rule", FRI_TO_NEXT_WORKDAY)
61
63
  super().__init__(*args, **kwargs)
62
64
 
65
+ def _get_weekend(self, dt: date) -> set[int]:
66
+ # Yemen switches from THU-FRI to FRI-SAT on Aug 15, 2013.
67
+ return {FRI, SAT} if dt >= date(2013, AUG, 15) else {THU, FRI}
68
+
63
69
  def _populate_public_holidays(self):
64
70
  dts_observed = set()
65
71
 
66
- # Yemen switches from THU-FRI to FRI-SAT on Aug 15, 2013
67
- self.weekend = {THU, FRI} if self._year <= 2012 else {FRI, SAT}
68
-
69
72
  # Hijri New Year.
70
73
  dts_observed.update(self._add_islamic_new_year_day(tr("عيد رأس السنة الهجرية")))
71
74
 
@@ -14,6 +14,7 @@
14
14
 
15
15
  from holidays.groups.balinese_saka import BalineseSakaCalendarHolidays
16
16
  from holidays.groups.buddhist import BuddhistCalendarHolidays
17
+ from holidays.groups.burmese import BurmeseCalendarHolidays
17
18
  from holidays.groups.chinese import ChineseCalendarHolidays
18
19
  from holidays.groups.christian import ChristianHolidays
19
20
  from holidays.groups.custom import StaticHolidays
@@ -13,7 +13,7 @@
13
13
  from datetime import date
14
14
  from typing import Optional
15
15
 
16
- from holidays.calendars import _BalineseSakaLunar
16
+ from holidays.calendars.balinese_saka import _BalineseSakaLunar
17
17
 
18
18
 
19
19
  class BalineseSakaCalendarHolidays:
@@ -13,7 +13,7 @@
13
13
  from datetime import date
14
14
  from typing import Optional
15
15
 
16
- from holidays.calendars import _BuddhistLunisolar
16
+ from holidays.calendars.buddhist import _BuddhistLunisolar
17
17
  from holidays.groups.eastern import EasternCalendarHolidays
18
18
 
19
19
 
@@ -0,0 +1,273 @@
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 typing import Optional
15
+
16
+ from holidays.calendars.burmese import _BurmeseLunisolar
17
+ from holidays.calendars.gregorian import _timedelta
18
+
19
+
20
+ class BurmeseCalendarHolidays:
21
+ """Burmese lunisolar calendar holidays."""
22
+
23
+ def __init__(self) -> None:
24
+ self._burmese_calendar = _BurmeseLunisolar()
25
+
26
+ def _add_burmese_calendar_holiday(
27
+ self, name: str, dt: Optional[date] = None, days_delta: int = 0
28
+ ) -> Optional[date]:
29
+ """Add Burmese calendar holiday."""
30
+
31
+ if dt is None:
32
+ return None
33
+
34
+ if days_delta:
35
+ dt = _timedelta(dt, days_delta)
36
+
37
+ return self._add_holiday(name, dt)
38
+
39
+ def _add_karen_new_year(self, name: str) -> set[date]:
40
+ """Add Karen New Year holiday.
41
+
42
+ The Karen New Year, also known as the Kayin New Year, is one of the major holidays
43
+ celebrated by the Karen people. The Karen New Year falls on the first day of Pyatho,
44
+ the tenth month in the Burmese calendar.
45
+ https://en.wikipedia.org/wiki/Karen_New_Year
46
+
47
+ Args:
48
+ name:
49
+ Holiday name.
50
+
51
+ Returns:
52
+ Set of dates of added holiday, empty if there is no holiday date for the current year.
53
+ """
54
+ return {
55
+ dt
56
+ for y in (self._year - 1, self._year)
57
+ if (
58
+ dt := self._add_burmese_calendar_holiday(
59
+ name, self._burmese_calendar.pyatho_waxing_moon_date(y)
60
+ )
61
+ )
62
+ }
63
+
64
+ def _add_kason_full_moon_day(self, name: str) -> Optional[date]:
65
+ """Add Full Moon Day of Kason holiday.
66
+
67
+ Vesak is known as the Full Moon Day of Kason, which is the second month
68
+ in the traditional Burmese calendar.
69
+ https://en.wikipedia.org/wiki/Vesak#In_Myanmar_(Burma)
70
+
71
+ Args:
72
+ name:
73
+ Holiday name.
74
+
75
+ Returns:
76
+ Date of added holiday, `None` if there is no holiday date for the current year.
77
+ """
78
+ return self._add_burmese_calendar_holiday(
79
+ name, self._burmese_calendar.kason_full_moon_date(self._year)
80
+ )
81
+
82
+ def _add_myanmar_diwali(self, name: str) -> Optional[date]:
83
+ """Add Myanmar Diwali holiday.
84
+
85
+ Diwali (Deepavali, Festival of Lights) is one of the most important festivals
86
+ in Indian religions. In Myanmar, it is celebrated on first day of Tazaungmon,
87
+ the eighth month of the Burmese calendar.
88
+ https://en.wikipedia.org/wiki/Diwali
89
+
90
+ Args:
91
+ name:
92
+ Holiday name.
93
+
94
+ Returns:
95
+ Date of added holiday, `None` if there is no holiday date for the current year.
96
+ """
97
+ return self._add_burmese_calendar_holiday(
98
+ name, self._burmese_calendar.tazaungmon_waxing_moon_date(self._year)
99
+ )
100
+
101
+ def _add_myanmar_national_day(self, name: str) -> Optional[date]:
102
+ """Add Myanmar National Day holiday.
103
+
104
+ National Day is a public holiday in Myanmar, marking the anniversary of the first
105
+ university student strike at Rangoon University in 1920. The date is based on
106
+ the traditional Burmese calendar, occurring on the 10th day following
107
+ the full moon of Tazaungmon.
108
+ https://en.wikipedia.org/wiki/National_Day_(Myanmar)
109
+
110
+ Args:
111
+ name:
112
+ Holiday name.
113
+
114
+ Returns:
115
+ Date of added holiday, `None` if there is no holiday date for the current year.
116
+ """
117
+ return self._add_burmese_calendar_holiday(
118
+ name, self._burmese_calendar.tazaungmon_full_moon_date(self._year), days_delta=+10
119
+ )
120
+
121
+ def _add_myanmar_new_year(
122
+ self,
123
+ name: str,
124
+ extra_days_before: int = 0,
125
+ extra_days_after: int = 0,
126
+ ) -> set[date]:
127
+ """Add Myanmar New Year (Thingyan, Water Festival).
128
+
129
+ Thingyan, also known as the Myanmar New Year, is a festival that usually occurs
130
+ in middle of April. Thingyan marks the transition from the old year to the new one,
131
+ based on the traditional Myanmar lunisolar calendar. The festival usually spans
132
+ four to five days.
133
+
134
+ https://en.wikipedia.org/wiki/Thingyan.
135
+
136
+ Args:
137
+ name:
138
+ Holiday name.
139
+
140
+ extra_days_before:
141
+ Number of additional holiday days preceding Akya.
142
+
143
+ extra_days_after:
144
+ Whether to add additional holiday days following Atat.
145
+
146
+ Returns:
147
+ Set of dates of added holiday, empty if there is no holiday date for the current year.
148
+ """
149
+ akya, atat = self._burmese_calendar.thingyan_dates(self._year)
150
+ if akya is None or atat is None:
151
+ return set()
152
+
153
+ # Default length is from Thingyan Akyo (akya - 1) to New Year Day (atat + 1).
154
+ # Optional additional days:
155
+ # pre-Akya days (1 day in 2007-2016, 4 days in 2022-2023),
156
+ # post-Atat days (3 or 4 days).
157
+ begin = -1 - extra_days_before
158
+ end = extra_days_after or (atat - akya).days + 1
159
+
160
+ return {
161
+ dt
162
+ for delta in range(begin, end)
163
+ if (dt := self._add_holiday(name, _timedelta(akya, delta)))
164
+ }
165
+
166
+ def _add_tabaung_full_moon_day(self, name: str) -> Optional[date]:
167
+ """Add Full Moon Day of Tabaung holiday.
168
+
169
+ Māgha Pūjā (also written as Makha Bucha Day, Meak Bochea) is a Buddhist festival
170
+ celebrated on the full moon day of Tabaung in Myanmar.
171
+ https://en.wikipedia.org/wiki/Māgha_Pūjā#Myanmar_(Burma)
172
+
173
+ Args:
174
+ name:
175
+ Holiday name.
176
+
177
+ Returns:
178
+ Date of added holiday, `None` if there is no holiday date for the current year.
179
+ """
180
+ return self._add_burmese_calendar_holiday(
181
+ name, self._burmese_calendar.tabaung_full_moon_date(self._year - 1)
182
+ )
183
+
184
+ def _add_tazaungmon_full_moon_day(self, name: str) -> Optional[date]:
185
+ """Add Full Moon Day of Tazaungmon holiday.
186
+
187
+ The Tazaungdaing Festival, also known as the Festival of Lights, held on the full moon day
188
+ of Tazaungmon, the eighth month of the Burmese calendar.
189
+ https://en.wikipedia.org/wiki/Tazaungdaing_festival
190
+
191
+ Args:
192
+ name:
193
+ Holiday name.
194
+
195
+ Returns:
196
+ Date of added holiday, `None` if there is no holiday date for the current year.
197
+ """
198
+ return self._add_burmese_calendar_holiday(
199
+ name, self._burmese_calendar.tazaungmon_full_moon_date(self._year)
200
+ )
201
+
202
+ def _add_thadingyut_full_moon_eve(self, name: str) -> Optional[date]:
203
+ """Add Pre-Full Moon Day of Thadingyut holiday.
204
+
205
+ The Thadingyut Festival, also known as the Lighting Festival of Myanmar, is held
206
+ on the full moon day of the Burmese lunar month of Thadingyut.
207
+ https://en.wikipedia.org/wiki/Thadingyut_Festival
208
+
209
+ Args:
210
+ name:
211
+ Holiday name.
212
+
213
+ Returns:
214
+ Date of added holiday, `None` if there is no holiday date for the current year.
215
+ """
216
+ return self._add_burmese_calendar_holiday(
217
+ name, self._burmese_calendar.thadingyut_full_moon_date(self._year), days_delta=-1
218
+ )
219
+
220
+ def _add_thadingyut_full_moon_day(self, name: str) -> Optional[date]:
221
+ """Add Full Moon Day of Thadingyut holiday.
222
+
223
+ The Thadingyut Festival, also known as the Lighting Festival of Myanmar, is held
224
+ on the full moon day of the Burmese lunar month of Thadingyut.
225
+ https://en.wikipedia.org/wiki/Thadingyut_Festival
226
+
227
+ Args:
228
+ name:
229
+ Holiday name.
230
+
231
+ Returns:
232
+ Date of added holiday, `None` if there is no holiday date for the current year.
233
+ """
234
+ return self._add_burmese_calendar_holiday(
235
+ name, self._burmese_calendar.thadingyut_full_moon_date(self._year)
236
+ )
237
+
238
+ def _add_thadingyut_full_moon_day_two(self, name: str) -> Optional[date]:
239
+ """Add Post-Full Moon Day of Thadingyut holiday.
240
+
241
+ The Thadingyut Festival, also known as the Lighting Festival of Myanmar, is held
242
+ on the full moon day of the Burmese lunar month of Thadingyut.
243
+ https://en.wikipedia.org/wiki/Thadingyut_Festival
244
+
245
+ Args:
246
+ name:
247
+ Holiday name.
248
+
249
+ Returns:
250
+ Date of added holiday, `None` if there is no holiday date for the current year.
251
+ """
252
+ return self._add_burmese_calendar_holiday(
253
+ name, self._burmese_calendar.thadingyut_full_moon_date(self._year), days_delta=+1
254
+ )
255
+
256
+ def _add_waso_full_moon_day(self, name: str) -> Optional[date]:
257
+ """Add Full Moon Day of Waso holiday.
258
+
259
+ Vassa is the three-month annual retreat observed by Theravada Buddhists.
260
+ Vassa lasts for three lunar months, from the Burmese month of Waso to
261
+ the Burmese month of Thadingyut.
262
+ https://en.wikipedia.org/wiki/Vassa
263
+
264
+ Args:
265
+ name:
266
+ Holiday name.
267
+
268
+ Returns:
269
+ Date of added holiday, `None` if there is no holiday date for the current year.
270
+ """
271
+ return self._add_burmese_calendar_holiday(
272
+ name, self._burmese_calendar.waso_full_moon_date(self._year)
273
+ )
@@ -14,7 +14,7 @@ from datetime import date
14
14
  from typing import Optional
15
15
 
16
16
  from holidays.calendars.chinese import _ChineseLunisolar, CHINESE_CALENDAR
17
- from holidays.calendars.gregorian import APR, DEC
17
+ from holidays.calendars.gregorian import APR
18
18
  from holidays.groups.eastern import EasternCalendarHolidays
19
19
 
20
20
 
@@ -79,20 +79,8 @@ class ChineseCalendarHolidays(EasternCalendarHolidays):
79
79
  def _dongzhi_festival(self):
80
80
  """
81
81
  Return Dongzhi Festival (Chinese Winter Solstice) date.
82
-
83
- This approximation is reliable for 1952-2099 years.
84
82
  """
85
- #
86
- if (
87
- (self._year % 4 == 0 and self._year >= 1988)
88
- or (self._year % 4 == 1 and self._year >= 2021)
89
- or (self._year % 4 == 2 and self._year >= 2058)
90
- or (self._year % 4 == 3 and self._year >= 2091)
91
- ):
92
- day = 21
93
- else:
94
- day = 22
95
- return date(self._year, DEC, day)
83
+ return self._chinese_calendar.winter_solstice_date(self._year)[0]
96
84
 
97
85
  def _add_chinese_calendar_holiday(
98
86
  self, name: str, dt_estimated: tuple[Optional[date], bool], days_delta: int = 0
@@ -195,6 +183,18 @@ class ChineseCalendarHolidays(EasternCalendarHolidays):
195
183
  name, self._chinese_calendar.lunar_new_year_date(self._year), days_delta=+4
196
184
  )
197
185
 
186
+ def _add_daeboreum_day(self, name) -> Optional[date]:
187
+ """
188
+ Add Daeboreum Day (15th day of 1st lunar month).
189
+
190
+ Daeboreum is a Korean holiday that celebrates the first full moon
191
+ of the new year of the lunar Korean calendar.
192
+ https://en.wikipedia.org/wiki/Daeboreum
193
+ """
194
+ return self._add_chinese_calendar_holiday(
195
+ name, self._chinese_calendar.lunar_new_year_date(self._year), days_delta=+14
196
+ )
197
+
198
198
  def _add_dongzhi_festival(self, name) -> Optional[date]:
199
199
  """
200
200
  Add Dongzhi Festival (Chinese Winter Solstice).
@@ -206,6 +206,19 @@ class ChineseCalendarHolidays(EasternCalendarHolidays):
206
206
  """
207
207
  return self._add_holiday(name, self._dongzhi_festival)
208
208
 
209
+ def _add_hanshi_festival(self, name) -> Optional[date]:
210
+ """
211
+ Add Hanshi Festival (105 days after Winter Solstice).
212
+
213
+ The Cold Food or Hanshi Festival is a traditional Chinese holiday. Its name
214
+ derives from the tradition of avoiding the lighting of any kind of fire,
215
+ even for the preparation of food.
216
+ https://en.wikipedia.org/wiki/Cold_Food_Festival
217
+ """
218
+ return self._add_chinese_calendar_holiday(
219
+ name, self._chinese_calendar.winter_solstice_date(self._year - 1), days_delta=+105
220
+ )
221
+
209
222
  def _add_qingming_festival(self, name) -> date:
210
223
  """
211
224
  Add Qingming Festival (15th day after the Spring Equinox).
holidays/groups/custom.py CHANGED
@@ -31,17 +31,23 @@ class StaticHolidays:
31
31
  setattr(self, attribute_name, value)
32
32
  self.has_special_holidays = True
33
33
 
34
- # Substituted holidays.
34
+ # "Substituted" labels.
35
35
  elif attribute_name.startswith("substituted_") and (
36
36
  value := getattr(cls, attribute_name, None)
37
37
  ):
38
38
  setattr(self, attribute_name, value)
39
- self.has_substituted_holidays = True
40
39
 
41
40
  # Populate substituted holidays from adjacent years.
42
41
  self.weekend_workdays = set()
43
42
  for special_public_holidays in getattr(self, "special_public_holidays", {}).values():
44
43
  for special_public_holiday in _normalize_tuple(special_public_holidays):
44
+ # Normally, special holiday is a 3 item tuple: (month, day, name).
45
+ if len(special_public_holiday) < 4: # Skip non-substituted holidays.
46
+ continue
47
+
48
+ # Handle cross-year substituted holidays.
45
49
  if len(special_public_holiday) == 5: # The fifth element is the year.
46
50
  _, _, from_month, from_day, from_year = special_public_holiday
47
51
  self.weekend_workdays.add(date(from_year, from_month, from_day))
52
+
53
+ self.has_substituted_holidays = True
@@ -10,6 +10,7 @@
10
10
  # Website: https://github.com/vacanza/holidays
11
11
  # License: MIT (see LICENSE file)
12
12
 
13
+ from collections.abc import Iterable
13
14
  from datetime import date
14
15
  from typing import Optional
15
16
 
@@ -33,15 +34,13 @@ class EasternCalendarHolidays:
33
34
 
34
35
  Adds customizable estimation label to holiday name if holiday date is an estimation.
35
36
  """
36
- estimated_label = getattr(self, "estimated_label", "%s")
37
37
  dt, is_estimated = dt_estimated
38
-
39
38
  if days_delta and dt:
40
39
  dt = _timedelta(dt, days_delta)
41
40
 
42
41
  return (
43
42
  self._add_holiday(
44
- self.tr(estimated_label) % self.tr(name)
43
+ self.tr(self.estimated_label) % self.tr(name)
45
44
  if is_estimated and show_estimated
46
45
  else name,
47
46
  dt,
@@ -49,3 +48,26 @@ class EasternCalendarHolidays:
49
48
  if dt
50
49
  else None
51
50
  )
51
+
52
+ def _add_eastern_calendar_holiday_set(
53
+ self,
54
+ name: str,
55
+ dts_estimated: Iterable[tuple[date, bool]],
56
+ show_estimated: bool = True,
57
+ days_delta: int = 0,
58
+ ) -> set[date]:
59
+ """
60
+ Add Eastern (Buddhist, Chinese, Hindu, Islamic, Mongolian) calendar holidays.
61
+
62
+ Adds customizable estimation label to holiday name if holiday date is an estimation.
63
+ """
64
+
65
+ return {
66
+ dt
67
+ for dt_estimated in dts_estimated
68
+ if (
69
+ dt := self._add_eastern_calendar_holiday(
70
+ name, dt_estimated, show_estimated, days_delta
71
+ )
72
+ )
73
+ }