holidays 0.46__py3-none-any.whl → 0.48__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.
- holidays/__init__.py +1 -1
- holidays/calendars/gregorian.py +9 -0
- holidays/countries/__init__.py +2 -0
- holidays/countries/andorra.py +18 -20
- holidays/countries/australia.py +19 -4
- holidays/countries/azerbaijan.py +1 -0
- holidays/countries/belgium.py +1 -2
- holidays/countries/bolivia.py +1 -2
- holidays/countries/bosnia_and_herzegovina.py +1 -0
- holidays/countries/botswana.py +5 -8
- holidays/countries/brazil.py +1 -2
- holidays/countries/brunei.py +1 -0
- holidays/countries/burkina_faso.py +1 -0
- holidays/countries/cameroon.py +1 -0
- holidays/countries/chad.py +1 -0
- holidays/countries/chile.py +6 -6
- holidays/countries/colombia.py +1 -2
- holidays/countries/cyprus.py +1 -2
- holidays/countries/denmark.py +1 -2
- holidays/countries/ethiopia.py +1 -0
- holidays/countries/finland.py +1 -1
- holidays/countries/france.py +1 -2
- holidays/countries/gabon.py +1 -0
- holidays/countries/greece.py +11 -6
- holidays/countries/honduras.py +3 -4
- holidays/countries/indonesia.py +1 -0
- holidays/countries/jordan.py +81 -0
- holidays/countries/latvia.py +4 -5
- holidays/countries/moldova.py +1 -2
- holidays/countries/new_zealand.py +5 -6
- holidays/countries/pakistan.py +1 -0
- holidays/countries/palau.py +127 -0
- holidays/countries/poland.py +1 -2
- holidays/countries/portugal.py +2 -6
- holidays/countries/south_africa.py +2 -0
- holidays/countries/south_korea.py +1 -1
- holidays/countries/tanzania.py +1 -0
- holidays/countries/timor_leste.py +24 -1
- holidays/countries/united_arab_emirates.py +1 -0
- holidays/countries/united_states.py +1 -1
- holidays/countries/uruguay.py +3 -4
- holidays/countries/uzbekistan.py +1 -0
- holidays/financial/european_central_bank.py +17 -3
- holidays/groups/international.py +10 -0
- holidays/holiday_base.py +129 -65
- holidays/locale/ar/LC_MESSAGES/JO.mo +0 -0
- holidays/locale/ar/LC_MESSAGES/JO.po +79 -0
- holidays/locale/en_US/LC_MESSAGES/JO.mo +0 -0
- holidays/locale/en_US/LC_MESSAGES/JO.po +79 -0
- holidays/registry.py +2 -0
- {holidays-0.46.dist-info → holidays-0.48.dist-info}/AUTHORS +1 -0
- {holidays-0.46.dist-info → holidays-0.48.dist-info}/METADATA +28 -18
- {holidays-0.46.dist-info → holidays-0.48.dist-info}/RECORD +56 -50
- {holidays-0.46.dist-info → holidays-0.48.dist-info}/LICENSE +0 -0
- {holidays-0.46.dist-info → holidays-0.48.dist-info}/WHEEL +0 -0
- {holidays-0.46.dist-info → holidays-0.48.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,127 @@
|
|
|
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/python-holidays
|
|
11
|
+
# License: MIT (see LICENSE file)
|
|
12
|
+
|
|
13
|
+
from holidays.calendars.gregorian import SEP, NOV
|
|
14
|
+
from holidays.constants import ARMED_FORCES, HALF_DAY, PUBLIC
|
|
15
|
+
from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays
|
|
16
|
+
from holidays.observed_holiday_base import ObservedHolidayBase, SAT_TO_PREV_FRI, SUN_TO_NEXT_MON
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
class Palau(ObservedHolidayBase, ChristianHolidays, InternationalHolidays):
|
|
20
|
+
"""
|
|
21
|
+
References:
|
|
22
|
+
- http://www.paclii.org/pw/legis/consol_act/gpt1262/ # Chapter 7, Holidays.
|
|
23
|
+
- https://www.palaugov.pw/wp-content/uploads/2017/11/RPPL-No.-10-15-re.-Family-Day-Holiday.pdf
|
|
24
|
+
- https://www.facebook.com/PalauPresident/posts/195883107230463 # EO336 Memorial Day repealed
|
|
25
|
+
- https://www.taiwanembassy.org/pal_en/post/792.html # Earliest source for President's Day
|
|
26
|
+
|
|
27
|
+
If any of the holidays enumerated in section 701 of this chapter falls on Sunday, the
|
|
28
|
+
following Monday shall be observed as a holiday. If any of the holidays enumerated in
|
|
29
|
+
section 701 of this chapter falls on Saturday, the preceding Friday shall be observed
|
|
30
|
+
as a holiday.
|
|
31
|
+
|
|
32
|
+
As there's no record of President's Day (Jun 1) and Independence Day (Oct 1) being
|
|
33
|
+
legal holiday before 2017, as seen in RPRL 10-15, they shall be assumed to start in 2018
|
|
34
|
+
for our current implementation.
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
country = "PW"
|
|
38
|
+
supported_categories = (ARMED_FORCES, HALF_DAY, PUBLIC)
|
|
39
|
+
observed_label = "%s (observed)"
|
|
40
|
+
|
|
41
|
+
def __init__(self, *args, **kwargs):
|
|
42
|
+
ChristianHolidays.__init__(self)
|
|
43
|
+
InternationalHolidays.__init__(self)
|
|
44
|
+
StaticHolidays.__init__(self, PalauStaticHolidays)
|
|
45
|
+
kwargs.setdefault("observed_rule", SAT_TO_PREV_FRI + SUN_TO_NEXT_MON)
|
|
46
|
+
super().__init__(*args, **kwargs)
|
|
47
|
+
|
|
48
|
+
def _populate_public_holidays(self):
|
|
49
|
+
# Republic of Palau Public Law No. 2-15.
|
|
50
|
+
# The legislation was first adopted by the 2nd Olbiil Era Kelulau (1984-1988),
|
|
51
|
+
# but since we cannot find any info on its actual adoption date, we may as
|
|
52
|
+
# well use the formation date of the country as the placeholder cut-off date.
|
|
53
|
+
if self._year <= 1980:
|
|
54
|
+
return None
|
|
55
|
+
|
|
56
|
+
# Fixed Date Public Holidays.
|
|
57
|
+
|
|
58
|
+
# New Year's Day.
|
|
59
|
+
name = "New Year's Day"
|
|
60
|
+
self._add_observed(self._add_new_years_day(name))
|
|
61
|
+
self._add_observed(self._next_year_new_years_day, name=name, rule=SAT_TO_PREV_FRI)
|
|
62
|
+
|
|
63
|
+
# Youth Day.
|
|
64
|
+
self._add_observed(self._add_holiday_mar_15("Youth Day"))
|
|
65
|
+
|
|
66
|
+
# Senior Citizens Day.
|
|
67
|
+
self._add_observed(self._add_holiday_may_5("Senior Citizens Day"))
|
|
68
|
+
|
|
69
|
+
if self._year in {2011, 2012}:
|
|
70
|
+
# Memorial Day.
|
|
71
|
+
self._add_holiday_last_mon_of_may("Memorial Day")
|
|
72
|
+
|
|
73
|
+
if self._year >= 2018:
|
|
74
|
+
# President's Day.
|
|
75
|
+
self._add_observed(self._add_holiday_jun_1("President's Day"))
|
|
76
|
+
|
|
77
|
+
# Constitution Day.
|
|
78
|
+
self._add_observed(self._add_holiday_jul_9("Constitution Day"))
|
|
79
|
+
|
|
80
|
+
# Labor Day.
|
|
81
|
+
self._add_holiday_1st_mon_of_sep("Labor Day")
|
|
82
|
+
|
|
83
|
+
if self._year >= 2018:
|
|
84
|
+
# Independence Day.
|
|
85
|
+
self._add_observed(self._add_holiday_oct_1("Independence Day"))
|
|
86
|
+
|
|
87
|
+
# United Nations Day.
|
|
88
|
+
self._add_observed(self._add_united_nations_day("United Nations Day"))
|
|
89
|
+
|
|
90
|
+
# Thanksgiving Day.
|
|
91
|
+
self._add_holiday_4th_thu_of_nov("Thanksgiving Day")
|
|
92
|
+
|
|
93
|
+
if self._year >= 2017:
|
|
94
|
+
# Family Day.
|
|
95
|
+
self._add_holiday_4th_fri_of_nov("Family Day")
|
|
96
|
+
|
|
97
|
+
# Christmas Day.
|
|
98
|
+
self._add_observed(self._add_christmas_day("Christmas Day"))
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
class PW(Palau):
|
|
102
|
+
pass
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
class PLW(Palau):
|
|
106
|
+
pass
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
class PalauStaticHolidays:
|
|
110
|
+
"""
|
|
111
|
+
Sources:
|
|
112
|
+
- https://www.facebook.com/photo?fbid=1774513196034105&set=a.175933635892077
|
|
113
|
+
- https://www.facebook.com/photo/?fbid=1794692910682800&set=a.175933635892077
|
|
114
|
+
- https://www.facebook.com/photo/?fbid=1408133829338712&set=a.175933635892077
|
|
115
|
+
"""
|
|
116
|
+
|
|
117
|
+
special_armed_forces_holidays = {
|
|
118
|
+
2020: (NOV, 11, "Veterans Day"),
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
special_half_day_holidays = {
|
|
122
|
+
2019: (SEP, 30, "Preparation for the 25th Independence Day of the Republic of Palau"),
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
special_public_holidays = {
|
|
126
|
+
2020: (NOV, 3, "National Day of Democracy"),
|
|
127
|
+
}
|
holidays/countries/poland.py
CHANGED
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
# Website: https://github.com/vacanza/python-holidays
|
|
11
11
|
# License: MIT (see LICENSE file)
|
|
12
12
|
|
|
13
|
-
from datetime import timedelta as td
|
|
14
13
|
from gettext import gettext as tr
|
|
15
14
|
|
|
16
15
|
from holidays.calendars.gregorian import NOV
|
|
@@ -68,7 +67,7 @@ class Poland(HolidayBase, ChristianHolidays, InternationalHolidays, StaticHolida
|
|
|
68
67
|
|
|
69
68
|
if self._year <= 1950:
|
|
70
69
|
# Ascension Day.
|
|
71
|
-
self.
|
|
70
|
+
self._add_ascension_thursday(tr("Wniebowstąpienie Pańskie"))
|
|
72
71
|
|
|
73
72
|
# Pentecost.
|
|
74
73
|
self._add_whit_sunday(tr("Zielone Świątki"))
|
holidays/countries/portugal.py
CHANGED
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
# Website: https://github.com/vacanza/python-holidays
|
|
11
11
|
# License: MIT (see LICENSE file)
|
|
12
12
|
|
|
13
|
-
from datetime import timedelta as td
|
|
14
13
|
from gettext import gettext as tr
|
|
15
14
|
|
|
16
15
|
from holidays.constants import OPTIONAL, PUBLIC
|
|
@@ -184,11 +183,8 @@ class Portugal(HolidayBase, ChristianHolidays, InternationalHolidays):
|
|
|
184
183
|
self._add_holiday_aug_22(tr("Dia de Nossa Senhora das Graças"))
|
|
185
184
|
|
|
186
185
|
def _populate_subdiv_05_public_holidays(self):
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
tr("Dia de Nossa Senhora de Mércoles"),
|
|
190
|
-
self._easter_sunday + td(days=+16),
|
|
191
|
-
)
|
|
186
|
+
# Feast of Our Lady of Mércoles.
|
|
187
|
+
self._add_holiday_16_days_past_easter(tr("Dia de Nossa Senhora de Mércoles"))
|
|
192
188
|
|
|
193
189
|
def _populate_subdiv_06_public_holidays(self):
|
|
194
190
|
# St. Elizabeth's Day.
|
|
@@ -20,6 +20,7 @@ class SouthAfrica(ObservedHolidayBase, ChristianHolidays, InternationalHolidays,
|
|
|
20
20
|
https://www.gov.za/about-sa/public-holidays
|
|
21
21
|
https://en.wikipedia.org/wiki/Public_holidays_in_South_Africa
|
|
22
22
|
https://www.gov.za/speeches/president-cyril-ramaphosa-progress-economic-recovery-30-oct-2023-0000
|
|
23
|
+
https://www.gov.za/documents/notices/public-holidays-act-declaration-29-may-2024-public-holiday-23-feb-2024
|
|
23
24
|
"""
|
|
24
25
|
|
|
25
26
|
country = "ZA"
|
|
@@ -147,6 +148,7 @@ class SouthAfricaStaticHolidays:
|
|
|
147
148
|
2022: (DEC, 27, presidential_decree_holiday),
|
|
148
149
|
# Winning the 2023 Rugby World Cup
|
|
149
150
|
2023: (DEC, 15, presidential_decree_holiday),
|
|
151
|
+
2024: (MAY, 29, national_and_provincial_elections),
|
|
150
152
|
}
|
|
151
153
|
|
|
152
154
|
special_public_holidays_observed = {
|
holidays/countries/tanzania.py
CHANGED
|
@@ -31,10 +31,11 @@ class TimorLeste(
|
|
|
31
31
|
References:
|
|
32
32
|
- https://mj.gov.tl/jornal/lawsTL/RDTL-Law/RDTL-Laws/Law-2005-10.pdf # 2005 Law
|
|
33
33
|
- http://timor-leste.gov.tl/?p=14494&lang=en # 2016 Amendment
|
|
34
|
+
- http://timor-leste.gov.tl/?p=30266&lang=en # 2022
|
|
34
35
|
- http://timor-leste.gov.tl/?p=31750&lang=en # 2023 (en_US)
|
|
35
36
|
- http://timor-leste.gov.tl/?p=31750&lang=pt # 2023 (pt_PT)
|
|
36
37
|
- http://timor-leste.gov.tl/?p=31750&lang=tp # 2023 (tet)
|
|
37
|
-
- http://timor-leste.gov.tl/?p=
|
|
38
|
+
- http://timor-leste.gov.tl/?p=35833&lang=en # 2024
|
|
38
39
|
|
|
39
40
|
Limitations:
|
|
40
41
|
|
|
@@ -201,6 +202,7 @@ class TimorLesteIslamicHolidays(_CustomIslamicHolidays):
|
|
|
201
202
|
2021: (JUL, 19),
|
|
202
203
|
2022: (JUL, 9),
|
|
203
204
|
2023: (JUN, 29),
|
|
205
|
+
2024: (JUN, 17),
|
|
204
206
|
}
|
|
205
207
|
|
|
206
208
|
EID_AL_FITR_DATES = {
|
|
@@ -217,6 +219,7 @@ class TimorLesteIslamicHolidays(_CustomIslamicHolidays):
|
|
|
217
219
|
2021: (MAY, 13),
|
|
218
220
|
2022: (MAY, 2),
|
|
219
221
|
2023: (APR, 22),
|
|
222
|
+
2024: (APR, 10),
|
|
220
223
|
}
|
|
221
224
|
|
|
222
225
|
|
|
@@ -395,20 +398,28 @@ class TimorLesteStaticHolidays:
|
|
|
395
398
|
(JAN, 2, special_national_holidays),
|
|
396
399
|
# http://timor-leste.gov.tl/?p=23607&lang=en
|
|
397
400
|
(FEB, 26, special_national_holidays),
|
|
401
|
+
# http://timor-leste.gov.tl/?p=25455&lang=en
|
|
402
|
+
(AUG, 20, special_national_holidays),
|
|
398
403
|
# http://timor-leste.gov.tl/?p=25502&lang=en
|
|
399
404
|
(AUG, 31, special_national_holidays),
|
|
400
405
|
# http://timor-leste.gov.tl/?p=26030&lang=en
|
|
401
406
|
(NOV, 3, special_national_holidays),
|
|
407
|
+
# http://timor-leste.gov.tl/?p=26365&lang=en
|
|
408
|
+
(DEC, 24, special_national_holidays),
|
|
402
409
|
),
|
|
403
410
|
2021: (
|
|
404
411
|
# http://timor-leste.gov.tl/?p=26865&lang=en
|
|
405
412
|
(FEB, 12, special_national_holidays),
|
|
413
|
+
# http://timor-leste.gov.tl/?p=26896&lang=en
|
|
414
|
+
(FEB, 17, special_national_holidays),
|
|
406
415
|
# http://timor-leste.gov.tl/?p=29682&lang=en
|
|
407
416
|
(NOV, 3, special_national_holidays),
|
|
408
417
|
),
|
|
409
418
|
2022: (
|
|
410
419
|
# http://timor-leste.gov.tl/?p=30029&lang=en
|
|
411
420
|
(FEB, 1, special_national_holidays),
|
|
421
|
+
# http://timor-leste.gov.tl/?p=30194&lang=en
|
|
422
|
+
(MAR, 2, special_national_holidays),
|
|
412
423
|
# http://timor-leste.gov.tl/?p=30254&lang=en
|
|
413
424
|
(MAR, 18, presidential_election),
|
|
414
425
|
# http://timor-leste.gov.tl/?p=30429&lang=en
|
|
@@ -416,11 +427,23 @@ class TimorLesteStaticHolidays:
|
|
|
416
427
|
(APR, 18, presidential_election),
|
|
417
428
|
(APR, 19, presidential_election),
|
|
418
429
|
(APR, 20, presidential_election),
|
|
430
|
+
# http://timor-leste.gov.tl/?p=31404&lang=en
|
|
431
|
+
(OCT, 31, special_national_holidays),
|
|
432
|
+
# http://timor-leste.gov.tl/?p=31574&lang=en
|
|
433
|
+
(DEC, 9, special_national_holidays),
|
|
434
|
+
# http://timor-leste.gov.tl/?p=31633&lang=en
|
|
435
|
+
(DEC, 26, special_national_holidays),
|
|
419
436
|
),
|
|
420
437
|
2023: (
|
|
421
438
|
# http://timor-leste.gov.tl/?p=31641&lang=en
|
|
422
439
|
(JAN, 2, special_national_holidays),
|
|
423
440
|
# http://timor-leste.gov.tl/?p=31798&lang=en
|
|
424
441
|
(JAN, 23, special_national_holidays),
|
|
442
|
+
# http://timor-leste.gov.tl/?p=32191&lang=en
|
|
443
|
+
(FEB, 22, special_national_holidays),
|
|
444
|
+
),
|
|
445
|
+
2024: (
|
|
446
|
+
# http://timor-leste.gov.tl/?p=36002&lang=en
|
|
447
|
+
(FEB, 14, special_national_holidays),
|
|
425
448
|
),
|
|
426
449
|
}
|
|
@@ -609,7 +609,7 @@ class UnitedStates(ObservedHolidayBase, ChristianHolidays, InternationalHolidays
|
|
|
609
609
|
|
|
610
610
|
# Confederate Memorial Day
|
|
611
611
|
if self._year >= 1866:
|
|
612
|
-
self.
|
|
612
|
+
self._add_holiday_last_mon_of_apr("Confederate Memorial Day")
|
|
613
613
|
|
|
614
614
|
def _populate_subdiv_mt_public_holidays(self):
|
|
615
615
|
# Election Day
|
holidays/countries/uruguay.py
CHANGED
|
@@ -11,7 +11,6 @@
|
|
|
11
11
|
# License: MIT (see LICENSE file)
|
|
12
12
|
|
|
13
13
|
from datetime import date
|
|
14
|
-
from datetime import timedelta as td
|
|
15
14
|
from gettext import gettext as tr
|
|
16
15
|
|
|
17
16
|
from holidays.calendars.gregorian import MAR
|
|
@@ -123,9 +122,9 @@ class Uruguay(ObservedHolidayBase, ChristianHolidays, InternationalHolidays, Sta
|
|
|
123
122
|
|
|
124
123
|
# Tourism Week.
|
|
125
124
|
name = tr("Semana de Turismo")
|
|
126
|
-
self.
|
|
127
|
-
self.
|
|
128
|
-
self.
|
|
125
|
+
self._add_holiday_6_days_prior_easter(name)
|
|
126
|
+
self._add_holiday_5_days_prior_easter(name)
|
|
127
|
+
self._add_holiday_4_days_prior_easter(name)
|
|
129
128
|
self._add_holy_thursday(name)
|
|
130
129
|
self._add_good_friday(name)
|
|
131
130
|
|
holidays/countries/uzbekistan.py
CHANGED
|
@@ -10,22 +10,30 @@
|
|
|
10
10
|
# Website: https://github.com/vacanza/python-holidays
|
|
11
11
|
# License: MIT (see LICENSE file)
|
|
12
12
|
|
|
13
|
-
from holidays.
|
|
13
|
+
from holidays.calendars.gregorian import DEC
|
|
14
|
+
from holidays.groups import ChristianHolidays, InternationalHolidays, StaticHolidays
|
|
14
15
|
from holidays.holiday_base import HolidayBase
|
|
15
16
|
|
|
16
17
|
|
|
17
18
|
class EuropeanCentralBank(HolidayBase, ChristianHolidays, InternationalHolidays):
|
|
18
|
-
|
|
19
|
-
|
|
19
|
+
"""
|
|
20
|
+
References:
|
|
21
|
+
- https://en.wikipedia.org/wiki/TARGET2
|
|
22
|
+
- https://www.ecb.europa.eu/press/pr/date/1999/html/pr990715_1.en.html
|
|
23
|
+
- https://www.ecb.europa.eu/press/pr/date/2000/html/pr001214_4.en.html
|
|
24
|
+
"""
|
|
20
25
|
|
|
21
26
|
market = "ECB"
|
|
22
27
|
|
|
23
28
|
def __init__(self, *args, **kwargs):
|
|
24
29
|
ChristianHolidays.__init__(self)
|
|
25
30
|
InternationalHolidays.__init__(self)
|
|
31
|
+
StaticHolidays.__init__(self, EuropeanCentralBankStaticHolidays)
|
|
26
32
|
super().__init__(*args, **kwargs)
|
|
27
33
|
|
|
28
34
|
def _populate(self, year):
|
|
35
|
+
if year <= 1999:
|
|
36
|
+
return None
|
|
29
37
|
super()._populate(year)
|
|
30
38
|
|
|
31
39
|
self._add_new_years_day("New Year's Day")
|
|
@@ -45,3 +53,9 @@ class ECB(EuropeanCentralBank):
|
|
|
45
53
|
|
|
46
54
|
class TAR(EuropeanCentralBank):
|
|
47
55
|
pass
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
class EuropeanCentralBankStaticHolidays:
|
|
59
|
+
special_public_holidays = {
|
|
60
|
+
2000: (DEC, 31, "Additional closing day"),
|
|
61
|
+
}
|
holidays/groups/international.py
CHANGED
|
@@ -194,3 +194,13 @@ class InternationalHolidays:
|
|
|
194
194
|
https://en.wikipedia.org/wiki/Victory_Day_(9_May)
|
|
195
195
|
"""
|
|
196
196
|
return self._add_holiday_may_9(name)
|
|
197
|
+
|
|
198
|
+
def _add_united_nations_day(self, name):
|
|
199
|
+
"""
|
|
200
|
+
Add United Nations Day (Oct 24th)
|
|
201
|
+
|
|
202
|
+
United Nations Day is an annual commemorative day, reflecting the
|
|
203
|
+
official creation of the United Nations on 24 October 1945.
|
|
204
|
+
https://en.wikipedia.org/wiki/United_Nations_Day
|
|
205
|
+
"""
|
|
206
|
+
return self._add_holiday_oct_24(name)
|
holidays/holiday_base.py
CHANGED
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
__all__ = ("DateLike", "HolidayBase", "HolidaySum")
|
|
14
14
|
|
|
15
15
|
import copy
|
|
16
|
-
import re
|
|
17
16
|
import warnings
|
|
18
17
|
from calendar import isleap
|
|
19
18
|
from datetime import date, datetime, timedelta, timezone
|
|
@@ -24,7 +23,6 @@ from typing import Any, Dict, Iterable, List, Optional, Set, Tuple, Union, cast
|
|
|
24
23
|
|
|
25
24
|
from dateutil.parser import parse
|
|
26
25
|
|
|
27
|
-
from holidays.calendars import gregorian
|
|
28
26
|
from holidays.calendars.gregorian import (
|
|
29
27
|
MON,
|
|
30
28
|
TUE,
|
|
@@ -35,6 +33,9 @@ from holidays.calendars.gregorian import (
|
|
|
35
33
|
SUN,
|
|
36
34
|
_get_nth_weekday_from,
|
|
37
35
|
_get_nth_weekday_of_month,
|
|
36
|
+
DAYS,
|
|
37
|
+
MONTHS,
|
|
38
|
+
WEEKDAYS,
|
|
38
39
|
)
|
|
39
40
|
from holidays.constants import HOLIDAY_NAME_DELIMITER, PUBLIC
|
|
40
41
|
from holidays.helpers import _normalize_arguments, _normalize_tuple
|
|
@@ -230,6 +231,8 @@ class HolidayBase(Dict[date, str]):
|
|
|
230
231
|
ones."""
|
|
231
232
|
weekend: Set[int] = {SAT, SUN}
|
|
232
233
|
"""Country weekend days."""
|
|
234
|
+
weekend_workdays: Set[date] = set()
|
|
235
|
+
"""Working days moved to weekends."""
|
|
233
236
|
default_category: str = PUBLIC
|
|
234
237
|
"""The entity category used by default."""
|
|
235
238
|
default_language: Optional[str] = None
|
|
@@ -353,6 +356,7 @@ class HolidayBase(Dict[date, str]):
|
|
|
353
356
|
self.language = language.lower() if language else None
|
|
354
357
|
self.observed = observed
|
|
355
358
|
self.subdiv = subdiv
|
|
359
|
+
self.weekend_workdays = set()
|
|
356
360
|
|
|
357
361
|
supported_languages = set(self.supported_languages)
|
|
358
362
|
self.tr = (
|
|
@@ -427,77 +431,103 @@ class HolidayBase(Dict[date, str]):
|
|
|
427
431
|
except AttributeError as e:
|
|
428
432
|
# This part is responsible for _add_holiday_* syntactic sugar support.
|
|
429
433
|
add_holiday_prefix = "_add_holiday_"
|
|
430
|
-
# Raise early if prefix doesn't match to avoid
|
|
434
|
+
# Raise early if prefix doesn't match to avoid patterns checks.
|
|
431
435
|
if name[: len(add_holiday_prefix)] != add_holiday_prefix:
|
|
432
436
|
raise e
|
|
433
437
|
|
|
438
|
+
tokens = name.split("_")
|
|
439
|
+
|
|
434
440
|
# Handle <month> <day> patterns (e.g., _add_holiday_jun_15()).
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
month
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
441
|
+
if len(tokens) == 5:
|
|
442
|
+
*_, month, day = tokens
|
|
443
|
+
if month in MONTHS and day in DAYS:
|
|
444
|
+
return lambda name: self._add_holiday(
|
|
445
|
+
name,
|
|
446
|
+
date(self._year, MONTHS[month], int(day)),
|
|
447
|
+
)
|
|
442
448
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
449
|
+
elif len(tokens) == 7:
|
|
450
|
+
# Handle <last/nth> <weekday> of <month> patterns (e.g.,
|
|
451
|
+
# _add_holiday_last_mon_of_aug() or _add_holiday_3rd_fri_of_aug()).
|
|
452
|
+
*_, number, weekday, of, month = tokens
|
|
453
|
+
if (
|
|
454
|
+
of == "of"
|
|
455
|
+
and (number == "last" or number[0].isdigit())
|
|
456
|
+
and month in MONTHS
|
|
457
|
+
and weekday in WEEKDAYS
|
|
458
|
+
):
|
|
459
|
+
return lambda name: self._add_holiday(
|
|
460
|
+
name,
|
|
461
|
+
_get_nth_weekday_of_month(
|
|
462
|
+
-1 if number == "last" else int(number[0]),
|
|
463
|
+
WEEKDAYS[weekday],
|
|
464
|
+
MONTHS[month],
|
|
465
|
+
self._year,
|
|
466
|
+
),
|
|
467
|
+
)
|
|
468
|
+
|
|
469
|
+
# Handle <n> days <past/prior> easter patterns (e.g.,
|
|
470
|
+
# _add_holiday_8_days_past_easter() or
|
|
471
|
+
# _add_holiday_5_days_prior_easter()).
|
|
472
|
+
*_, days, unit, delta_direction, easter = tokens
|
|
473
|
+
if (
|
|
474
|
+
unit in {"day", "days"}
|
|
475
|
+
and delta_direction in {"past", "prior"}
|
|
476
|
+
and easter == "easter"
|
|
477
|
+
and len(days) < 3
|
|
478
|
+
and days.isdigit()
|
|
479
|
+
):
|
|
480
|
+
return lambda name: self._add_holiday(
|
|
481
|
+
name,
|
|
482
|
+
self._easter_sunday
|
|
483
|
+
+ timedelta(days=+int(days) if delta_direction == "past" else -int(days)),
|
|
484
|
+
)
|
|
459
485
|
|
|
460
486
|
# Handle <n> day(s) <past/prior> <last/<nth> <weekday> of <month> patterns (e.g.,
|
|
461
487
|
# _add_holiday_1_day_past_1st_fri_of_aug() or
|
|
462
488
|
# _add_holiday_5_days_prior_last_fri_of_aug()).
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
days
|
|
470
|
-
|
|
471
|
-
number
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
)
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
489
|
+
elif len(tokens) == 10:
|
|
490
|
+
*_, days, unit, delta_direction, number, weekday, of, month = tokens
|
|
491
|
+
if (
|
|
492
|
+
unit in {"day", "days"}
|
|
493
|
+
and delta_direction in {"past", "prior"}
|
|
494
|
+
and of == "of"
|
|
495
|
+
and len(days) < 3
|
|
496
|
+
and days.isdigit()
|
|
497
|
+
and (number == "last" or number[0].isdigit())
|
|
498
|
+
and month in MONTHS
|
|
499
|
+
and weekday in WEEKDAYS
|
|
500
|
+
):
|
|
501
|
+
return lambda name: self._add_holiday(
|
|
502
|
+
name,
|
|
503
|
+
_get_nth_weekday_of_month(
|
|
504
|
+
-1 if number == "last" else int(number[0]),
|
|
505
|
+
WEEKDAYS[weekday],
|
|
506
|
+
MONTHS[month],
|
|
507
|
+
self._year,
|
|
508
|
+
)
|
|
509
|
+
+ timedelta(days=+int(days) if delta_direction == "past" else -int(days)),
|
|
482
510
|
)
|
|
483
|
-
+ timedelta(days=+int(days) if delta_direction == "past" else -int(days)),
|
|
484
|
-
)
|
|
485
511
|
|
|
486
512
|
# Handle <nth> <weekday> <before/from> <month> <day> patterns (e.g.,
|
|
487
513
|
# _add_holiday_1st_mon_before_jun_15() or _add_holiday_1st_mon_from_jun_15()).
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
514
|
+
elif len(tokens) == 8:
|
|
515
|
+
*_, number, weekday, date_direction, month, day = tokens
|
|
516
|
+
if (
|
|
517
|
+
date_direction in {"before", "from"}
|
|
518
|
+
and number[0].isdigit()
|
|
519
|
+
and month in MONTHS
|
|
520
|
+
and weekday in WEEKDAYS
|
|
521
|
+
and day in DAYS
|
|
522
|
+
):
|
|
523
|
+
return lambda name: self._add_holiday(
|
|
524
|
+
name,
|
|
525
|
+
_get_nth_weekday_from(
|
|
526
|
+
-int(number[0]) if date_direction == "before" else +int(number[0]),
|
|
527
|
+
WEEKDAYS[weekday],
|
|
528
|
+
date(self._year, MONTHS[month], int(day)),
|
|
529
|
+
),
|
|
530
|
+
)
|
|
501
531
|
|
|
502
532
|
raise e # No match.
|
|
503
533
|
|
|
@@ -676,9 +706,13 @@ class HolidayBase(Dict[date, str]):
|
|
|
676
706
|
.lower()
|
|
677
707
|
)
|
|
678
708
|
|
|
679
|
-
@
|
|
709
|
+
@property
|
|
680
710
|
def _sorted_categories(self):
|
|
681
|
-
return
|
|
711
|
+
return (
|
|
712
|
+
[self.default_category] + sorted(self.categories - {self.default_category})
|
|
713
|
+
if self.default_category in self.categories
|
|
714
|
+
else sorted(self.categories)
|
|
715
|
+
)
|
|
682
716
|
|
|
683
717
|
@classmethod
|
|
684
718
|
def get_subdivision_aliases(cls) -> Dict[str, List]:
|
|
@@ -724,14 +758,14 @@ class HolidayBase(Dict[date, str]):
|
|
|
724
758
|
)
|
|
725
759
|
else: # Substituted holidays.
|
|
726
760
|
to_month, to_day, from_month, from_day, *optional = data
|
|
761
|
+
from_date = date(optional[0] if optional else self._year, from_month, from_day)
|
|
727
762
|
self._add_holiday(
|
|
728
763
|
self.tr(self.substituted_label)
|
|
729
|
-
%
|
|
730
|
-
optional[0] if optional else self._year, from_month, from_day
|
|
731
|
-
).strftime(self.tr(self.substituted_date_format)),
|
|
764
|
+
% from_date.strftime(self.tr(self.substituted_date_format)),
|
|
732
765
|
to_month,
|
|
733
766
|
to_day,
|
|
734
767
|
)
|
|
768
|
+
self.weekend_workdays.add(from_date)
|
|
735
769
|
|
|
736
770
|
def _check_weekday(self, weekday: int, *args) -> bool:
|
|
737
771
|
"""
|
|
@@ -922,6 +956,36 @@ class HolidayBase(Dict[date, str]):
|
|
|
922
956
|
|
|
923
957
|
raise AttributeError(f"Unknown lookup type: {lookup}")
|
|
924
958
|
|
|
959
|
+
def get_nth_workday(self, key: DateLike, n: int) -> date:
|
|
960
|
+
"""Return n-th working day from provided date (if n is positive)
|
|
961
|
+
or n-th working day before provided date (if n is negative).
|
|
962
|
+
"""
|
|
963
|
+
direction = +1 if n > 0 else -1
|
|
964
|
+
dt = self.__keytransform__(key)
|
|
965
|
+
for _ in range(abs(n)):
|
|
966
|
+
dt += timedelta(days=direction)
|
|
967
|
+
while not self.is_workday(dt):
|
|
968
|
+
dt += timedelta(days=direction)
|
|
969
|
+
return dt
|
|
970
|
+
|
|
971
|
+
def get_workdays_number(self, key1: DateLike, key2: DateLike) -> int:
|
|
972
|
+
"""Return the number of working days between two dates (not including the start date)."""
|
|
973
|
+
dt1 = self.__keytransform__(key1)
|
|
974
|
+
dt2 = self.__keytransform__(key2)
|
|
975
|
+
if dt1 == dt2:
|
|
976
|
+
return 0
|
|
977
|
+
if dt1 > dt2:
|
|
978
|
+
dt1, dt2 = dt2, dt1
|
|
979
|
+
|
|
980
|
+
return sum(
|
|
981
|
+
self.is_workday(dt1 + timedelta(days=n)) for n in range(1, (dt2 - dt1).days + 1)
|
|
982
|
+
)
|
|
983
|
+
|
|
984
|
+
def is_workday(self, key: DateLike) -> bool:
|
|
985
|
+
"""Return True if date is a working day (not a holiday or a weekend)."""
|
|
986
|
+
dt = self.__keytransform__(key)
|
|
987
|
+
return dt in self.weekend_workdays if self._is_weekend(dt) else dt not in self
|
|
988
|
+
|
|
925
989
|
def pop(self, key: DateLike, default: Union[str, Any] = None) -> Union[str, Any]:
|
|
926
990
|
"""If date is a holiday, remove it and return its date, else return
|
|
927
991
|
default.
|