holidays 0.66__py3-none-any.whl → 0.67__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 (90) hide show
  1. holidays/countries/__init__.py +2 -0
  2. holidays/countries/australia.py +6 -6
  3. holidays/countries/cambodia.py +1 -1
  4. holidays/countries/chile.py +1 -1
  5. holidays/countries/cuba.py +1 -1
  6. holidays/countries/denmark.py +1 -1
  7. holidays/countries/finland.py +19 -19
  8. holidays/countries/greenland.py +22 -19
  9. holidays/countries/guatemala.py +1 -1
  10. holidays/countries/haiti.py +3 -3
  11. holidays/countries/hongkong.py +124 -174
  12. holidays/countries/isle_of_man.py +15 -11
  13. holidays/countries/kazakhstan.py +1 -1
  14. holidays/countries/laos.py +2 -2
  15. holidays/countries/nicaragua.py +1 -1
  16. holidays/countries/panama.py +69 -31
  17. holidays/countries/peru.py +1 -1
  18. holidays/countries/saint_lucia.py +88 -0
  19. holidays/countries/seychelles.py +4 -4
  20. holidays/countries/singapore.py +1 -1
  21. holidays/countries/spain.py +9 -9
  22. holidays/countries/sri_lanka.py +1 -1
  23. holidays/countries/switzerland.py +1 -1
  24. holidays/countries/tuvalu.py +174 -0
  25. holidays/countries/united_kingdom.py +72 -56
  26. holidays/countries/united_states.py +141 -10
  27. holidays/countries/uruguay.py +1 -1
  28. holidays/financial/brasil_bolsa_balcao.py +1 -1
  29. holidays/holiday_base.py +62 -13
  30. holidays/locale/da/LC_MESSAGES/GL.mo +0 -0
  31. holidays/locale/en_GB/LC_MESSAGES/GB.mo +0 -0
  32. holidays/locale/en_GB/LC_MESSAGES/IM.mo +0 -0
  33. holidays/locale/en_GB/LC_MESSAGES/TV.mo +0 -0
  34. holidays/locale/en_HK/LC_MESSAGES/HK.mo +0 -0
  35. holidays/locale/en_LC/LC_MESSAGES/LC.mo +0 -0
  36. holidays/locale/en_US/LC_MESSAGES/AR.mo +0 -0
  37. holidays/locale/en_US/LC_MESSAGES/CH.mo +0 -0
  38. holidays/locale/en_US/LC_MESSAGES/CL.mo +0 -0
  39. holidays/locale/en_US/LC_MESSAGES/CO.mo +0 -0
  40. holidays/locale/en_US/LC_MESSAGES/CU.mo +0 -0
  41. holidays/locale/en_US/LC_MESSAGES/DK.mo +0 -0
  42. holidays/locale/en_US/LC_MESSAGES/ES.mo +0 -0
  43. holidays/locale/en_US/LC_MESSAGES/FI.mo +0 -0
  44. holidays/locale/en_US/LC_MESSAGES/GB.mo +0 -0
  45. holidays/locale/en_US/LC_MESSAGES/GL.mo +0 -0
  46. holidays/locale/en_US/LC_MESSAGES/GT.mo +0 -0
  47. holidays/locale/en_US/LC_MESSAGES/HK.mo +0 -0
  48. holidays/locale/en_US/LC_MESSAGES/HT.mo +0 -0
  49. holidays/locale/en_US/LC_MESSAGES/IM.mo +0 -0
  50. holidays/locale/en_US/LC_MESSAGES/KH.mo +0 -0
  51. holidays/locale/en_US/LC_MESSAGES/KZ.mo +0 -0
  52. holidays/locale/en_US/LC_MESSAGES/LA.mo +0 -0
  53. holidays/locale/en_US/LC_MESSAGES/LC.mo +0 -0
  54. holidays/locale/en_US/LC_MESSAGES/LK.mo +0 -0
  55. holidays/locale/en_US/LC_MESSAGES/NI.mo +0 -0
  56. holidays/locale/en_US/LC_MESSAGES/PA.mo +0 -0
  57. holidays/locale/en_US/LC_MESSAGES/PE.mo +0 -0
  58. holidays/locale/en_US/LC_MESSAGES/RU.mo +0 -0
  59. holidays/locale/en_US/LC_MESSAGES/SC.mo +0 -0
  60. holidays/locale/en_US/LC_MESSAGES/TV.mo +0 -0
  61. holidays/locale/en_US/LC_MESSAGES/UY.mo +0 -0
  62. holidays/locale/es/LC_MESSAGES/PA.mo +0 -0
  63. holidays/locale/fi/LC_MESSAGES/GL.mo +0 -0
  64. holidays/locale/is/LC_MESSAGES/GL.mo +0 -0
  65. holidays/locale/kl/LC_MESSAGES/GL.mo +0 -0
  66. holidays/locale/no/LC_MESSAGES/GL.mo +0 -0
  67. holidays/locale/sv/LC_MESSAGES/GL.mo +0 -0
  68. holidays/locale/th/LC_MESSAGES/GB.mo +0 -0
  69. holidays/locale/th/LC_MESSAGES/HK.mo +0 -0
  70. holidays/locale/th/LC_MESSAGES/IM.mo +0 -0
  71. holidays/locale/tvl/LC_MESSAGES/TV.mo +0 -0
  72. holidays/locale/uk/LC_MESSAGES/CR.mo +0 -0
  73. holidays/locale/uk/LC_MESSAGES/DK.mo +0 -0
  74. holidays/locale/uk/LC_MESSAGES/ES.mo +0 -0
  75. holidays/locale/uk/LC_MESSAGES/GE.mo +0 -0
  76. holidays/locale/uk/LC_MESSAGES/GL.mo +0 -0
  77. holidays/locale/uk/LC_MESSAGES/MC.mo +0 -0
  78. holidays/locale/uk/LC_MESSAGES/MG.mo +0 -0
  79. holidays/locale/uk/LC_MESSAGES/PA.mo +0 -0
  80. holidays/locale/uk/LC_MESSAGES/RO.mo +0 -0
  81. holidays/locale/zh_CN/LC_MESSAGES/HK.mo +0 -0
  82. holidays/locale/zh_HK/LC_MESSAGES/HK.mo +0 -0
  83. holidays/registry.py +2 -0
  84. holidays/version.py +1 -1
  85. {holidays-0.66.dist-info → holidays-0.67.dist-info}/AUTHORS +1 -0
  86. {holidays-0.66.dist-info → holidays-0.67.dist-info}/METADATA +33 -17
  87. {holidays-0.66.dist-info → holidays-0.67.dist-info}/RECORD +90 -64
  88. {holidays-0.66.dist-info → holidays-0.67.dist-info}/LICENSE +0 -0
  89. {holidays-0.66.dist-info → holidays-0.67.dist-info}/WHEEL +0 -0
  90. {holidays-0.66.dist-info → holidays-0.67.dist-info}/top_level.txt +0 -0
holidays/holiday_base.py CHANGED
@@ -14,13 +14,14 @@ __all__ = ("DateLike", "HolidayBase", "HolidaySum")
14
14
 
15
15
  import copy
16
16
  import warnings
17
+ from bisect import bisect_left, bisect_right
17
18
  from calendar import isleap
18
19
  from collections.abc import Iterable
19
20
  from datetime import date, datetime, timedelta, timezone
20
21
  from functools import cached_property
21
22
  from gettext import gettext, translation
22
23
  from pathlib import Path
23
- from typing import Any, Dict, Optional, Union, cast
24
+ from typing import Any, Literal, Optional, Union, cast
24
25
 
25
26
  from dateutil.parser import parse
26
27
 
@@ -249,6 +250,8 @@ class HolidayBase(dict[date, str]):
249
250
  """Start year of holidays presence for this entity."""
250
251
  end_year: int = DEFAULT_END_YEAR
251
252
  """End year of holidays presence for this entity."""
253
+ parent_entity: Optional[type["HolidayBase"]] = None
254
+ """Optional parent entity to reference as a base."""
252
255
 
253
256
  def __init__(
254
257
  self,
@@ -364,16 +367,32 @@ class HolidayBase(dict[date, str]):
364
367
  self.weekend_workdays = getattr(self, "weekend_workdays", set())
365
368
 
366
369
  supported_languages = set(self.supported_languages)
367
- self.tr = (
368
- translation(
370
+ if self._entity_code is not None:
371
+ fallback = language not in supported_languages
372
+ languages = [language] if language in supported_languages else None
373
+ locale_directory = str(Path(__file__).with_name("locale"))
374
+
375
+ # Add entity native content translations.
376
+ entity_translation = translation(
369
377
  self._entity_code,
370
- fallback=language not in supported_languages,
371
- languages=[language] if language in supported_languages else None,
372
- localedir=str(Path(__file__).with_name("locale")),
373
- ).gettext
374
- if self._entity_code is not None
375
- else gettext
376
- )
378
+ fallback=fallback,
379
+ languages=languages,
380
+ localedir=locale_directory,
381
+ )
382
+ # Add a fallback if entity has parent translations.
383
+ if parent_entity := self.parent_entity:
384
+ entity_translation.add_fallback(
385
+ translation(
386
+ parent_entity.country or parent_entity.market,
387
+ fallback=fallback,
388
+ languages=languages,
389
+ localedir=locale_directory,
390
+ )
391
+ )
392
+ self.tr = entity_translation.gettext
393
+ else:
394
+ self.tr = gettext
395
+
377
396
  self.years = _normalize_arguments(int, years)
378
397
 
379
398
  # Populate holidays.
@@ -418,7 +437,7 @@ class HolidayBase(dict[date, str]):
418
437
  if not isinstance(key, (date, datetime, float, int, str)):
419
438
  raise TypeError(f"Cannot convert type '{type(key)}' to date.")
420
439
 
421
- return dict.__contains__(cast("Dict[Any, Any]", self), self.__keytransform__(key))
440
+ return dict.__contains__(cast("dict[Any, Any]", self), self.__keytransform__(key))
422
441
 
423
442
  def __eq__(self, other: object) -> bool:
424
443
  if not isinstance(other, HolidayBase):
@@ -428,7 +447,7 @@ class HolidayBase(dict[date, str]):
428
447
  if getattr(self, attribute_name, None) != getattr(other, attribute_name, None):
429
448
  return False
430
449
 
431
- return dict.__eq__(cast("Dict[Any, Any]", self), other)
450
+ return dict.__eq__(cast("dict[Any, Any]", self), other)
432
451
 
433
452
  def __getattr__(self, name):
434
453
  try:
@@ -967,6 +986,36 @@ class HolidayBase(dict[date, str]):
967
986
 
968
987
  raise AttributeError(f"Unknown lookup type: {lookup}")
969
988
 
989
+ def get_closest_holiday(
990
+ self,
991
+ target_date: DateLike = None,
992
+ direction: Literal["forward", "backward"] = "forward",
993
+ ) -> Optional[tuple[date, str]]:
994
+ """Return the date and name of the next holiday for a target_date
995
+ if direction is "forward" or the previous holiday if direction is "backward".
996
+ If target_date is not provided the current date will be used by default."""
997
+
998
+ if direction not in {"backward", "forward"}:
999
+ raise AttributeError(f"Unknown direction: {direction}")
1000
+
1001
+ dt = self.__keytransform__(target_date or datetime.now().date())
1002
+ if direction == "forward" and (next_year := dt.year + 1) not in self.years:
1003
+ self._populate(next_year)
1004
+ elif direction == "backward" and (previous_year := dt.year - 1) not in self.years:
1005
+ self._populate(previous_year)
1006
+
1007
+ sorted_dates = sorted(self.keys())
1008
+ position = (
1009
+ bisect_right(sorted_dates, dt)
1010
+ if direction == "forward"
1011
+ else bisect_left(sorted_dates, dt) - 1
1012
+ )
1013
+ if 0 <= position < len(sorted_dates):
1014
+ dt = sorted_dates[position]
1015
+ return dt, self[dt]
1016
+
1017
+ return None
1018
+
970
1019
  def get_nth_working_day(self, key: DateLike, n: int) -> date:
971
1020
  """Return n-th working day from provided date (if n is positive)
972
1021
  or n-th working day before provided date (if n is negative).
@@ -1201,4 +1250,4 @@ country_holidays('CA') + country_holidays('MX')
1201
1250
  def _populate(self, year):
1202
1251
  for operand in self.holidays:
1203
1252
  operand._populate(year)
1204
- self.update(cast("Dict[DateLike, str]", operand))
1253
+ self.update(cast("dict[DateLike, str]", operand))
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
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/registry.py CHANGED
@@ -142,6 +142,7 @@ COUNTRIES: RegistryDict = {
142
142
  "romania": ("Romania", "RO", "ROU"),
143
143
  "russia": ("Russia", "RU", "RUS"),
144
144
  "saint_kitts_and_nevis": ("SaintKittsAndNevis", "KN", "KNA"),
145
+ "saint_lucia": ("SaintLucia", "LC", "LCA"),
145
146
  "samoa": ("Samoa", "WS", "WSM"),
146
147
  "san_marino": ("SanMarino", "SM", "SMR"),
147
148
  "saudi_arabia": ("SaudiArabia", "SA", "SAU"),
@@ -163,6 +164,7 @@ COUNTRIES: RegistryDict = {
163
164
  "tonga": ("Tonga", "TO", "TON"),
164
165
  "tunisia": ("Tunisia", "TN", "TUN"),
165
166
  "turkey": ("Turkey", "TR", "TUR"),
167
+ "tuvalu": ("Tuvalu", "TV", "TUV"),
166
168
  "ukraine": ("Ukraine", "UA", "UKR"),
167
169
  "united_arab_emirates": ("UnitedArabEmirates", "AE", "ARE"),
168
170
  "united_kingdom": ("UnitedKingdom", "GB", "GBR", "UK"),
holidays/version.py CHANGED
@@ -10,4 +10,4 @@
10
10
  # Website: https://github.com/vacanza/holidays
11
11
  # License: MIT (see LICENSE file)
12
12
 
13
- __version__ = "0.66"
13
+ __version__ = "0.67"
@@ -29,6 +29,7 @@ Chanran Kim
29
29
  Chris McKeague
30
30
  Chris Turra
31
31
  Christian Alexander
32
+ Colin Watson
32
33
  Dan Gentry
33
34
  Daniel Musketa
34
35
  Daniël Niemeijer
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: holidays
3
- Version: 0.66
3
+ Version: 0.67
4
4
  Summary: Open World Holidays Framework
5
5
  Author: Vacanza Team
6
6
  Maintainer: Arkadii Yakovets, Panpakorn Siripanich, Serhii Murza
@@ -96,15 +96,21 @@ flexible as possible.
96
96
  :target: https://github.com/vacanza/holidays/commits/dev
97
97
  :alt: GitHub last commit
98
98
 
99
- +--------+------------------------------------------------+
100
- | PyPI | |downloads| |version| |release date| |
101
- +--------+------------------------------------------------+
102
- | CI/CD | |status| |documentation| |
103
- +--------+------------------------------------------------+
104
- | Code | |license| |python versions| |style| |coverage| |
105
- +--------+------------------------------------------------+
106
- | GitHub | |stars| |forks| |contributors| |last commit| |
107
- +--------+------------------------------------------------+
99
+ .. |doi| image:: https://img.shields.io/badge/DOI-10.5281/zenodo.14847397-41B5BE?style=flat
100
+ :target: https://doi.org/10.5281/zenodo.14847397
101
+ :alt: Open World Holidays Franework DOI
102
+
103
+ +----------+------------------------------------------------+
104
+ | PyPI | |downloads| |version| |release date| |
105
+ +----------+------------------------------------------------+
106
+ | CI/CD | |status| |documentation| |
107
+ +----------+------------------------------------------------+
108
+ | Code | |license| |python versions| |style| |coverage| |
109
+ +----------+------------------------------------------------+
110
+ | GitHub | |stars| |forks| |contributors| |last commit| |
111
+ +----------+------------------------------------------------+
112
+ | Citation | |doi| |
113
+ +----------+------------------------------------------------+
108
114
 
109
115
  Install
110
116
  -------
@@ -183,7 +189,7 @@ Available Countries
183
189
  .. _ISO 639-1 code: https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
184
190
  .. _ISO 639-2 code: https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes
185
191
 
186
- We currently support 157 country codes. The standard way to refer to a country
192
+ We currently support 159 country codes. The standard way to refer to a country
187
193
  is by using its `ISO 3166-1 alpha-2 code`_, the same used for domain names, and
188
194
  for a subdivision its `ISO 3166-2 code`_. Some countries have common or foreign
189
195
  names or abbreviations as aliases for their subdivisions. These are defined in
@@ -510,7 +516,7 @@ All other default values are highlighted with bold:
510
516
  * - Greenland
511
517
  - GL
512
518
  -
513
- - da, en_US, **kl**
519
+ - da, en_US, fi, is, **kl**, no, sv, uk
514
520
  - OPTIONAL
515
521
  * - Guam
516
522
  - GU
@@ -540,7 +546,7 @@ All other default values are highlighted with bold:
540
546
  * - Hong Kong
541
547
  - HK
542
548
  -
543
- -
549
+ - en_HK, en_US, th, zh_CN, **zh_HK**
544
550
  - OPTIONAL
545
551
  * - Hungary
546
552
  - HU
@@ -575,7 +581,7 @@ All other default values are highlighted with bold:
575
581
  * - Isle of Man
576
582
  - IM
577
583
  -
578
- -
584
+ - **en_GB**, en_US, th
579
585
  -
580
586
  * - Israel
581
587
  - IL
@@ -775,8 +781,8 @@ All other default values are highlighted with bold:
775
781
  * - Panama
776
782
  - PA
777
783
  -
778
- -
779
- -
784
+ - en_US, **es**, uk
785
+ - BANK
780
786
  * - Papua New Guinea
781
787
  - PG
782
788
  -
@@ -827,6 +833,11 @@ All other default values are highlighted with bold:
827
833
  -
828
834
  -
829
835
  - HALF_DAY, WORKDAY
836
+ * - Saint Lucia
837
+ - LC
838
+ -
839
+ - **en_LC**, en_US
840
+ -
830
841
  * - Samoa
831
842
  - WS
832
843
  -
@@ -932,6 +943,11 @@ All other default values are highlighted with bold:
932
943
  -
933
944
  - en_US, **tr**, uk
934
945
  - HALF_DAY
946
+ * - Tuvalu
947
+ - TV
948
+ - Town/Island Councils: FUN (Funafuti), NIT (Niutao), NKF (Nukufetau), NKL (Nukulaelae), NMA (Nanumea), NMG (Nanumaga, Nanumanga), NUI (Nui), VAI (Vaitupu)
949
+ - en_GB, en_US, **tvl**
950
+ -
935
951
  * - Ukraine
936
952
  - UA
937
953
  -
@@ -945,7 +961,7 @@ All other default values are highlighted with bold:
945
961
  * - United Kingdom
946
962
  - GB
947
963
  - Subdivisions: ENG (England), NIR (Northern Ireland), SCT (Scotland), WLS (Wales)
948
- -
964
+ - **en_GB**, en_US, th
949
965
  -
950
966
  * - United States Minor Outlying Islands
951
967
  - UM