holidays 0.69__py3-none-any.whl → 0.71__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 (249) hide show
  1. holidays/__init__.py +1 -1
  2. holidays/calendars/__init__.py +1 -1
  3. holidays/calendars/balinese_saka.py +3 -3
  4. holidays/calendars/buddhist.py +1 -1
  5. holidays/calendars/chinese.py +1 -1
  6. holidays/calendars/custom.py +1 -1
  7. holidays/calendars/gregorian.py +1 -1
  8. holidays/calendars/hebrew.py +1 -1
  9. holidays/calendars/hindu.py +1 -1
  10. holidays/calendars/islamic.py +161 -1
  11. holidays/calendars/julian.py +1 -1
  12. holidays/calendars/julian_revised.py +1 -1
  13. holidays/calendars/persian.py +1 -1
  14. holidays/calendars/sinhala.py +1 -1
  15. holidays/calendars/thai.py +309 -257
  16. holidays/constants.py +2 -1
  17. holidays/countries/__init__.py +10 -1
  18. holidays/countries/afghanistan.py +11 -7
  19. holidays/countries/albania.py +10 -7
  20. holidays/countries/algeria.py +10 -10
  21. holidays/countries/american_samoa.py +6 -4
  22. holidays/countries/andorra.py +5 -4
  23. holidays/countries/angola.py +15 -14
  24. holidays/countries/antigua_and_barbuda.py +145 -0
  25. holidays/countries/argentina.py +787 -169
  26. holidays/countries/armenia.py +5 -6
  27. holidays/countries/aruba.py +11 -9
  28. holidays/countries/australia.py +21 -20
  29. holidays/countries/austria.py +3 -1
  30. holidays/countries/azerbaijan.py +24 -19
  31. holidays/countries/bahamas.py +13 -11
  32. holidays/countries/bahrain.py +8 -7
  33. holidays/countries/bangladesh.py +5 -4
  34. holidays/countries/barbados.py +11 -9
  35. holidays/countries/belarus.py +15 -15
  36. holidays/countries/belgium.py +8 -6
  37. holidays/countries/belize.py +7 -6
  38. holidays/countries/bolivia.py +12 -11
  39. holidays/countries/bosnia_and_herzegovina.py +15 -11
  40. holidays/countries/botswana.py +8 -6
  41. holidays/countries/brazil.py +8 -7
  42. holidays/countries/brunei.py +50 -62
  43. holidays/countries/bulgaria.py +9 -10
  44. holidays/countries/burkina_faso.py +8 -5
  45. holidays/countries/burundi.py +13 -12
  46. holidays/countries/cambodia.py +15 -24
  47. holidays/countries/cameroon.py +10 -7
  48. holidays/countries/canada.py +13 -12
  49. holidays/countries/chad.py +9 -6
  50. holidays/countries/chile.py +29 -28
  51. holidays/countries/china.py +39 -38
  52. holidays/countries/colombia.py +15 -20
  53. holidays/countries/congo.py +6 -7
  54. holidays/countries/costa_rica.py +11 -10
  55. holidays/countries/croatia.py +8 -5
  56. holidays/countries/cuba.py +30 -27
  57. holidays/countries/curacao.py +6 -4
  58. holidays/countries/cyprus.py +4 -5
  59. holidays/countries/czechia.py +7 -6
  60. holidays/countries/denmark.py +5 -6
  61. holidays/countries/djibouti.py +7 -3
  62. holidays/countries/dominica.py +18 -16
  63. holidays/countries/dominican_republic.py +6 -4
  64. holidays/countries/ecuador.py +5 -4
  65. holidays/countries/egypt.py +6 -11
  66. holidays/countries/el_salvador.py +6 -5
  67. holidays/countries/estonia.py +3 -1
  68. holidays/countries/eswatini.py +6 -4
  69. holidays/countries/ethiopia.py +20 -11
  70. holidays/countries/fiji.py +183 -0
  71. holidays/countries/finland.py +11 -10
  72. holidays/countries/france.py +7 -10
  73. holidays/countries/french_southern_territories.py +53 -0
  74. holidays/countries/gabon.py +11 -8
  75. holidays/countries/georgia.py +7 -7
  76. holidays/countries/germany.py +11 -11
  77. holidays/countries/ghana.py +10 -6
  78. holidays/countries/greece.py +4 -5
  79. holidays/countries/greenland.py +5 -6
  80. holidays/countries/guam.py +6 -4
  81. holidays/countries/guatemala.py +7 -9
  82. holidays/countries/guernsey.py +37 -34
  83. holidays/countries/guinea.py +182 -0
  84. holidays/countries/haiti.py +6 -5
  85. holidays/countries/honduras.py +8 -4
  86. holidays/countries/hongkong.py +11 -8
  87. holidays/countries/hungary.py +26 -23
  88. holidays/countries/iceland.py +5 -4
  89. holidays/countries/india.py +14 -10
  90. holidays/countries/indonesia.py +57 -53
  91. holidays/countries/iran.py +12 -9
  92. holidays/countries/ireland.py +5 -4
  93. holidays/countries/isle_of_man.py +2 -2
  94. holidays/countries/israel.py +4 -5
  95. holidays/countries/italy.py +5 -4
  96. holidays/countries/ivory_coast.py +156 -0
  97. holidays/countries/jamaica.py +6 -4
  98. holidays/countries/japan.py +5 -5
  99. holidays/countries/jersey.py +29 -26
  100. holidays/countries/jordan.py +9 -6
  101. holidays/countries/kazakhstan.py +66 -51
  102. holidays/countries/kenya.py +22 -18
  103. holidays/countries/kuwait.py +10 -7
  104. holidays/countries/kyrgyzstan.py +7 -6
  105. holidays/countries/laos.py +21 -29
  106. holidays/countries/latvia.py +7 -5
  107. holidays/countries/lesotho.py +6 -5
  108. holidays/countries/liechtenstein.py +5 -5
  109. holidays/countries/lithuania.py +4 -5
  110. holidays/countries/luxembourg.py +5 -3
  111. holidays/countries/macau.py +32 -26
  112. holidays/countries/madagascar.py +5 -4
  113. holidays/countries/malawi.py +6 -4
  114. holidays/countries/malaysia.py +29 -19
  115. holidays/countries/maldives.py +10 -7
  116. holidays/countries/malta.py +10 -19
  117. holidays/countries/marshall_islands.py +6 -4
  118. holidays/countries/mauritania.py +9 -6
  119. holidays/countries/mexico.py +8 -7
  120. holidays/countries/moldova.py +6 -4
  121. holidays/countries/monaco.py +6 -4
  122. holidays/countries/montenegro.py +10 -7
  123. holidays/countries/morocco.py +9 -8
  124. holidays/countries/mozambique.py +3 -1
  125. holidays/countries/namibia.py +7 -5
  126. holidays/countries/netherlands.py +6 -6
  127. holidays/countries/new_zealand.py +3 -1
  128. holidays/countries/nicaragua.py +6 -5
  129. holidays/countries/nigeria.py +9 -5
  130. holidays/countries/north_macedonia.py +9 -5
  131. holidays/countries/northern_mariana_islands.py +6 -4
  132. holidays/countries/norway.py +15 -15
  133. holidays/countries/oman.py +185 -0
  134. holidays/countries/pakistan.py +48 -17
  135. holidays/countries/palau.py +13 -11
  136. holidays/countries/panama.py +9 -8
  137. holidays/countries/papua_new_guinea.py +25 -21
  138. holidays/countries/paraguay.py +10 -9
  139. holidays/countries/peru.py +4 -5
  140. holidays/countries/philippines.py +25 -21
  141. holidays/countries/poland.py +6 -5
  142. holidays/countries/portugal.py +13 -15
  143. holidays/countries/puerto_rico.py +6 -4
  144. holidays/countries/qatar.py +172 -0
  145. holidays/countries/romania.py +6 -4
  146. holidays/countries/russia.py +6 -4
  147. holidays/countries/saint_kitts_and_nevis.py +24 -22
  148. holidays/countries/saint_lucia.py +8 -7
  149. holidays/countries/samoa.py +7 -6
  150. holidays/countries/san_marino.py +4 -3
  151. holidays/countries/saudi_arabia.py +11 -15
  152. holidays/countries/serbia.py +3 -4
  153. holidays/countries/seychelles.py +22 -26
  154. holidays/countries/sierra_leone.py +149 -0
  155. holidays/countries/singapore.py +29 -39
  156. holidays/countries/slovakia.py +6 -5
  157. holidays/countries/slovenia.py +7 -6
  158. holidays/countries/south_africa.py +8 -6
  159. holidays/countries/south_korea.py +39 -47
  160. holidays/countries/spain.py +25 -24
  161. holidays/countries/sri_lanka.py +46 -42
  162. holidays/countries/suriname.py +227 -0
  163. holidays/countries/sweden.py +20 -19
  164. holidays/countries/switzerland.py +6 -5
  165. holidays/countries/taiwan.py +52 -49
  166. holidays/countries/tanzania.py +28 -27
  167. holidays/countries/thailand.py +134 -142
  168. holidays/countries/timor_leste.py +20 -18
  169. holidays/countries/tonga.py +46 -42
  170. holidays/countries/tunisia.py +5 -3
  171. holidays/countries/turkey.py +11 -9
  172. holidays/countries/tuvalu.py +12 -11
  173. holidays/countries/ukraine.py +54 -54
  174. holidays/countries/united_arab_emirates.py +37 -30
  175. holidays/countries/united_kingdom.py +7 -6
  176. holidays/countries/united_states.py +50 -55
  177. holidays/countries/united_states_minor_outlying_islands.py +6 -4
  178. holidays/countries/united_states_virgin_islands.py +6 -4
  179. holidays/countries/uruguay.py +10 -9
  180. holidays/countries/uzbekistan.py +10 -7
  181. holidays/countries/vanuatu.py +7 -5
  182. holidays/countries/vatican_city.py +16 -15
  183. holidays/countries/venezuela.py +11 -14
  184. holidays/countries/vietnam.py +15 -11
  185. holidays/countries/zambia.py +8 -6
  186. holidays/countries/zimbabwe.py +6 -4
  187. holidays/deprecations/v1_incompatibility.py +1 -1
  188. holidays/financial/__init__.py +1 -1
  189. holidays/financial/brasil_bolsa_balcao.py +14 -13
  190. holidays/financial/european_central_bank.py +7 -6
  191. holidays/financial/ice_futures_europe.py +7 -6
  192. holidays/financial/ny_stock_exchange.py +13 -10
  193. holidays/groups/__init__.py +1 -1
  194. holidays/groups/balinese_saka.py +1 -1
  195. holidays/groups/buddhist.py +1 -1
  196. holidays/groups/chinese.py +1 -1
  197. holidays/groups/christian.py +1 -1
  198. holidays/groups/custom.py +1 -1
  199. holidays/groups/eastern.py +1 -1
  200. holidays/groups/hebrew.py +1 -1
  201. holidays/groups/hindu.py +1 -1
  202. holidays/groups/international.py +1 -1
  203. holidays/groups/islamic.py +22 -1
  204. holidays/groups/persian.py +1 -1
  205. holidays/groups/sinhala.py +1 -1
  206. holidays/groups/thai.py +1 -7
  207. holidays/helpers.py +1 -1
  208. holidays/holiday_base.py +393 -245
  209. holidays/ical.py +228 -0
  210. holidays/locale/ar/LC_MESSAGES/OM.mo +0 -0
  211. holidays/locale/ar_QA/LC_MESSAGES/QA.mo +0 -0
  212. holidays/locale/en_CI/LC_MESSAGES/CI.mo +0 -0
  213. holidays/locale/en_PK/LC_MESSAGES/PK.mo +0 -0
  214. holidays/locale/en_SL/LC_MESSAGES/SL.mo +0 -0
  215. holidays/locale/en_TL/LC_MESSAGES/TL.mo +0 -0
  216. holidays/locale/en_US/LC_MESSAGES/AR.mo +0 -0
  217. holidays/locale/en_US/LC_MESSAGES/CI.mo +0 -0
  218. holidays/locale/en_US/LC_MESSAGES/GN.mo +0 -0
  219. holidays/locale/en_US/LC_MESSAGES/OM.mo +0 -0
  220. holidays/locale/en_US/LC_MESSAGES/PK.mo +0 -0
  221. holidays/locale/en_US/LC_MESSAGES/QA.mo +0 -0
  222. holidays/locale/en_US/LC_MESSAGES/SL.mo +0 -0
  223. holidays/locale/en_US/LC_MESSAGES/SR.mo +0 -0
  224. holidays/locale/en_US/LC_MESSAGES/TF.mo +0 -0
  225. holidays/locale/en_US/LC_MESSAGES/TL.mo +0 -0
  226. holidays/locale/es/LC_MESSAGES/AR.mo +0 -0
  227. holidays/locale/fr/LC_MESSAGES/CI.mo +0 -0
  228. holidays/locale/fr/LC_MESSAGES/GN.mo +0 -0
  229. holidays/locale/fr/LC_MESSAGES/TF.mo +0 -0
  230. holidays/locale/hi/LC_MESSAGES/IN.mo +0 -0
  231. holidays/locale/nl/LC_MESSAGES/SR.mo +0 -0
  232. holidays/locale/pt_TL/LC_MESSAGES/TL.mo +0 -0
  233. holidays/locale/tet/LC_MESSAGES/TL.mo +0 -0
  234. holidays/locale/th/LC_MESSAGES/TL.mo +0 -0
  235. holidays/locale/uk/LC_MESSAGES/AR.mo +0 -0
  236. holidays/locale/uk/LC_MESSAGES/TF.mo +0 -0
  237. holidays/locale/ur_PK/LC_MESSAGES/PK.mo +0 -0
  238. holidays/mixins.py +2 -2
  239. holidays/observed_holiday_base.py +10 -3
  240. holidays/registry.py +10 -1
  241. holidays/utils.py +203 -151
  242. holidays/version.py +2 -2
  243. holidays-0.71.dist-info/METADATA +1432 -0
  244. {holidays-0.69.dist-info → holidays-0.71.dist-info}/RECORD +248 -217
  245. {holidays-0.69.dist-info → holidays-0.71.dist-info}/WHEEL +1 -1
  246. holidays-0.69.dist-info/AUTHORS → holidays-0.71.dist-info/licenses/AUTHORS.md +9 -2
  247. {holidays-0.69.dist-info → holidays-0.71.dist-info/licenses}/LICENSE +1 -1
  248. holidays-0.69.dist-info/METADATA +0 -1085
  249. {holidays-0.69.dist-info → holidays-0.71.dist-info}/top_level.txt +0 -0
holidays/ical.py ADDED
@@ -0,0 +1,228 @@
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.md 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
+ import re
14
+ import uuid
15
+ from datetime import date, datetime, timedelta, timezone
16
+ from typing import Union
17
+
18
+ from holidays.holiday_base import HolidayBase
19
+ from holidays.version import __version__
20
+
21
+ # iCal-specific constants
22
+ CONTENT_LINE_MAX_LENGTH = 75
23
+ CONTENT_LINE_DELIMITER = "\r\n"
24
+ CONTENT_LINE_DELIMITER_WRAP = f"{CONTENT_LINE_DELIMITER} "
25
+
26
+
27
+ class ICalExporter:
28
+ def __init__(self, instance: HolidayBase, show_language: bool = False) -> None:
29
+ """Initialize iCalendar exporter.
30
+
31
+ Args:
32
+ show_language:
33
+ Determines whether to include the `;LANGUAGE=` attribute in the
34
+ `SUMMARY` field. Defaults to `False`.
35
+
36
+ If the `HolidaysBase` object has a `language` attribute, it will
37
+ be used. Otherwise, `default_language` will be used if available.
38
+
39
+ If neither attribute exists and `show_language=True`, an
40
+ exception will be raised.
41
+
42
+ instance:
43
+ `HolidaysBase` object containing holiday data.
44
+ """
45
+ self.holidays = instance
46
+ self.show_language = show_language
47
+ self.ical_timestamp = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
48
+ self.holidays_version = __version__
49
+ language = getattr(self.holidays, "language", None) or getattr(
50
+ self.holidays, "default_language", None
51
+ )
52
+ self.language = (
53
+ self._validate_language(language)
54
+ if isinstance(language, str)
55
+ and language in getattr(self.holidays, "supported_languages", [])
56
+ else None
57
+ )
58
+
59
+ if self.show_language and self.language is None:
60
+ raise ValueError("LANGUAGE cannot be included because the language code is missing.")
61
+
62
+ def _validate_language(self, language: str) -> str:
63
+ """Validate the language code to ensure it complies with RFC 5646.
64
+
65
+ In the current implementation, all languages must comply with
66
+ either ISO 639-1 or ISO 639-2 if specified (part of RFC 5646).
67
+
68
+ Args:
69
+ language:
70
+ The language code to validate.
71
+
72
+ Returns:
73
+ Validated language code.
74
+ """
75
+ # Remove whitespace (if any), transforms HolidaysBase default to RFC 5646 compliant
76
+ # i.e. `en_US` to `en-US`.
77
+ language = language.strip().replace("_", "-")
78
+
79
+ # ISO 639-1 and ISO 639-2 patterns, in compliance with RFC 5646.
80
+ iso639_pattern = re.compile(r"^[a-z]{2,3}(?:-[A-Z]{2})?$")
81
+
82
+ if not iso639_pattern.fullmatch(language):
83
+ raise ValueError(
84
+ f"Invalid language tag: '{language}'. Expected format follows "
85
+ "ISO 639-1 or ISO 639-2, e.g., 'en', 'en-US'. For more details, "
86
+ "refer to: https://www.loc.gov/standards/iso639-2/php/code_list.php."
87
+ )
88
+ return language
89
+
90
+ def _fold_line(self, line: str) -> str:
91
+ """Fold long lines according to RFC 5545.
92
+
93
+ Content lines SHOULD NOT exceed 75 octets. If a line is too long,
94
+ it must be split into multiple lines, with each continuation line
95
+ starting with a space.
96
+
97
+ Args:
98
+ line:
99
+ The content line to be folded.
100
+
101
+ Returns:
102
+ The folded content line.
103
+ """
104
+ if line.isascii():
105
+ # Simple split for ASCII: every (CONTENT_LINE_MAX_LENGTH - 1) chars,
106
+ # as first char of the next line is space
107
+ if len(line) > CONTENT_LINE_MAX_LENGTH:
108
+ return CONTENT_LINE_DELIMITER_WRAP.join(
109
+ line[i : i + CONTENT_LINE_MAX_LENGTH - 1]
110
+ for i in range(0, len(line), CONTENT_LINE_MAX_LENGTH - 1)
111
+ )
112
+
113
+ elif len(line.encode()) > CONTENT_LINE_MAX_LENGTH:
114
+ # Handle non-ASCII text while respecting byte length
115
+ parts = []
116
+ part_start = 0
117
+ part_len = 0
118
+ for i, char in enumerate(line):
119
+ char_byte_len = len(char.encode())
120
+ part_len += char_byte_len
121
+
122
+ if part_len > CONTENT_LINE_MAX_LENGTH:
123
+ parts.append(line[part_start:i])
124
+ part_start = i
125
+ part_len = char_byte_len + 1 # line start with space
126
+
127
+ parts.append(line[part_start:])
128
+ return CONTENT_LINE_DELIMITER_WRAP.join(parts)
129
+
130
+ # Return as-is if it doesn't exceed the limit
131
+ return line
132
+
133
+ def _generate_event(self, dt: date, holiday_name: str, holiday_length: int = 1) -> list[str]:
134
+ """Generate a single holiday event.
135
+
136
+ Args:
137
+ dt:
138
+ Holiday date.
139
+
140
+ holiday_name:
141
+ Holiday name.
142
+
143
+ holiday_length:
144
+ Holiday length in days, default to 1.
145
+
146
+ Returns:
147
+ List of iCalendar format event lines.
148
+ """
149
+ # Escape special characters per RFC 5545.
150
+ # SEMICOLON is used as a delimiter in HolidayBase (HOLIDAY_NAME_DELIMITER = "; "),
151
+ # so a name with a semicolon gets split into two separate `VEVENT`s.
152
+ sanitized_holiday_name = (
153
+ holiday_name.replace("\\", "\\\\").replace(",", "\\,").replace(":", "\\:")
154
+ )
155
+ event_uid = f"{uuid.uuid4()}@{self.holidays_version}.holidays.local"
156
+ language_tag = f";LANGUAGE={self.language}" if self.show_language else ""
157
+
158
+ return [
159
+ "BEGIN:VEVENT",
160
+ f"DTSTAMP:{self.ical_timestamp}",
161
+ f"UID:{event_uid}",
162
+ self._fold_line(f"SUMMARY{language_tag}:{sanitized_holiday_name}"),
163
+ f"DTSTART;VALUE=DATE:{dt:%Y%m%d}",
164
+ f"DURATION:P{holiday_length}D",
165
+ "END:VEVENT",
166
+ ]
167
+
168
+ def generate(self, return_bytes: bool = False) -> Union[str, bytes]:
169
+ """Generate iCalendar data.
170
+
171
+ Args:
172
+ return_bytes:
173
+ If True, return bytes instead of string.
174
+
175
+ Returns:
176
+ The complete iCalendar data
177
+ (string or UTF-8 bytes depending on return_bytes).
178
+ """
179
+ lines = [
180
+ "BEGIN:VCALENDAR",
181
+ f"PRODID:-//Vacanza//Open World Holidays Framework v{self.holidays_version}//EN",
182
+ "VERSION:2.0",
183
+ "CALSCALE:GREGORIAN",
184
+ ]
185
+
186
+ sorted_dates = sorted(self.holidays.keys())
187
+ # Merged continuous holiday with the same name and use `DURATION` instead.
188
+ i = 0
189
+ while i < len(sorted_dates):
190
+ dt = sorted_dates[i]
191
+ names = self.holidays.get_list(dt)
192
+
193
+ for name in names:
194
+ days = 1
195
+ while (
196
+ i + days < len(sorted_dates)
197
+ and sorted_dates[i + days] == sorted_dates[i] + timedelta(days=days)
198
+ and name in self.holidays.get_list(sorted_dates[i + days])
199
+ ):
200
+ days += 1
201
+
202
+ lines.extend(self._generate_event(dt, name, days))
203
+
204
+ i += days
205
+
206
+ lines.append("END:VCALENDAR")
207
+ lines.append("")
208
+
209
+ output = CONTENT_LINE_DELIMITER.join(lines)
210
+ return output.encode() if return_bytes else output
211
+
212
+ def save_ics(self, file_path: str) -> None:
213
+ """Export the calendar data to a .ics file.
214
+
215
+ While RFC 5545 does not specifically forbid filenames for .ics files, but it’s advisable
216
+ to follow general filesystem conventions and avoid using problematic characters.
217
+
218
+ Args:
219
+ file_path:
220
+ Path to save the .ics file, including the filename (with extension).
221
+ """
222
+ # Generate and write out content (always in bytes for .ics)
223
+ content = self.generate(return_bytes=True)
224
+ if not content:
225
+ raise ValueError("Generated content is empty or invalid.")
226
+
227
+ with open(file_path, "wb") as file:
228
+ file.write(content) # type: ignore # this is always bytes, ignoring mypy error.
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
holidays/mixins.py CHANGED
@@ -4,7 +4,7 @@
4
4
  # specific sets of holidays on the fly. It aims to make determining whether a
5
5
  # specific date is a holiday as fast and flexible as possible.
6
6
  #
7
- # Authors: Vacanza Team and individual contributors (see AUTHORS file)
7
+ # Authors: Vacanza Team and individual contributors (see AUTHORS.md file)
8
8
  # dr-prodigy <dr.prodigy.github@gmail.com> (c) 2017-2023
9
9
  # ryanss <ryanssdev@icloud.com> (c) 2014-2017
10
10
  # Website: https://github.com/vacanza/holidays
@@ -14,7 +14,7 @@
14
14
  class PreferredDiscretionaryHolidays:
15
15
  """A mixin for setting preferred discretionary holidays.
16
16
 
17
- See :class:`holidays.countries.hongkong.HongKong` for an example.
17
+ See [HongKong][holidays.countries.hongkong.HongKong] for an example.
18
18
  """
19
19
 
20
20
  default_preferred_discretionary_holidays: tuple[str, ...] = ()
@@ -4,7 +4,7 @@
4
4
  # specific sets of holidays on the fly. It aims to make determining whether a
5
5
  # specific date is a holiday as fast and flexible as possible.
6
6
  #
7
- # Authors: Vacanza Team and individual contributors (see AUTHORS file)
7
+ # Authors: Vacanza Team and individual contributors (see AUTHORS.md file)
8
8
  # dr-prodigy <dr.prodigy.github@gmail.com> (c) 2017-2023
9
9
  # ryanss <ryanssdev@icloud.com> (c) 2014-2017
10
10
  # Website: https://github.com/vacanza/holidays
@@ -104,7 +104,11 @@ class ObservedHolidayBase(HolidayBase):
104
104
  observed_label = "%s"
105
105
 
106
106
  def __init__(
107
- self, observed_rule: ObservedRule = None, observed_since: int = None, *args, **kwargs
107
+ self,
108
+ observed_rule: Optional[ObservedRule] = None,
109
+ observed_since: Optional[int] = None,
110
+ *args,
111
+ **kwargs,
108
112
  ):
109
113
  self._observed_rule = observed_rule or ObservedRule()
110
114
  self._observed_since = observed_since
@@ -138,11 +142,14 @@ class ObservedHolidayBase(HolidayBase):
138
142
 
139
143
  def _add_observed(
140
144
  self,
141
- dt: DateArg,
145
+ dt: Optional[DateArg] = None,
142
146
  name: Optional[str] = None,
143
147
  rule: Optional[ObservedRule] = None,
144
148
  show_observed_label: bool = True,
145
149
  ) -> tuple[bool, Optional[date]]:
150
+ if dt is None:
151
+ return False, None
152
+
146
153
  dt = dt if isinstance(dt, date) else date(self._year, *dt)
147
154
 
148
155
  if not self.observed or not self._is_observed(dt):
holidays/registry.py CHANGED
@@ -4,7 +4,7 @@
4
4
  # specific sets of holidays on the fly. It aims to make determining whether a
5
5
  # specific date is a holiday as fast and flexible as possible.
6
6
  #
7
- # Authors: Vacanza Team and individual contributors (see AUTHORS file)
7
+ # Authors: Vacanza Team and individual contributors (see AUTHORS.md file)
8
8
  # dr-prodigy <dr.prodigy.github@gmail.com> (c) 2017-2023
9
9
  # ryanss <ryanssdev@icloud.com> (c) 2014-2017
10
10
  # Website: https://github.com/vacanza/holidays
@@ -26,6 +26,7 @@ COUNTRIES: RegistryDict = {
26
26
  "american_samoa": ("AmericanSamoa", "AS", "ASM", "HolidaysAS"),
27
27
  "andorra": ("Andorra", "AD", "AND"),
28
28
  "angola": ("Angola", "AO", "AGO"),
29
+ "antigua_and_barbuda": ("AntiguaAndBarbuda", "AG", "ATG"),
29
30
  "argentina": ("Argentina", "AR", "ARG"),
30
31
  "armenia": ("Armenia", "AM", "ARM"),
31
32
  "aruba": ("Aruba", "AW", "ABW"),
@@ -72,8 +73,10 @@ COUNTRIES: RegistryDict = {
72
73
  "estonia": ("Estonia", "EE", "EST"),
73
74
  "eswatini": ("Eswatini", "SZ", "SZW", "Swaziland"),
74
75
  "ethiopia": ("Ethiopia", "ET", "ETH"),
76
+ "fiji": ("Fiji", "FJ", "FJI"),
75
77
  "finland": ("Finland", "FI", "FIN"),
76
78
  "france": ("France", "FR", "FRA"),
79
+ "french_southern_territories": ("FrenchSouthernTerritories", "TF", "ATF", "HolidaysTF"),
77
80
  "gabon": ("Gabon", "GA", "GAB"),
78
81
  "georgia": ("Georgia", "GE", "GEO"),
79
82
  "germany": ("Germany", "DE", "DEU"),
@@ -83,6 +86,7 @@ COUNTRIES: RegistryDict = {
83
86
  "guam": ("Guam", "GU", "GUM", "HolidaysGU"),
84
87
  "guatemala": ("Guatemala", "GT", "GUA"),
85
88
  "guernsey": ("Guernsey", "GG", "GGY"),
89
+ "guinea": ("Guinea", "GN", "GIN"),
86
90
  "haiti": ("Haiti", "HT", "HTI"),
87
91
  "honduras": ("Honduras", "HN", "HND"),
88
92
  "hongkong": ("HongKong", "HK", "HKG"),
@@ -95,6 +99,7 @@ COUNTRIES: RegistryDict = {
95
99
  "isle_of_man": ("IsleOfMan", "IM", "IMN"),
96
100
  "israel": ("Israel", "IL", "ISR"),
97
101
  "italy": ("Italy", "IT", "ITA"),
102
+ "ivory_coast": ("IvoryCoast", "CI", "CIV"),
98
103
  "jamaica": ("Jamaica", "JM", "JAM"),
99
104
  "japan": ("Japan", "JP", "JPN"),
100
105
  "jersey": ("Jersey", "JE", "JEY"),
@@ -130,6 +135,7 @@ COUNTRIES: RegistryDict = {
130
135
  "north_macedonia": ("NorthMacedonia", "MK", "MKD"),
131
136
  "northern_mariana_islands": ("NorthernMarianaIslands", "MP", "MNP", "HolidaysMP"),
132
137
  "norway": ("Norway", "NO", "NOR"),
138
+ "oman": ("Oman", "OM", "OMN"),
133
139
  "pakistan": ("Pakistan", "PK", "PAK"),
134
140
  "palau": ("Palau", "PW", "PLW"),
135
141
  "panama": ("Panama", "PA", "PAN"),
@@ -140,6 +146,7 @@ COUNTRIES: RegistryDict = {
140
146
  "poland": ("Poland", "PL", "POL"),
141
147
  "portugal": ("Portugal", "PT", "PRT"),
142
148
  "puerto_rico": ("PuertoRico", "PR", "PRI", "HolidaysPR"),
149
+ "qatar": ("Qatar", "QA", "QAT"),
143
150
  "romania": ("Romania", "RO", "ROU"),
144
151
  "russia": ("Russia", "RU", "RUS"),
145
152
  "saint_kitts_and_nevis": ("SaintKittsAndNevis", "KN", "KNA"),
@@ -149,6 +156,7 @@ COUNTRIES: RegistryDict = {
149
156
  "saudi_arabia": ("SaudiArabia", "SA", "SAU"),
150
157
  "serbia": ("Serbia", "RS", "SRB"),
151
158
  "seychelles": ("Seychelles", "SC", "SYC"),
159
+ "sierra_leone": ("SierraLeone", "SL", "SLE"),
152
160
  "singapore": ("Singapore", "SG", "SGP"),
153
161
  "slovakia": ("Slovakia", "SK", "SVK"),
154
162
  "slovenia": ("Slovenia", "SI", "SVN"),
@@ -156,6 +164,7 @@ COUNTRIES: RegistryDict = {
156
164
  "south_korea": ("SouthKorea", "KR", "KOR", "Korea"),
157
165
  "spain": ("Spain", "ES", "ESP"),
158
166
  "sri_lanka": ("SriLanka", "LK", "LKA"),
167
+ "suriname": ("Suriname", "SR", "SUR"),
159
168
  "sweden": ("Sweden", "SE", "SWE"),
160
169
  "switzerland": ("Switzerland", "CH", "CHE"),
161
170
  "taiwan": ("Taiwan", "TW", "TWN"),