holidays 0.58__py3-none-any.whl → 0.59__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 (70) hide show
  1. holidays/__init__.py +1 -1
  2. holidays/calendars/buddhist.py +4 -4
  3. holidays/calendars/chinese.py +8 -8
  4. holidays/calendars/hindu.py +4 -4
  5. holidays/calendars/islamic.py +25 -25
  6. holidays/countries/angola.py +2 -2
  7. holidays/countries/armenia.py +5 -2
  8. holidays/countries/azerbaijan.py +7 -2
  9. holidays/countries/belarus.py +1 -1
  10. holidays/countries/bosnia_and_herzegovina.py +2 -2
  11. holidays/countries/bulgaria.py +1 -2
  12. holidays/countries/chile.py +1 -2
  13. holidays/countries/czechia.py +6 -3
  14. holidays/countries/egypt.py +0 -1
  15. holidays/countries/france.py +1 -1
  16. holidays/countries/georgia.py +1 -1
  17. holidays/countries/germany.py +10 -0
  18. holidays/countries/hongkong.py +1 -2
  19. holidays/countries/japan.py +3 -4
  20. holidays/countries/jersey.py +2 -2
  21. holidays/countries/jordan.py +1 -1
  22. holidays/countries/kazakhstan.py +1 -1
  23. holidays/countries/kuwait.py +1 -1
  24. holidays/countries/kyrgyzstan.py +1 -1
  25. holidays/countries/malaysia.py +7 -1
  26. holidays/countries/mauritania.py +0 -1
  27. holidays/countries/moldova.py +4 -3
  28. holidays/countries/russia.py +1 -1
  29. holidays/countries/saudi_arabia.py +1 -2
  30. holidays/countries/slovakia.py +1 -1
  31. holidays/countries/south_korea.py +1 -2
  32. holidays/countries/taiwan.py +1 -2
  33. holidays/countries/ukraine.py +1 -3
  34. holidays/countries/united_arab_emirates.py +5 -2
  35. holidays/countries/united_kingdom.py +2 -2
  36. holidays/countries/united_states.py +2 -2
  37. holidays/countries/uzbekistan.py +2 -1
  38. holidays/countries/vietnam.py +116 -25
  39. holidays/groups/__init__.py +1 -0
  40. holidays/groups/buddhist.py +6 -11
  41. holidays/groups/chinese.py +7 -25
  42. holidays/groups/eastern.py +51 -0
  43. holidays/groups/hindu.py +6 -11
  44. holidays/groups/international.py +8 -5
  45. holidays/groups/islamic.py +39 -46
  46. holidays/holiday_base.py +31 -30
  47. holidays/locale/de/LC_MESSAGES/DE.mo +0 -0
  48. holidays/locale/de/LC_MESSAGES/DE.po +11 -4
  49. holidays/locale/en_US/LC_MESSAGES/DE.mo +0 -0
  50. holidays/locale/en_US/LC_MESSAGES/DE.po +13 -4
  51. holidays/locale/en_US/LC_MESSAGES/VN.mo +0 -0
  52. holidays/locale/en_US/LC_MESSAGES/VN.po +37 -19
  53. holidays/locale/th/LC_MESSAGES/DE.mo +0 -0
  54. holidays/locale/th/LC_MESSAGES/DE.po +11 -2
  55. holidays/locale/th/LC_MESSAGES/VN.mo +0 -0
  56. holidays/locale/th/LC_MESSAGES/VN.po +93 -0
  57. holidays/locale/uk/LC_MESSAGES/DE.mo +0 -0
  58. holidays/locale/uk/LC_MESSAGES/DE.po +13 -4
  59. holidays/locale/vi/LC_MESSAGES/VN.mo +0 -0
  60. holidays/locale/vi/LC_MESSAGES/VN.po +32 -14
  61. holidays/mixins.py +1 -4
  62. holidays/observed_holiday_base.py +5 -5
  63. holidays/registry.py +4 -3
  64. holidays/utils.py +8 -7
  65. {holidays-0.58.dist-info → holidays-0.59.dist-info}/METADATA +22 -38
  66. {holidays-0.58.dist-info → holidays-0.59.dist-info}/RECORD +70 -67
  67. {holidays-0.58.dist-info → holidays-0.59.dist-info}/WHEEL +1 -1
  68. {holidays-0.58.dist-info → holidays-0.59.dist-info}/AUTHORS +0 -0
  69. {holidays-0.58.dist-info → holidays-0.59.dist-info}/LICENSE +0 -0
  70. {holidays-0.58.dist-info → holidays-0.59.dist-info}/top_level.txt +0 -0
@@ -12,7 +12,6 @@
12
12
 
13
13
  from datetime import date
14
14
  from gettext import gettext as tr
15
- from typing import Set
16
15
 
17
16
  from holidays.calendars.gregorian import (
18
17
  JAN,
@@ -80,7 +79,7 @@ class Taiwan(ObservedHolidayBase, ChineseCalendarHolidays, InternationalHolidays
80
79
  super().__init__(*args, **kwargs)
81
80
 
82
81
  def _populate_observed(
83
- self, dts: Set[date], rule: ObservedRule = None, since: int = 2015
82
+ self, dts: set[date], rule: ObservedRule = None, since: int = 2015
84
83
  ) -> None:
85
84
  if self._year < since:
86
85
  return None
@@ -103,9 +103,7 @@ class Ukraine(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, Sta
103
103
  else tr("День перемоги")
104
104
  )
105
105
  dts_observed.add(
106
- self._add_holiday_may_8(name)
107
- if self._year >= 2024
108
- else self._add_world_war_two_victory_day(name)
106
+ self._add_world_war_two_victory_day(name, is_western=(self._year >= 2024))
109
107
  )
110
108
 
111
109
  if self._year >= 1997:
@@ -13,7 +13,7 @@
13
13
  from gettext import gettext as tr
14
14
 
15
15
  from holidays.calendars import _CustomIslamicHolidays
16
- from holidays.calendars.gregorian import APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, FRI, SAT
16
+ from holidays.calendars.gregorian import APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, FRI, SAT, SUN
17
17
  from holidays.groups import InternationalHolidays, IslamicHolidays
18
18
  from holidays.holiday_base import HolidayBase
19
19
 
@@ -35,7 +35,6 @@ class UnitedArabEmirates(HolidayBase, InternationalHolidays, IslamicHolidays):
35
35
  # %s (estimated).
36
36
  estimated_label = tr("(تقدير) %s")
37
37
  supported_languages = ("ar", "en_US")
38
- weekend = {FRI, SAT}
39
38
 
40
39
  def __init__(self, *args, **kwargs):
41
40
  InternationalHolidays.__init__(self)
@@ -43,6 +42,10 @@ class UnitedArabEmirates(HolidayBase, InternationalHolidays, IslamicHolidays):
43
42
  super().__init__(*args, **kwargs)
44
43
 
45
44
  def _populate_public_holidays(self):
45
+ # The resting days are Saturday and Sunday since Jan 1, 2022.
46
+ # https://time.com/6126260/uae-working-days-weekend/
47
+ self.weekend = {FRI, SAT} if self._year <= 2021 else {SAT, SUN}
48
+
46
49
  # New Year's Day.
47
50
  self._add_new_years_day(tr("رأس السنة الميلادية"))
48
51
 
@@ -10,7 +10,7 @@
10
10
  # Website: https://github.com/vacanza/holidays
11
11
  # License: MIT (see LICENSE file)
12
12
 
13
- from typing import Tuple, Union
13
+ from typing import Union
14
14
 
15
15
  from holidays.calendars.gregorian import APR, MAY, JUN, JUL, SEP, DEC
16
16
  from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays
@@ -38,7 +38,7 @@ class UnitedKingdom(ObservedHolidayBase, ChristianHolidays, InternationalHoliday
38
38
 
39
39
  country = "GB"
40
40
  observed_label = "%s (observed)"
41
- subdivisions: Union[Tuple[()], Tuple[str, ...]] = (
41
+ subdivisions: Union[tuple[()], tuple[str, ...]] = (
42
42
  "ENG", # England
43
43
  "NIR", # Northern Ireland
44
44
  "SCT", # Scotland
@@ -10,7 +10,7 @@
10
10
  # Website: https://github.com/vacanza/holidays
11
11
  # License: MIT (see LICENSE file)
12
12
 
13
- from typing import Tuple, Union
13
+ from typing import Union
14
14
 
15
15
  from holidays.calendars.gregorian import MON, TUE, WED, THU, FRI, SAT, SUN
16
16
  from holidays.constants import PUBLIC, UNOFFICIAL
@@ -62,7 +62,7 @@ class UnitedStates(ObservedHolidayBase, ChristianHolidays, InternationalHolidays
62
62
  country = "US"
63
63
  supported_categories = (PUBLIC, UNOFFICIAL)
64
64
  observed_label = "%s (observed)"
65
- subdivisions: Union[Tuple[()], Tuple[str, ...]] = (
65
+ subdivisions: Union[tuple[()], tuple[str, ...]] = (
66
66
  "AK", # Alaska.
67
67
  "AL", # Alabama.
68
68
  "AR", # Arkansas.
@@ -68,7 +68,8 @@ class Uzbekistan(ObservedHolidayBase, InternationalHolidays, IslamicHolidays, St
68
68
  tr("Xotira va qadrlash kuni")
69
69
  if self._year >= 1999
70
70
  # Victory Day.
71
- else tr("G‘alaba kuni")
71
+ else tr("G‘alaba kuni"),
72
+ is_western=False,
72
73
  )
73
74
  )
74
75
 
@@ -10,69 +10,135 @@
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
- from holidays.groups import ChineseCalendarHolidays, InternationalHolidays
16
- from holidays.observed_holiday_base import ObservedHolidayBase, SAT_SUN_TO_NEXT_WORKDAY
17
-
18
-
19
- class Vietnam(ObservedHolidayBase, ChineseCalendarHolidays, InternationalHolidays):
16
+ from holidays.calendars.gregorian import (
17
+ JAN,
18
+ FEB,
19
+ APR,
20
+ MAY,
21
+ SEP,
22
+ DEC,
23
+ MON,
24
+ TUE,
25
+ WED,
26
+ THU,
27
+ FRI,
28
+ SAT,
29
+ SUN,
30
+ _timedelta,
31
+ )
32
+ from holidays.groups import ChineseCalendarHolidays, InternationalHolidays, StaticHolidays
33
+ from holidays.observed_holiday_base import (
34
+ ObservedHolidayBase,
35
+ ObservedRule,
36
+ SAT_TO_PREV_WORKDAY,
37
+ SUN_TO_NEXT_WORKDAY,
38
+ SAT_SUN_TO_NEXT_WORKDAY,
39
+ )
40
+
41
+ NATIONAL_DAY_RULE = ObservedRule({MON: +1, TUE: -1, WED: -1, THU: +1, FRI: -1, SAT: -1, SUN: +1})
42
+
43
+
44
+ class Vietnam(ObservedHolidayBase, ChineseCalendarHolidays, InternationalHolidays, StaticHolidays):
20
45
  """
21
- https://publicholidays.vn/
22
- http://vbpl.vn/TW/Pages/vbpqen-toanvan.aspx?ItemID=11013 Article.115
23
- https://www.timeanddate.com/holidays/vietnam/
46
+ References:
47
+ - `Labor Code 1994 (Art. 73) (en) <https://vbpl.vn/TW/Pages/vbpqen-toanvan.aspx?ItemID=2835>`_
48
+ - `Labor Code 2012 (Art. 115) (en) <https://vbpl.vn/TW/Pages/vbpqen-toanvan.aspx?ItemID=11013>`_
49
+ - `Labor Code 2012 (Art. 115) (vi) <https://vbpl.vn/TW/Pages/vbpq-toanvan.aspx?ItemID=27615>`_
50
+ - `Labor Code 2019 (Art. 112) (en) <https://vbpl.vn/TW/Pages/vbpqen-toanvan.aspx?ItemID=11135>`_
51
+ - `Labor Code 2019 (Art. 112) (vi) <https://vbpl.vn/TW/Pages/vbpq-van-ban-goc.aspx?ItemID=139264>`_
52
+
53
+ Substituted holidays:
54
+ - `2018-2019 <https://thuvienphapluat.vn/cong-van/EN/Lao-dong-Tien-luong/Official-Dispatch-6519-VPCP-KGVX-2018-national-holidays-for-public-sector-employees/387625/tieng-anh.aspx>`_
55
+ - `2024 <https://thuvienphapluat.vn/cong-van/EN/Lao-dong-Tien-luong/Official-Dispatch-2450-VPCP-KGVX-2024-swap-of-working-days-during-the-Reunification-Day/606458/tieng-anh.aspx>`_
24
56
  """
25
57
 
26
58
  country = "VN"
27
59
  # %s (observed).
28
60
  observed_label = tr("%s (nghỉ bù)")
29
61
  default_language = "vi"
30
- supported_languages = ("en_US", "vi")
62
+ supported_languages = ("en_US", "th", "vi")
31
63
 
32
64
  def __init__(self, *args, **kwargs):
33
65
  ChineseCalendarHolidays.__init__(self)
34
66
  InternationalHolidays.__init__(self)
67
+ StaticHolidays.__init__(self, VietnamStaticHolidays)
35
68
  kwargs.setdefault("observed_rule", SAT_SUN_TO_NEXT_WORKDAY)
69
+ kwargs.setdefault("observed_since", 1995)
36
70
  super().__init__(*args, **kwargs)
37
71
 
72
+ def _add_lunar_new_year_observed(self, dt_lny: date) -> None:
73
+ if self._year <= 1994:
74
+ return None
75
+
76
+ day_names = {
77
+ # 29 of Lunar New Year.
78
+ -2: tr("29 Tết"),
79
+ # Fourth Day of Lunar New Year.
80
+ 3: tr("Mùng bốn Tết Nguyên Đán"),
81
+ # Fifth Day of Lunar New Year.
82
+ 4: tr("Mùng năm Tết Nguyên Đán"),
83
+ # Sixth Day of Lunar New Year.
84
+ 5: tr("Mùng sáu Tết Nguyên Đán"),
85
+ }
86
+ for delta in range(-1, 4 if self._year >= 2013 else 3):
87
+ dt = _timedelta(dt_lny, delta)
88
+ dt_observed = self._get_observed_date(
89
+ dt,
90
+ rule=(
91
+ SAT_TO_PREV_WORKDAY + SUN_TO_NEXT_WORKDAY
92
+ if self._year >= 2014
93
+ else SAT_SUN_TO_NEXT_WORKDAY
94
+ ),
95
+ )
96
+ if dt_observed != dt:
97
+ self._add_holiday(
98
+ day_names[(dt_observed - dt_lny).days], # type: ignore[operator]
99
+ dt_observed,
100
+ )
101
+
38
102
  def _populate_public_holidays(self):
39
103
  dts_observed = set()
40
104
 
41
- # New Year's Day
105
+ # New Year's Day.
42
106
  dts_observed.add(self._add_new_years_day(tr("Tết Dương lịch")))
43
107
 
44
- # Lunar New Year's Eve
108
+ # Lunar New Year's Eve.
45
109
  self._add_chinese_new_years_eve(tr("Giao thừa Tết Nguyên Đán"))
46
110
 
47
- # Lunar New Year
48
- self._add_chinese_new_years_day(tr("Tết Nguyên Đán"))
111
+ # Lunar New Year.
112
+ lny = self._add_chinese_new_years_day(tr("Tết Nguyên Đán"))
49
113
 
50
- # Second Day of Lunar New Year
114
+ # Second Day of Lunar New Year.
51
115
  self._add_chinese_new_years_day_two(tr("Mùng hai Tết Nguyên Đán"))
52
116
 
53
- # Third Day of Lunar New Year
117
+ # Third Day of Lunar New Year.
54
118
  self._add_chinese_new_years_day_three(tr("Mùng ba Tết Nguyên Đán"))
55
119
 
56
- # Fourth Day of Lunar New Year
57
- self._add_chinese_new_years_day_four(tr("Mùng bốn Tết Nguyên Đán"))
58
-
59
- # Fifth Day of Lunar New Year
60
- self._add_chinese_new_years_day_five(tr("Mùng năm Tết Nguyên Đán"))
120
+ if self._year >= 2013:
121
+ # Fourth Day of Lunar New Year.
122
+ self._add_chinese_new_years_day_four(tr("Mùng bốn Tết Nguyên Đán"))
61
123
 
62
124
  if self._year >= 2007:
63
- # Hung Kings' Commemoration Day
125
+ # Hung Kings' Commemoration Day.
64
126
  dts_observed.add(self._add_hung_kings_day(tr("Ngày Giỗ Tổ Hùng Vương")))
65
127
 
66
- # Liberation Day/Reunification Day
128
+ # Liberation Day/Reunification Day.
67
129
  dts_observed.add(self._add_holiday_apr_30(tr("Ngày Chiến thắng")))
68
130
 
69
- # International Labor Day
131
+ # International Labor Day.
70
132
  dts_observed.add(self._add_labor_day(tr("Ngày Quốc tế Lao động")))
71
133
 
72
- # National Day
73
- dts_observed.add(self._add_holiday_sep_2(tr("Quốc khánh")))
134
+ # National Day.
135
+ name = tr("Quốc khánh")
136
+ dts_observed.add(sep_2 := self._add_holiday_sep_2(name))
137
+ if self._year >= 2021:
138
+ self._add_holiday(name, self._get_observed_date(sep_2, NATIONAL_DAY_RULE))
74
139
 
75
140
  if self.observed:
141
+ self._add_lunar_new_year_observed(lny)
76
142
  self._populate_observed(dts_observed)
77
143
 
78
144
 
@@ -82,3 +148,28 @@ class VN(Vietnam):
82
148
 
83
149
  class VNM(Vietnam):
84
150
  pass
151
+
152
+
153
+ class VietnamStaticHolidays:
154
+ # Date format (see strftime() Format Codes).
155
+ substituted_date_format = tr("%d/%m/%Y")
156
+ # Day off (substituted from %s).
157
+ substituted_label = tr("Ngày nghỉ (thay cho ngày %s)")
158
+
159
+ special_public_holidays = {
160
+ 2010: (FEB, 19, FEB, 27),
161
+ 2012: (JAN, 27, FEB, 4),
162
+ 2013: (APR, 29, MAY, 4),
163
+ 2014: (
164
+ (MAY, 2, APR, 26),
165
+ (SEP, 1, SEP, 6),
166
+ ),
167
+ 2015: (
168
+ (JAN, 2, DEC, 27, 2014),
169
+ (FEB, 16, FEB, 14),
170
+ (APR, 29, APR, 25),
171
+ ),
172
+ 2018: (DEC, 31, JAN, 5, 2019),
173
+ 2019: (APR, 29, MAY, 4),
174
+ 2024: (APR, 29, MAY, 4),
175
+ }
@@ -16,6 +16,7 @@ from holidays.groups.buddhist import BuddhistCalendarHolidays
16
16
  from holidays.groups.chinese import ChineseCalendarHolidays
17
17
  from holidays.groups.christian import ChristianHolidays
18
18
  from holidays.groups.custom import StaticHolidays
19
+ from holidays.groups.eastern import EasternCalendarHolidays
19
20
  from holidays.groups.hindu import HinduCalendarHolidays
20
21
  from holidays.groups.international import InternationalHolidays
21
22
  from holidays.groups.islamic import IslamicHolidays
@@ -11,12 +11,13 @@
11
11
  # License: MIT (see LICENSE file)
12
12
 
13
13
  from datetime import date
14
- from typing import Optional, Tuple
14
+ from typing import Optional
15
15
 
16
16
  from holidays.calendars import _BuddhistLunisolar
17
+ from holidays.groups.eastern import EasternCalendarHolidays
17
18
 
18
19
 
19
- class BuddhistCalendarHolidays:
20
+ class BuddhistCalendarHolidays(EasternCalendarHolidays):
20
21
  """
21
22
  Buddhist lunisolar calendar holidays.
22
23
  """
@@ -26,7 +27,7 @@ class BuddhistCalendarHolidays:
26
27
  self._buddhist_calendar_show_estimated = show_estimated
27
28
 
28
29
  def _add_buddhist_calendar_holiday(
29
- self, name: str, dt_estimated: Tuple[date, bool]
30
+ self, name: str, dt_estimated: tuple[Optional[date], bool]
30
31
  ) -> Optional[date]:
31
32
  """
32
33
  Add Buddhist calendar holiday.
@@ -34,14 +35,8 @@ class BuddhistCalendarHolidays:
34
35
  Adds customizable estimation label to holiday name if holiday date
35
36
  is an estimation.
36
37
  """
37
- estimated_label = getattr(self, "estimated_label", "%s (estimated)")
38
- dt, is_estimated = dt_estimated
39
-
40
- return self._add_holiday(
41
- self.tr(estimated_label) % self.tr(name)
42
- if is_estimated and self._buddhist_calendar_show_estimated
43
- else name,
44
- dt,
38
+ return self._add_eastern_calendar_holiday(
39
+ name, dt_estimated, self._buddhist_calendar_show_estimated
45
40
  )
46
41
 
47
42
  def _add_vesak(self, name) -> Optional[date]:
@@ -11,13 +11,14 @@
11
11
  # License: MIT (see LICENSE file)
12
12
 
13
13
  from datetime import date
14
- from typing import Optional, Tuple
14
+ from typing import Optional
15
15
 
16
16
  from holidays.calendars import _ChineseLunisolar
17
- from holidays.calendars.gregorian import APR, _timedelta
17
+ from holidays.calendars.gregorian import APR
18
+ from holidays.groups.eastern import EasternCalendarHolidays
18
19
 
19
20
 
20
- class ChineseCalendarHolidays:
21
+ class ChineseCalendarHolidays(EasternCalendarHolidays):
21
22
  """
22
23
  Chinese lunisolar calendar holidays.
23
24
  """
@@ -48,7 +49,7 @@ class ChineseCalendarHolidays:
48
49
  return self._chinese_calendar.mid_autumn_date(self._year)[0]
49
50
 
50
51
  def _add_chinese_calendar_holiday(
51
- self, name: str, dt_estimated: Tuple[date, bool], days_delta: int = 0
52
+ self, name: str, dt_estimated: tuple[Optional[date], bool], days_delta: int = 0
52
53
  ) -> Optional[date]:
53
54
  """
54
55
  Add Chinese calendar holiday.
@@ -56,17 +57,8 @@ class ChineseCalendarHolidays:
56
57
  Adds customizable estimation label to holiday name if holiday date
57
58
  is an estimation.
58
59
  """
59
- estimated_label = getattr(self, "estimated_label", "%s (estimated)")
60
- dt, is_estimated = dt_estimated
61
-
62
- if days_delta != 0:
63
- dt = _timedelta(dt, days_delta)
64
-
65
- return self._add_holiday(
66
- self.tr(estimated_label) % self.tr(name)
67
- if is_estimated and self._chinese_calendar_show_estimated
68
- else name,
69
- dt,
60
+ return self._add_eastern_calendar_holiday(
61
+ name, dt_estimated, self._chinese_calendar_show_estimated, days_delta
70
62
  )
71
63
 
72
64
  def _add_chinese_birthday_of_buddha(self, name) -> Optional[date]:
@@ -136,16 +128,6 @@ class ChineseCalendarHolidays:
136
128
  name, self._chinese_calendar.lunar_new_year_date(self._year), days_delta=+3
137
129
  )
138
130
 
139
- def _add_chinese_new_years_day_five(self, name) -> Optional[date]:
140
- """
141
- Add Chinese New Year's Day Five.
142
-
143
- https://en.wikipedia.org/wiki/Chinese_New_Year
144
- """
145
- return self._add_chinese_calendar_holiday(
146
- name, self._chinese_calendar.lunar_new_year_date(self._year), days_delta=+4
147
- )
148
-
149
131
  def _add_qingming_festival(self, name) -> date:
150
132
  """
151
133
  Add Qingming Festival (15th day after the Spring Equinox).
@@ -0,0 +1,51 @@
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 AUTHORS 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.gregorian import _timedelta
17
+
18
+
19
+ class EasternCalendarHolidays:
20
+ """
21
+ Eastern calendar holidays base class.
22
+ """
23
+
24
+ def _add_eastern_calendar_holiday(
25
+ self,
26
+ name: str,
27
+ dt_estimated: tuple[Optional[date], bool],
28
+ show_estimated: bool = True,
29
+ days_delta: int = 0,
30
+ ) -> Optional[date]:
31
+ """
32
+ Add Eastern (Buddhist, Chinese, Hindu, Islamic) calendar holiday.
33
+
34
+ Adds customizable estimation label to holiday name if holiday date is an estimation.
35
+ """
36
+ estimated_label = getattr(self, "estimated_label", "%s (estimated)")
37
+ dt, is_estimated = dt_estimated
38
+
39
+ if days_delta and dt:
40
+ dt = _timedelta(dt, days_delta)
41
+
42
+ return (
43
+ self._add_holiday(
44
+ self.tr(estimated_label) % self.tr(name)
45
+ if is_estimated and show_estimated
46
+ else name,
47
+ dt,
48
+ )
49
+ if dt
50
+ else None
51
+ )
holidays/groups/hindu.py CHANGED
@@ -11,12 +11,13 @@
11
11
  # License: MIT (see LICENSE file)
12
12
 
13
13
  from datetime import date
14
- from typing import Optional, Tuple
14
+ from typing import Optional
15
15
 
16
16
  from holidays.calendars import _HinduLunisolar
17
+ from holidays.groups.eastern import EasternCalendarHolidays
17
18
 
18
19
 
19
- class HinduCalendarHolidays:
20
+ class HinduCalendarHolidays(EasternCalendarHolidays):
20
21
  """
21
22
  Hindu lunisolar calendar holidays.
22
23
  """
@@ -26,7 +27,7 @@ class HinduCalendarHolidays:
26
27
  self._hindu_calendar_show_estimated = show_estimated
27
28
 
28
29
  def _add_hindu_calendar_holiday(
29
- self, name: str, dt_estimated: Tuple[date, bool]
30
+ self, name: str, dt_estimated: tuple[Optional[date], bool]
30
31
  ) -> Optional[date]:
31
32
  """
32
33
  Add Hindu calendar holiday.
@@ -34,14 +35,8 @@ class HinduCalendarHolidays:
34
35
  Adds customizable estimation label to holiday name if holiday date
35
36
  is an estimation.
36
37
  """
37
- estimated_label = getattr(self, "estimated_label", "%s (estimated)")
38
- dt, is_estimated = dt_estimated
39
-
40
- return self._add_holiday(
41
- self.tr(estimated_label) % self.tr(name)
42
- if is_estimated and self._hindu_calendar_show_estimated
43
- else name,
44
- dt,
38
+ return self._add_eastern_calendar_holiday(
39
+ name, dt_estimated, self._hindu_calendar_show_estimated
45
40
  )
46
41
 
47
42
  def _add_diwali(self, name) -> Optional[date]:
@@ -185,15 +185,18 @@ class InternationalHolidays:
185
185
  """
186
186
  return self._add_holiday_mar_8(name)
187
187
 
188
- def _add_world_war_two_victory_day(self, name):
188
+ def _add_world_war_two_victory_day(self, name, is_western=True):
189
189
  """
190
- Add Victory Day (May 9th)
190
+ Add Day of Victory in World War II in Europe (May 8).
191
+ https://en.wikipedia.org/wiki/Victory_in_Europe_Day
191
192
 
192
- Victory Day is a holiday that commemorates the victory over Nazi
193
- Germany in 1945.
193
+ Some Eastern European countries celebrate Victory Day on May 9.
194
194
  https://en.wikipedia.org/wiki/Victory_Day_(9_May)
195
195
  """
196
- return self._add_holiday_may_9(name)
196
+ if is_western:
197
+ return self._add_holiday_may_8(name)
198
+ else:
199
+ return self._add_holiday_may_9(name)
197
200
 
198
201
  def _add_united_nations_day(self, name):
199
202
  """