Refactoring core classes
* Refactoring the core ``Calendar`` classes / mixins for better understanding. Only one ``Calendar`` subclass should be imported / used in calendar classes, the rest (when possible) should be ``Mixins`` (related to #511). * Fixed Belarus holidays related to the Orthodox calendar * Fixed Algeria week-end days
This commit is contained in:
parent
21ab4044c8
commit
b347472334
|
@ -2,7 +2,11 @@
|
|||
|
||||
## master (unreleased)
|
||||
|
||||
Nothing here yet.
|
||||
- Refactoring the core ``Calendar`` classes / mixins for better understanding. Only one ``Calendar`` subclass should be imported / used in calendar classes, the rest (when possible) should be ``Mixins`` (related to #511).
|
||||
- Fixed `contributing.md` documentation with the new class/mixin organization.
|
||||
- Bugfix -- Belarus: removing day after Radonitsa, which is apparently not a holiday.
|
||||
- Bugfix -- Algeria: assigning the week-end days as FRI+SAT, as it's following a Islamic calendar.
|
||||
|
||||
|
||||
## v10.2.0 (2020-06-26)
|
||||
|
||||
|
|
|
@ -133,12 +133,12 @@ Now we've got 3 holidays out of 6.
|
|||
|
||||
#### Add religious holidays
|
||||
|
||||
Using `ChristianMixin` as a base to our `Zhraa` class will instantly add Christmas Day as a holiday. Now we can add Easter monday just by switching the correct flag.
|
||||
Since we're using `WesternCalendar` (it inherits from `ChristianMixin`) as a base to our `Zhraa` class, it automatically adds Christmas Day as a holiday. Now we can add Easter monday just by switching the correct flag.
|
||||
|
||||
```python
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
|
||||
class Zhraa(WesternCalendar, ChristianMixin):
|
||||
class Zhraa(WesternCalendar):
|
||||
include_easter_monday = True
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
|
@ -152,7 +152,7 @@ Almost there, 5 holidays out of 6.
|
|||
There are many static methods that will grant you a clean access to variable days computation. It's very easy to add days like the "Birthday of the Founder":
|
||||
|
||||
```python
|
||||
class Zhraa(WesternCalendar, ChristianMixin):
|
||||
class Zhraa(WesternCalendar):
|
||||
include_easter_monday = True
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
|
@ -184,7 +184,7 @@ To register, add the following:
|
|||
from ..registry_tools import iso_register
|
||||
|
||||
@iso_register('ZK')
|
||||
class Zhraa(WesternCalendar, ChristianMixin):
|
||||
class Zhraa(WesternCalendar):
|
||||
# The rest of your code...
|
||||
```
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, IslamicMixin
|
||||
from ..core import IslamicCalendar, NewYearsDayMixin
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('DZ')
|
||||
class Algeria(WesternCalendar, IslamicMixin):
|
||||
class Algeria(NewYearsDayMixin, IslamicCalendar):
|
||||
"Algeria"
|
||||
# Islamic holidays
|
||||
include_prophet_birthday = True
|
||||
|
@ -11,12 +11,13 @@ class Algeria(WesternCalendar, IslamicMixin):
|
|||
include_day_of_sacrifice = True
|
||||
include_islamic_new_year = True
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
(7, 5, "Independence Day"),
|
||||
(11, 1, "Anniversary of the revolution"),
|
||||
)
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + \
|
||||
IslamicCalendar.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
(7, 5, "Independence Day"),
|
||||
(11, 1, "Anniversary of the revolution"),
|
||||
)
|
||||
|
||||
ISLAMIC_HOLIDAYS = IslamicMixin.ISLAMIC_HOLIDAYS + (
|
||||
ISLAMIC_HOLIDAYS = IslamicCalendar.ISLAMIC_HOLIDAYS + (
|
||||
(1, 10, "Ashura"),
|
||||
)
|
||||
|
|
|
@ -1,11 +1,10 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('AO')
|
||||
class Angola(WesternCalendar, ChristianMixin):
|
||||
class Angola(WesternCalendar):
|
||||
"Angola"
|
||||
|
||||
include_fat_tuesday = True
|
||||
fat_tuesday_label = "Dia de Carnaval"
|
||||
include_good_friday = True
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
from ..core import WesternCalendar, IslamicMixin, ChristianMixin
|
||||
from ..core import NewYearsDayMixin, IslamoWesternCalendar, SAT, SUN
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('BJ')
|
||||
class Benin(WesternCalendar, IslamicMixin, ChristianMixin):
|
||||
class Benin(NewYearsDayMixin, IslamoWesternCalendar):
|
||||
"Benin"
|
||||
# Christian holidays
|
||||
include_easter_monday = True
|
||||
include_ascension = True
|
||||
include_whit_monday = True
|
||||
|
@ -16,10 +17,13 @@ class Benin(WesternCalendar, IslamicMixin, ChristianMixin):
|
|||
include_day_of_sacrifice = True
|
||||
include_day_of_sacrifice_label = "Tabaski"
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
(1, 10, "Traditional Day"),
|
||||
(5, 1, "Labour Day"),
|
||||
(8, 1, "Independence Day"),
|
||||
(10, 26, "Armed Forces Day"),
|
||||
(11, 30, "National Day"),
|
||||
)
|
||||
|
||||
# Explicitely assign these WE days, Benin has adopted the western workweek
|
||||
WEEKEND_DAYS = (SAT, SUN)
|
||||
|
|
|
@ -1,22 +1,27 @@
|
|||
from ..core import WesternCalendar, IslamicMixin, ChristianMixin
|
||||
from ..core import NewYearsDayMixin, IslamoWesternCalendar, SAT, SUN
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('CI')
|
||||
class IvoryCoast(WesternCalendar, ChristianMixin, IslamicMixin):
|
||||
class IvoryCoast(NewYearsDayMixin, IslamoWesternCalendar):
|
||||
"Ivory Coast"
|
||||
# Christian holidays
|
||||
include_easter_monday = True
|
||||
include_ascension = True
|
||||
include_whit_monday = True
|
||||
include_assumption = True
|
||||
include_all_saints = True
|
||||
# Islamic holidays
|
||||
include_day_after_prophet_birthday = True
|
||||
include_eid_al_fitr = True
|
||||
include_day_of_sacrifice = True
|
||||
include_day_of_sacrifice_label = "Feast of the Sacrifice"
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
(8, 7, "Independence Day"),
|
||||
(11, 15, "National Peace Day"),
|
||||
)
|
||||
|
||||
# Ivory Coast has adopted the "western" workweek.
|
||||
WEEKEND_DAYS = (SAT, SUN)
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
from copy import copy
|
||||
from datetime import timedelta, date
|
||||
|
||||
from ..core import WesternCalendar, IslamicMixin, ChristianMixin, SUN
|
||||
from ..core import NewYearsDayMixin, IslamoWesternCalendar, SAT, SUN
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('KE')
|
||||
class Kenya(WesternCalendar, IslamicMixin, ChristianMixin):
|
||||
class Kenya(NewYearsDayMixin, IslamoWesternCalendar):
|
||||
"Kenya"
|
||||
# Christian holidays
|
||||
include_good_friday = True
|
||||
include_easter_monday = True
|
||||
# Islamic holidays
|
||||
|
@ -15,7 +16,10 @@ class Kenya(WesternCalendar, IslamicMixin, ChristianMixin):
|
|||
include_day_of_sacrifice = True
|
||||
shift_sunday_holidays = True
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
# Explicitely assign these WE days, Kenya has adopted the western workweek
|
||||
WEEKEND_DAYS = (SAT, SUN)
|
||||
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
(6, 1, "Madaraka Day"),
|
||||
(10, 20, "Mashujaa Day"),
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('MG')
|
||||
class Madagascar(WesternCalendar, ChristianMixin):
|
||||
class Madagascar(WesternCalendar):
|
||||
"Madagascar"
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
(3, 29, "Martyrs' Day"),
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('ST')
|
||||
class SaoTomeAndPrincipe(WesternCalendar, ChristianMixin):
|
||||
class SaoTomeAndPrincipe(WesternCalendar):
|
||||
"São Tomé and Príncipe"
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
(2, 3, "Martyr's Day"),
|
||||
|
|
|
@ -1,14 +1,12 @@
|
|||
from datetime import timedelta, date
|
||||
|
||||
from ..core import WesternCalendar
|
||||
from ..core import SUN, MON, FRI
|
||||
from ..core import ChristianMixin
|
||||
from ..core import WesternCalendar, SUN, MON, FRI
|
||||
from ..exceptions import CalendarError
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('ZA')
|
||||
class SouthAfrica(WesternCalendar, ChristianMixin):
|
||||
class SouthAfrica(WesternCalendar):
|
||||
"South Africa"
|
||||
include_good_friday = True
|
||||
include_christmas = True
|
||||
|
|
|
@ -1,13 +1,10 @@
|
|||
from datetime import timedelta, date
|
||||
from ..core import (
|
||||
WesternCalendar, ChristianMixin,
|
||||
MON, TUE, WED, THU, FRI, SAT
|
||||
)
|
||||
from ..core import WesternCalendar, MON, TUE, WED, THU, FRI, SAT
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('AR')
|
||||
class Argentina(WesternCalendar, ChristianMixin):
|
||||
class Argentina(WesternCalendar):
|
||||
'Argentina'
|
||||
|
||||
include_fat_tuesday = True
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
from datetime import timedelta
|
||||
from copy import copy
|
||||
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import SUN, MON
|
||||
from ..core import WesternCalendar, SUN, MON
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register("BB")
|
||||
class Barbados(WesternCalendar, ChristianMixin):
|
||||
class Barbados(WesternCalendar):
|
||||
"Barbados"
|
||||
|
||||
include_good_friday = True
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
from datetime import timedelta, date
|
||||
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import MON, SAT, SUN
|
||||
from ..core import WesternCalendar, MON, SAT, SUN
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('BR')
|
||||
class Brazil(WesternCalendar, ChristianMixin):
|
||||
class Brazil(WesternCalendar):
|
||||
"Brazil"
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
(4, 21, "Tiradentes' Day"),
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
from datetime import date
|
||||
|
||||
from ..core import WesternCalendar, ChristianMixin, Calendar
|
||||
from ..core import SUN, MON, SAT
|
||||
from ..core import WesternCalendar, SUN, MON, SAT
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('CA')
|
||||
class Canada(WesternCalendar, ChristianMixin):
|
||||
class Canada(WesternCalendar):
|
||||
"Canada"
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
(7, 1, "Canada Day"),
|
||||
|
@ -31,14 +30,14 @@ class Canada(WesternCalendar, ChristianMixin):
|
|||
return days
|
||||
|
||||
|
||||
class LateFamilyDayMixin(Calendar):
|
||||
class LateFamilyDayMixin:
|
||||
"3rd Monday of February"
|
||||
|
||||
def get_family_day(self, year, label="Family Day"):
|
||||
return (self.get_nth_weekday_in_month(year, 2, MON, 3), label)
|
||||
|
||||
|
||||
class VictoriaDayMixin(Calendar):
|
||||
class VictoriaDayMixin:
|
||||
"Monday preceding the 25th of May"
|
||||
|
||||
def get_victoria_day(self, year):
|
||||
|
@ -47,14 +46,14 @@ class VictoriaDayMixin(Calendar):
|
|||
return (date(year, 5, day), "Victoria Day")
|
||||
|
||||
|
||||
class AugustCivicHolidayMixin(Calendar):
|
||||
class AugustCivicHolidayMixin:
|
||||
"1st Monday of August; different names depending on location"
|
||||
|
||||
def get_civic_holiday(self, year, label="Civic Holiday"):
|
||||
return (self.get_nth_weekday_in_month(year, 8, MON), label)
|
||||
|
||||
|
||||
class ThanksgivingMixin(Calendar):
|
||||
class ThanksgivingMixin:
|
||||
"2nd Monday of October"
|
||||
|
||||
def get_thanksgiving(self, year):
|
||||
|
@ -62,7 +61,7 @@ class ThanksgivingMixin(Calendar):
|
|||
return (thanksgiving, "Thanksgiving")
|
||||
|
||||
|
||||
class BoxingDayMixin(Calendar):
|
||||
class BoxingDayMixin:
|
||||
"26th of December; shift to next working day"
|
||||
|
||||
def get_boxing_day(self, year):
|
||||
|
@ -78,7 +77,7 @@ class BoxingDayMixin(Calendar):
|
|||
return days
|
||||
|
||||
|
||||
class StJeanBaptisteMixin(Calendar):
|
||||
class StJeanBaptisteMixin:
|
||||
"24th of June; shift to next working day"
|
||||
|
||||
def get_st_jean(self, year):
|
||||
|
@ -92,7 +91,7 @@ class StJeanBaptisteMixin(Calendar):
|
|||
return days
|
||||
|
||||
|
||||
class RemembranceDayShiftMixin(Calendar):
|
||||
class RemembranceDayShiftMixin:
|
||||
"11th of November; shift to next day"
|
||||
def get_remembrance_day(self, year):
|
||||
remembranceday = date(year, 11, 11)
|
||||
|
@ -106,8 +105,9 @@ class RemembranceDayShiftMixin(Calendar):
|
|||
|
||||
|
||||
@iso_register('CA-ON')
|
||||
class Ontario(Canada, BoxingDayMixin, ThanksgivingMixin, VictoriaDayMixin,
|
||||
LateFamilyDayMixin, AugustCivicHolidayMixin):
|
||||
class Ontario(BoxingDayMixin, ThanksgivingMixin, VictoriaDayMixin,
|
||||
LateFamilyDayMixin, AugustCivicHolidayMixin,
|
||||
Canada):
|
||||
"Ontario"
|
||||
include_good_friday = True
|
||||
|
||||
|
@ -125,7 +125,7 @@ class Ontario(Canada, BoxingDayMixin, ThanksgivingMixin, VictoriaDayMixin,
|
|||
|
||||
|
||||
@iso_register('CA-QC')
|
||||
class Quebec(Canada, VictoriaDayMixin, StJeanBaptisteMixin, ThanksgivingMixin):
|
||||
class Quebec(VictoriaDayMixin, StJeanBaptisteMixin, ThanksgivingMixin, Canada):
|
||||
"Quebec"
|
||||
include_easter_monday = True
|
||||
|
||||
|
@ -140,8 +140,8 @@ class Quebec(Canada, VictoriaDayMixin, StJeanBaptisteMixin, ThanksgivingMixin):
|
|||
|
||||
|
||||
@iso_register('CA-BC')
|
||||
class BritishColumbia(Canada, VictoriaDayMixin, AugustCivicHolidayMixin,
|
||||
ThanksgivingMixin):
|
||||
class BritishColumbia(VictoriaDayMixin, AugustCivicHolidayMixin,
|
||||
ThanksgivingMixin, Canada):
|
||||
"British Columbia"
|
||||
|
||||
include_good_friday = True
|
||||
|
@ -176,7 +176,7 @@ class BritishColumbia(Canada, VictoriaDayMixin, AugustCivicHolidayMixin,
|
|||
|
||||
|
||||
@iso_register('CA-AB')
|
||||
class Alberta(Canada, LateFamilyDayMixin, VictoriaDayMixin, ThanksgivingMixin):
|
||||
class Alberta(LateFamilyDayMixin, VictoriaDayMixin, ThanksgivingMixin, Canada):
|
||||
"Alberta"
|
||||
include_good_friday = True
|
||||
|
||||
|
@ -195,9 +195,9 @@ class Alberta(Canada, LateFamilyDayMixin, VictoriaDayMixin, ThanksgivingMixin):
|
|||
|
||||
|
||||
@iso_register('CA-SK')
|
||||
class Saskatchewan(Canada, LateFamilyDayMixin, VictoriaDayMixin,
|
||||
class Saskatchewan(LateFamilyDayMixin, VictoriaDayMixin,
|
||||
RemembranceDayShiftMixin, AugustCivicHolidayMixin,
|
||||
ThanksgivingMixin):
|
||||
ThanksgivingMixin, Canada):
|
||||
"Saskatchewan"
|
||||
include_good_friday = True
|
||||
|
||||
|
@ -214,8 +214,9 @@ class Saskatchewan(Canada, LateFamilyDayMixin, VictoriaDayMixin,
|
|||
|
||||
|
||||
@iso_register('CA-MB')
|
||||
class Manitoba(Canada, LateFamilyDayMixin, VictoriaDayMixin,
|
||||
AugustCivicHolidayMixin, ThanksgivingMixin):
|
||||
class Manitoba(LateFamilyDayMixin, VictoriaDayMixin,
|
||||
AugustCivicHolidayMixin, ThanksgivingMixin,
|
||||
Canada):
|
||||
"Manitoba"
|
||||
include_good_friday = True
|
||||
|
||||
|
@ -231,7 +232,7 @@ class Manitoba(Canada, LateFamilyDayMixin, VictoriaDayMixin,
|
|||
|
||||
|
||||
@iso_register('CA-NB')
|
||||
class NewBrunswick(Canada, AugustCivicHolidayMixin):
|
||||
class NewBrunswick(AugustCivicHolidayMixin, Canada):
|
||||
"New Brunswick"
|
||||
|
||||
FIXED_HOLIDAYS = Canada.FIXED_HOLIDAYS + (
|
||||
|
@ -247,7 +248,7 @@ class NewBrunswick(Canada, AugustCivicHolidayMixin):
|
|||
|
||||
|
||||
@iso_register('CA-NS')
|
||||
class NovaScotia(Canada, RemembranceDayShiftMixin, LateFamilyDayMixin):
|
||||
class NovaScotia(RemembranceDayShiftMixin, LateFamilyDayMixin, Canada):
|
||||
"Nova Scotia"
|
||||
|
||||
include_good_friday = True
|
||||
|
@ -261,7 +262,7 @@ class NovaScotia(Canada, RemembranceDayShiftMixin, LateFamilyDayMixin):
|
|||
|
||||
|
||||
@iso_register('CA-PE')
|
||||
class PrinceEdwardIsland(Canada, LateFamilyDayMixin, RemembranceDayShiftMixin):
|
||||
class PrinceEdwardIsland(LateFamilyDayMixin, RemembranceDayShiftMixin, Canada):
|
||||
"Prince Edward Island"
|
||||
|
||||
include_good_friday = True
|
||||
|
@ -280,7 +281,7 @@ class Newfoundland(Canada):
|
|||
|
||||
|
||||
@iso_register('CA-YT')
|
||||
class Yukon(Canada, VictoriaDayMixin, ThanksgivingMixin):
|
||||
class Yukon(VictoriaDayMixin, ThanksgivingMixin, Canada):
|
||||
"Yukon"
|
||||
|
||||
FIXED_HOLIDAYS = Canada.FIXED_HOLIDAYS + (
|
||||
|
@ -300,8 +301,8 @@ class Yukon(Canada, VictoriaDayMixin, ThanksgivingMixin):
|
|||
|
||||
|
||||
@iso_register('CA-NT')
|
||||
class NorthwestTerritories(Canada, RemembranceDayShiftMixin, VictoriaDayMixin,
|
||||
ThanksgivingMixin):
|
||||
class NorthwestTerritories(RemembranceDayShiftMixin, VictoriaDayMixin,
|
||||
ThanksgivingMixin, Canada):
|
||||
"Northwest Territories"
|
||||
|
||||
FIXED_HOLIDAYS = Canada.FIXED_HOLIDAYS + (
|
||||
|
@ -321,8 +322,8 @@ class NorthwestTerritories(Canada, RemembranceDayShiftMixin, VictoriaDayMixin,
|
|||
|
||||
|
||||
@iso_register('CA-NU')
|
||||
class Nunavut(Canada, VictoriaDayMixin, ThanksgivingMixin,
|
||||
RemembranceDayShiftMixin):
|
||||
class Nunavut(VictoriaDayMixin, ThanksgivingMixin, RemembranceDayShiftMixin,
|
||||
Canada):
|
||||
"Nunavut"
|
||||
include_good_friday = True
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
from datetime import date
|
||||
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import MON, TUE, WED, FRI
|
||||
from ..core import WesternCalendar, MON, TUE, WED, FRI
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('CL')
|
||||
class Chile(WesternCalendar, ChristianMixin):
|
||||
class Chile(WesternCalendar):
|
||||
"Chile"
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from datetime import timedelta, date
|
||||
|
||||
from ..core import WesternCalendar, ChristianMixin, MON
|
||||
from ..core import WesternCalendar, MON
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('CO')
|
||||
class Colombia(WesternCalendar, ChristianMixin):
|
||||
class Colombia(WesternCalendar):
|
||||
"Colombia"
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
from datetime import date, timedelta
|
||||
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import SUN, MON, SAT
|
||||
from ..core import WesternCalendar, SUN, MON, SAT
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('MX')
|
||||
class Mexico(WesternCalendar, ChristianMixin):
|
||||
class Mexico(WesternCalendar):
|
||||
"Mexico"
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from datetime import timedelta
|
||||
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('PA')
|
||||
class Panama(WesternCalendar, ChristianMixin):
|
||||
class Panama(WesternCalendar):
|
||||
"Panama"
|
||||
include_good_friday = True
|
||||
include_easter_saturday = True
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from datetime import date
|
||||
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('PY')
|
||||
class Paraguay(WesternCalendar, ChristianMixin):
|
||||
class Paraguay(WesternCalendar):
|
||||
"Paraguay"
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from datetime import date
|
||||
import warnings
|
||||
|
||||
from ..core import ChineseNewYearCalendar, WesternCalendar
|
||||
from ..core import ChineseNewYearCalendar, NewYearsDayMixin
|
||||
from ..registry_tools import iso_register
|
||||
from ..exceptions import CalendarError
|
||||
|
||||
|
@ -56,12 +56,12 @@ workdays = {
|
|||
|
||||
|
||||
@iso_register('CN')
|
||||
class China(ChineseNewYearCalendar, WesternCalendar):
|
||||
class China(NewYearsDayMixin, ChineseNewYearCalendar):
|
||||
"China"
|
||||
# WARNING: Support 2018, 2019 currently, need update every year.
|
||||
# National Days, 10.1 - 10.7
|
||||
national_days = [(10, i, "National Day") for i in range(1, 8)]
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + tuple(national_days)
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + tuple(national_days)
|
||||
|
||||
include_chinese_new_year_eve = True
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from datetime import date, timedelta
|
||||
|
||||
from ..core import (
|
||||
ChineseNewYearCalendar, WesternCalendar, ChristianMixin,
|
||||
ChineseNewYearCalendar, NewYearsDayMixin, WesternMixin,
|
||||
SUN, SAT
|
||||
)
|
||||
from ..astronomy import solar_term
|
||||
|
@ -9,7 +9,7 @@ from ..registry_tools import iso_register
|
|||
|
||||
|
||||
@iso_register('HK')
|
||||
class HongKong(WesternCalendar, ChineseNewYearCalendar, ChristianMixin):
|
||||
class HongKong(NewYearsDayMixin, WesternMixin, ChineseNewYearCalendar):
|
||||
"Hong Kong"
|
||||
include_good_friday = True
|
||||
include_easter_saturday = True
|
||||
|
@ -18,7 +18,7 @@ class HongKong(WesternCalendar, ChineseNewYearCalendar, ChristianMixin):
|
|||
|
||||
WEEKEND_DAYS = (SUN,)
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
(7, 1, "SAR Establishment Day"),
|
||||
(10, 1, "National Day"),
|
||||
|
|
|
@ -1,16 +1,18 @@
|
|||
from datetime import date
|
||||
|
||||
from ..core import MON
|
||||
from ..core import WesternCalendar
|
||||
from ..core import NewYearsDayMixin, Calendar, MON, SAT, SUN
|
||||
from ..astronomy import calculate_equinoxes
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('JP')
|
||||
class Japan(WesternCalendar):
|
||||
class Japan(NewYearsDayMixin, Calendar):
|
||||
"Japan"
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
# Japan uses the "western" workweek
|
||||
WEEKEND_DAYS = (SAT, SUN)
|
||||
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
(2, 11, "Foundation Day"),
|
||||
(4, 29, "Showa Day"),
|
||||
(5, 3, "Constitution Memorial Day"),
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
from datetime import date
|
||||
|
||||
from ..core import ChineseNewYearCalendar, WesternCalendar
|
||||
from ..core import IslamicMixin
|
||||
from ..core import (
|
||||
NewYearsDayMixin, IslamicMixin, ChineseNewYearCalendar,
|
||||
SAT, SUN
|
||||
)
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('MY')
|
||||
class Malaysia(ChineseNewYearCalendar, WesternCalendar, IslamicMixin):
|
||||
class Malaysia(NewYearsDayMixin, IslamicMixin, ChineseNewYearCalendar):
|
||||
"Malaysia"
|
||||
include_nuzul_al_quran = True
|
||||
include_eid_al_fitr = True
|
||||
|
@ -17,7 +19,11 @@ class Malaysia(ChineseNewYearCalendar, WesternCalendar, IslamicMixin):
|
|||
include_islamic_new_year = True
|
||||
include_prophet_birthday = True
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
# Most of th Malaysian territory uses these Week-end days
|
||||
WEEKEND_DAYS = (SAT, SUN)
|
||||
# TODO: Add calendar exceptions
|
||||
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
(2, 1, "Federal Territory Day"),
|
||||
(5, 1, "Workers' Day"),
|
||||
(8, 31, "National Day"),
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
from ..core import Calendar
|
||||
from ..core import FRI, SAT, IslamicMixin
|
||||
from ..core import IslamicCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('QA')
|
||||
class Qatar(IslamicMixin, Calendar):
|
||||
class Qatar(IslamicCalendar):
|
||||
"Qatar"
|
||||
WEEKEND_DAYS = (FRI, SAT)
|
||||
|
||||
FIXED_HOLIDAYS = (
|
||||
(12, 18, "National Day"),
|
||||
|
|
|
@ -1,26 +1,33 @@
|
|||
from datetime import date
|
||||
|
||||
from ..core import (
|
||||
ChineseNewYearCalendar, WesternCalendar, ChristianMixin, IslamicMixin
|
||||
NewYearsDayMixin, WesternMixin, IslamicMixin, ChineseNewYearCalendar,
|
||||
SAT, SUN
|
||||
)
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('SG')
|
||||
class Singapore(WesternCalendar,
|
||||
ChineseNewYearCalendar, ChristianMixin, IslamicMixin):
|
||||
class Singapore(NewYearsDayMixin, WesternMixin, IslamicMixin,
|
||||
ChineseNewYearCalendar):
|
||||
"Singapore"
|
||||
# Christian holiday
|
||||
include_good_friday = True
|
||||
|
||||
# Islamic holidays
|
||||
include_eid_al_fitr = True
|
||||
eid_al_fitr_label = "Hari Raya Puasa"
|
||||
include_day_of_sacrifice = True
|
||||
day_of_sacrifice_label = "Hari Raya Haji"
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
(8, 9, "National Day"),
|
||||
)
|
||||
|
||||
# Explicitely assign these WE days, Singapore calendar is too much of a mix
|
||||
WEEKEND_DAYS = (SAT, SUN)
|
||||
|
||||
# Diwali/Deepavali is sometimes celebrated on a different day to India
|
||||
# so this can't be put into a HinduMixin
|
||||
DEEPAVALI = {
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from ..core import ChineseNewYearCalendar, WesternCalendar
|
||||
from ..core import NewYearsDayMixin, ChineseNewYearCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('KR')
|
||||
class SouthKorea(WesternCalendar, ChineseNewYearCalendar):
|
||||
class SouthKorea(NewYearsDayMixin, ChineseNewYearCalendar):
|
||||
"South Korea"
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
(3, 1, "Independence Day"),
|
||||
(5, 5, "Children's Day"),
|
||||
(6, 6, "Memorial Day"),
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
from ..core import ChineseNewYearCalendar, WesternCalendar
|
||||
from ..core import NewYearsDayMixin, ChineseNewYearCalendar
|
||||
from ..astronomy import solar_term
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('TW')
|
||||
class Taiwan(ChineseNewYearCalendar, WesternCalendar):
|
||||
class Taiwan(NewYearsDayMixin, ChineseNewYearCalendar):
|
||||
"Taiwan (Republic of China)"
|
||||
FIXED_HOLIDAYS = (
|
||||
WesternCalendar.FIXED_HOLIDAYS +
|
||||
NewYearsDayMixin.FIXED_HOLIDAYS +
|
||||
(
|
||||
(2, 28, "228 Peace Memorial Day"),
|
||||
(4, 4, "Combination of Women's Day and Children's Day"),
|
||||
|
|
|
@ -42,7 +42,451 @@ def cleaned_date(day, keep_datetime=False):
|
|||
return day
|
||||
|
||||
|
||||
class Calendar:
|
||||
class NewYearsDayMixin:
|
||||
FIXED_HOLIDAYS = (
|
||||
(1, 1, 'New year'),
|
||||
)
|
||||
|
||||
shift_new_years_day = False
|
||||
|
||||
def get_variable_days(self, year):
|
||||
days = super().get_variable_days(year)
|
||||
new_year = date(year, 1, 1)
|
||||
if self.shift_new_years_day:
|
||||
if new_year.weekday() in self.get_weekend_days():
|
||||
days.append((
|
||||
self.find_following_working_day(new_year),
|
||||
"New Year shift"))
|
||||
return days
|
||||
|
||||
|
||||
class ChristianMixin:
|
||||
EASTER_METHOD = None # to be assigned in the inherited mixin
|
||||
include_epiphany = False
|
||||
include_clean_monday = False
|
||||
include_annunciation = False
|
||||
include_fat_tuesday = False
|
||||
# Fat tuesday forced to `None` to make sure this value is always set
|
||||
# We've seen that there was a wide variety of labels.
|
||||
fat_tuesday_label = None
|
||||
include_ash_wednesday = False
|
||||
ash_wednesday_label = "Ash Wednesday"
|
||||
include_palm_sunday = False
|
||||
include_holy_thursday = False
|
||||
include_good_friday = False
|
||||
good_friday_label = "Good Friday"
|
||||
include_easter_monday = False
|
||||
include_easter_saturday = False
|
||||
include_easter_sunday = False
|
||||
include_all_saints = False
|
||||
include_immaculate_conception = False
|
||||
immaculate_conception_label = "Immaculate Conception"
|
||||
include_christmas = True
|
||||
include_christmas_eve = False
|
||||
include_ascension = False
|
||||
include_assumption = False
|
||||
include_whit_sunday = False
|
||||
whit_sunday_label = 'Whit Sunday'
|
||||
include_whit_monday = False
|
||||
whit_monday_label = 'Whit Monday'
|
||||
include_corpus_christi = False
|
||||
include_boxing_day = False
|
||||
boxing_day_label = "Boxing Day"
|
||||
include_all_souls = False
|
||||
|
||||
def get_fat_tuesday(self, year):
|
||||
if not self.fat_tuesday_label:
|
||||
raise CalendarError(
|
||||
"Improperly configured: please provide a "
|
||||
"`fat_tuesday_label` value")
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return sunday - timedelta(days=47)
|
||||
|
||||
def get_ash_wednesday(self, year):
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return sunday - timedelta(days=46)
|
||||
|
||||
def get_palm_sunday(self, year):
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return sunday - timedelta(days=7)
|
||||
|
||||
def get_holy_thursday(self, year):
|
||||
"Return the date of the last thursday before easter"
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return sunday - timedelta(days=3)
|
||||
|
||||
def get_good_friday(self, year):
|
||||
"Return the date of the last friday before easter"
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return sunday - timedelta(days=2)
|
||||
|
||||
def get_clean_monday(self, year):
|
||||
"Return the clean monday date"
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return sunday - timedelta(days=48)
|
||||
|
||||
def get_easter_saturday(self, year):
|
||||
"Return the Easter Saturday date"
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return sunday - timedelta(days=1)
|
||||
|
||||
def get_easter_sunday(self, year):
|
||||
"Return the date of the easter (sunday) -- following the easter method"
|
||||
return easter.easter(year, self.EASTER_METHOD)
|
||||
|
||||
def get_easter_monday(self, year):
|
||||
"Return the date of the monday after easter"
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return sunday + timedelta(days=1)
|
||||
|
||||
def get_ascension_thursday(self, year):
|
||||
easter = self.get_easter_sunday(year)
|
||||
return easter + timedelta(days=39)
|
||||
|
||||
def get_whit_monday(self, year):
|
||||
easter = self.get_easter_sunday(year)
|
||||
return easter + timedelta(days=50)
|
||||
|
||||
def get_whit_sunday(self, year):
|
||||
easter = self.get_easter_sunday(year)
|
||||
return easter + timedelta(days=49)
|
||||
|
||||
def get_corpus_christi(self, year):
|
||||
return self.get_easter_sunday(year) + timedelta(days=60)
|
||||
|
||||
def shift_christmas_boxing_days(self, year):
|
||||
""" When Christmas and/or Boxing Day falls on a weekend, it is rolled
|
||||
forward to the next weekday.
|
||||
"""
|
||||
christmas = date(year, 12, 25)
|
||||
boxing_day = date(year, 12, 26)
|
||||
boxing_day_label = "{} Shift".format(self.boxing_day_label)
|
||||
results = []
|
||||
if christmas.weekday() in self.get_weekend_days():
|
||||
shift = self.find_following_working_day(christmas)
|
||||
results.append((shift, "Christmas Shift"))
|
||||
results.append((shift + timedelta(days=1), boxing_day_label))
|
||||
elif boxing_day.weekday() in self.get_weekend_days():
|
||||
shift = self.find_following_working_day(boxing_day)
|
||||
results.append((shift, boxing_day_label))
|
||||
return results
|
||||
|
||||
def get_variable_days(self, year): # noqa
|
||||
"Return the christian holidays list according to the mixin"
|
||||
days = super().get_variable_days(year)
|
||||
if self.include_epiphany:
|
||||
days.append((date(year, 1, 6), "Epiphany"))
|
||||
if self.include_clean_monday:
|
||||
days.append((self.get_clean_monday(year), "Clean Monday"))
|
||||
if self.include_annunciation:
|
||||
days.append((date(year, 3, 25), "Annunciation"))
|
||||
if self.include_fat_tuesday:
|
||||
days.append(
|
||||
(self.get_fat_tuesday(year), self.fat_tuesday_label)
|
||||
)
|
||||
if self.include_ash_wednesday:
|
||||
days.append(
|
||||
(self.get_ash_wednesday(year), self.ash_wednesday_label)
|
||||
)
|
||||
if self.include_palm_sunday:
|
||||
days.append((self.get_palm_sunday(year), "Palm Sunday"))
|
||||
if self.include_holy_thursday:
|
||||
days.append((self.get_holy_thursday(year), "Holy Thursday"))
|
||||
if self.include_good_friday:
|
||||
days.append((self.get_good_friday(year), self.good_friday_label))
|
||||
if self.include_easter_saturday:
|
||||
days.append((self.get_easter_saturday(year), "Easter Saturday"))
|
||||
if self.include_easter_sunday:
|
||||
days.append((self.get_easter_sunday(year), "Easter Sunday"))
|
||||
if self.include_easter_monday:
|
||||
days.append((self.get_easter_monday(year), "Easter Monday"))
|
||||
if self.include_assumption:
|
||||
days.append((date(year, 8, 15), "Assumption of Mary to Heaven"))
|
||||
if self.include_all_saints:
|
||||
days.append((date(year, 11, 1), "All Saints Day"))
|
||||
if self.include_all_souls:
|
||||
days.append((date(year, 11, 2), "All Souls Day"))
|
||||
if self.include_immaculate_conception:
|
||||
days.append((date(year, 12, 8), self.immaculate_conception_label))
|
||||
if self.include_christmas:
|
||||
days.append((date(year, 12, 25), "Christmas Day"))
|
||||
if self.include_christmas_eve:
|
||||
days.append((date(year, 12, 24), "Christmas Eve"))
|
||||
if self.include_boxing_day:
|
||||
days.append((date(year, 12, 26), self.boxing_day_label))
|
||||
if self.include_ascension:
|
||||
days.append((
|
||||
self.get_ascension_thursday(year), "Ascension Thursday"))
|
||||
if self.include_whit_monday:
|
||||
days.append((self.get_whit_monday(year), self.whit_monday_label))
|
||||
if self.include_whit_sunday:
|
||||
days.append((self.get_whit_sunday(year), self.whit_sunday_label))
|
||||
if self.include_corpus_christi:
|
||||
days.append((self.get_corpus_christi(year), "Corpus Christi"))
|
||||
return days
|
||||
|
||||
|
||||
class WesternMixin(ChristianMixin):
|
||||
"""
|
||||
General usage calendar for Western countries.
|
||||
|
||||
(chiefly Europe and Northern America)
|
||||
|
||||
"""
|
||||
EASTER_METHOD = easter.EASTER_WESTERN
|
||||
WEEKEND_DAYS = (SAT, SUN)
|
||||
|
||||
|
||||
class OrthodoxMixin(ChristianMixin):
|
||||
EASTER_METHOD = easter.EASTER_ORTHODOX
|
||||
WEEKEND_DAYS = (SAT, SUN)
|
||||
|
||||
|
||||
class LunarMixin:
|
||||
"""
|
||||
Calendar ready to compute luncar calendar days
|
||||
"""
|
||||
@staticmethod
|
||||
def lunar(year, month, day):
|
||||
return LunarDate(year, month, day).toSolarDate()
|
||||
|
||||
|
||||
class ChineseNewYearMixin(LunarMixin):
|
||||
"""
|
||||
Calendar including toolsets to compute the Chinese New Year holidays.
|
||||
"""
|
||||
include_chinese_new_year_eve = False
|
||||
chinese_new_year_eve_label = "Chinese New Year's eve"
|
||||
# Chinese New Year will be included by default
|
||||
include_chinese_new_year = True
|
||||
chinese_new_year_label = 'Chinese New Year'
|
||||
# Some countries include the 2nd lunar day as a holiday
|
||||
include_chinese_second_day = False
|
||||
chinese_second_day_label = "Chinese New Year (2nd day)"
|
||||
include_chinese_third_day = False
|
||||
chinese_third_day_label = "Chinese New Year (3rd day)"
|
||||
shift_sunday_holidays = False
|
||||
# Some calendars roll a starting Sunday CNY to Sat
|
||||
shift_start_cny_sunday = False
|
||||
|
||||
def get_chinese_new_year(self, year):
|
||||
"""
|
||||
Compute Chinese New Year days. To return a list of holidays.
|
||||
|
||||
By default, it'll at least return the Chinese New Year holidays chosen
|
||||
using the following options:
|
||||
|
||||
* ``include_chinese_new_year_eve``
|
||||
* ``include_chinese_new_year`` (on by default)
|
||||
* ``include_chinese_second_day``
|
||||
|
||||
If the ``shift_sunday_holidays`` option is on, the rules are the
|
||||
following.
|
||||
|
||||
* If the CNY1 falls on MON-FRI, there's not shift.
|
||||
* If the CNY1 falls on SAT, the CNY2 is shifted to the Monday after.
|
||||
* If the CNY1 falls on SUN, the CNY1 is shifted to the Monday after,
|
||||
and CNY2 is shifted to the Tuesday after.
|
||||
"""
|
||||
days = []
|
||||
|
||||
lunar_first_day = ChineseNewYearMixin.lunar(year, 1, 1)
|
||||
# Chinese new year's eve
|
||||
if self.include_chinese_new_year_eve:
|
||||
days.append((
|
||||
lunar_first_day - timedelta(days=1),
|
||||
self.chinese_new_year_eve_label
|
||||
))
|
||||
# Chinese new year (is included by default)
|
||||
if self.include_chinese_new_year:
|
||||
days.append((lunar_first_day, self.chinese_new_year_label))
|
||||
|
||||
if self.include_chinese_second_day:
|
||||
lunar_second_day = lunar_first_day + timedelta(days=1)
|
||||
days.append((
|
||||
lunar_second_day,
|
||||
self.chinese_second_day_label
|
||||
))
|
||||
if self.include_chinese_third_day:
|
||||
lunar_third_day = lunar_first_day + timedelta(days=2)
|
||||
days.append((
|
||||
lunar_third_day,
|
||||
self.chinese_third_day_label
|
||||
))
|
||||
|
||||
if self.shift_sunday_holidays:
|
||||
if lunar_first_day.weekday() == SUN:
|
||||
if self.shift_start_cny_sunday:
|
||||
days.append(
|
||||
(lunar_first_day - timedelta(days=1),
|
||||
"Chinese Lunar New Year shift"),
|
||||
)
|
||||
else:
|
||||
if self.include_chinese_third_day:
|
||||
shift_day = lunar_third_day
|
||||
else:
|
||||
shift_day = lunar_second_day
|
||||
days.append(
|
||||
(shift_day + timedelta(days=1),
|
||||
"Chinese Lunar New Year shift"),
|
||||
)
|
||||
if (lunar_second_day.weekday() == SUN
|
||||
and self.include_chinese_third_day):
|
||||
days.append(
|
||||
(lunar_third_day + timedelta(days=1),
|
||||
"Chinese Lunar New Year shift"),
|
||||
)
|
||||
return days
|
||||
|
||||
def get_variable_days(self, year):
|
||||
days = super().get_variable_days(year)
|
||||
days.extend(self.get_chinese_new_year(year))
|
||||
return days
|
||||
|
||||
def get_shifted_holidays(self, dates):
|
||||
"""
|
||||
Taking a list of existing holidays, yield a list of 'shifted' days if
|
||||
the holiday falls on SUN.
|
||||
"""
|
||||
for holiday, label in dates:
|
||||
if holiday.weekday() == SUN:
|
||||
yield (
|
||||
holiday + timedelta(days=1),
|
||||
label + ' shift'
|
||||
)
|
||||
|
||||
def get_calendar_holidays(self, year):
|
||||
"""
|
||||
Take into account the eventual shift to the next MON if any holiday
|
||||
falls on SUN.
|
||||
"""
|
||||
# Unshifted days are here:
|
||||
days = super().get_calendar_holidays(year)
|
||||
if self.shift_sunday_holidays:
|
||||
days_to_inspect = copy(days)
|
||||
for day_shifted in self.get_shifted_holidays(days_to_inspect):
|
||||
days.append(day_shifted)
|
||||
return days
|
||||
|
||||
|
||||
class CalverterMixin:
|
||||
conversion_method = None
|
||||
ISLAMIC_HOLIDAYS = ()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.calverter = Calverter()
|
||||
if self.conversion_method is None:
|
||||
raise NotImplementedError
|
||||
|
||||
def converted(self, year):
|
||||
conversion_method = getattr(
|
||||
self.calverter, 'jd_to_%s' % self.conversion_method)
|
||||
current = date(year, 1, 1)
|
||||
days = []
|
||||
while current.year == year:
|
||||
julian_day = self.calverter.gregorian_to_jd(
|
||||
current.year,
|
||||
current.month,
|
||||
current.day)
|
||||
days.append(conversion_method(julian_day))
|
||||
current = current + timedelta(days=1)
|
||||
return days
|
||||
|
||||
def calverted_years(self, year):
|
||||
converted = self.converted(year)
|
||||
generator = (y for y, m, d in converted)
|
||||
return sorted(list(set(generator)))
|
||||
|
||||
def get_islamic_holidays(self):
|
||||
return self.ISLAMIC_HOLIDAYS
|
||||
|
||||
def get_delta_islamic_holidays(self, year):
|
||||
"""
|
||||
Return the delta to add/substract according to the year or customs.
|
||||
|
||||
By default, to return None or timedelta(days=0)
|
||||
"""
|
||||
return None
|
||||
|
||||
def get_variable_days(self, year):
|
||||
warnings.warn('Please take note that, due to arbitrary decisions, '
|
||||
'this Islamic calendar computation may be wrong.')
|
||||
days = super().get_variable_days(year)
|
||||
years = self.calverted_years(year)
|
||||
conversion_method = getattr(
|
||||
self.calverter, '%s_to_jd' % self.conversion_method)
|
||||
for month, day, label in self.get_islamic_holidays():
|
||||
for y in years:
|
||||
jd = conversion_method(y, month, day)
|
||||
g_year, g_month, g_day = self.calverter.jd_to_gregorian(jd)
|
||||
holiday = date(g_year, g_month, g_day)
|
||||
|
||||
# Only add a delta if necessary
|
||||
delta = self.get_delta_islamic_holidays(year)
|
||||
if delta:
|
||||
holiday += delta
|
||||
|
||||
if holiday.year == year:
|
||||
days.append((holiday, label))
|
||||
return days
|
||||
|
||||
|
||||
class IslamicMixin(CalverterMixin):
|
||||
|
||||
WEEKEND_DAYS = (FRI, SAT)
|
||||
|
||||
conversion_method = 'islamic'
|
||||
include_prophet_birthday = False
|
||||
include_day_after_prophet_birthday = False
|
||||
include_start_ramadan = False
|
||||
include_eid_al_fitr = False
|
||||
length_eid_al_fitr = 1
|
||||
eid_al_fitr_label = "Eid al-Fitr"
|
||||
include_eid_al_adha = False
|
||||
length_eid_al_adha = 1
|
||||
include_day_of_sacrifice = False
|
||||
day_of_sacrifice_label = "Eid al-Adha"
|
||||
include_islamic_new_year = False
|
||||
include_laylat_al_qadr = False
|
||||
include_nuzul_al_quran = False
|
||||
|
||||
def get_islamic_holidays(self):
|
||||
"""Return a list of Islamic (month, day, label) for islamic holidays.
|
||||
Please take note that these dates must be expressed using the Islamic
|
||||
Calendar"""
|
||||
days = list(super().get_islamic_holidays())
|
||||
|
||||
if self.include_islamic_new_year:
|
||||
days.append((1, 1, "Islamic New Year"))
|
||||
if self.include_prophet_birthday:
|
||||
days.append((3, 12, "Prophet's Birthday"))
|
||||
if self.include_day_after_prophet_birthday:
|
||||
days.append((3, 13, "Day after Prophet's Birthday"))
|
||||
if self.include_start_ramadan:
|
||||
days.append((9, 1, "Start of ramadan"))
|
||||
if self.include_nuzul_al_quran:
|
||||
days.append((9, 17, "Nuzul Al-Qur'an"))
|
||||
if self.include_eid_al_fitr:
|
||||
for x in range(self.length_eid_al_fitr):
|
||||
days.append((10, x + 1, self.eid_al_fitr_label))
|
||||
if self.include_eid_al_adha:
|
||||
for x in range(self.length_eid_al_adha):
|
||||
days.append((12, x + 10, "Eid al-Adha"))
|
||||
if self.include_day_of_sacrifice:
|
||||
days.append((12, 10, self.day_of_sacrifice_label))
|
||||
if self.include_laylat_al_qadr:
|
||||
warnings.warn("The Islamic holiday named Laylat al-Qadr is decided"
|
||||
" by the religious authorities. It is not possible"
|
||||
" to compute it. You'll have to add it manually.")
|
||||
return tuple(days)
|
||||
|
||||
|
||||
class JalaliMixin(CalverterMixin):
|
||||
conversion_method = 'jalali'
|
||||
|
||||
|
||||
class CoreCalendar:
|
||||
|
||||
FIXED_HOLIDAYS = ()
|
||||
WEEKEND_DAYS = ()
|
||||
|
@ -368,438 +812,40 @@ class Calendar:
|
|||
return count
|
||||
|
||||
|
||||
class ChristianMixin(Calendar):
|
||||
EASTER_METHOD = None # to be assigned in the inherited mixin
|
||||
include_epiphany = False
|
||||
include_clean_monday = False
|
||||
include_annunciation = False
|
||||
include_fat_tuesday = False
|
||||
# Fat tuesday forced to `None` to make sure this value is always set
|
||||
# We've seen that there was a wide variety of labels.
|
||||
fat_tuesday_label = None
|
||||
include_ash_wednesday = False
|
||||
ash_wednesday_label = "Ash Wednesday"
|
||||
include_palm_sunday = False
|
||||
include_holy_thursday = False
|
||||
include_good_friday = False
|
||||
good_friday_label = "Good Friday"
|
||||
include_easter_monday = False
|
||||
include_easter_saturday = False
|
||||
include_easter_sunday = False
|
||||
include_all_saints = False
|
||||
include_immaculate_conception = False
|
||||
immaculate_conception_label = "Immaculate Conception"
|
||||
include_christmas = True
|
||||
include_christmas_eve = False
|
||||
include_ascension = False
|
||||
include_assumption = False
|
||||
include_whit_sunday = False
|
||||
whit_sunday_label = 'Whit Sunday'
|
||||
include_whit_monday = False
|
||||
whit_monday_label = 'Whit Monday'
|
||||
include_corpus_christi = False
|
||||
include_boxing_day = False
|
||||
boxing_day_label = "Boxing Day"
|
||||
include_all_souls = False
|
||||
|
||||
def get_fat_tuesday(self, year):
|
||||
if not self.fat_tuesday_label:
|
||||
raise CalendarError(
|
||||
"Improperly configured: please provide a "
|
||||
"`fat_tuesday_label` value")
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return sunday - timedelta(days=47)
|
||||
|
||||
def get_ash_wednesday(self, year):
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return sunday - timedelta(days=46)
|
||||
|
||||
def get_palm_sunday(self, year):
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return sunday - timedelta(days=7)
|
||||
|
||||
def get_holy_thursday(self, year):
|
||||
"Return the date of the last thursday before easter"
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return sunday - timedelta(days=3)
|
||||
|
||||
def get_good_friday(self, year):
|
||||
"Return the date of the last friday before easter"
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return sunday - timedelta(days=2)
|
||||
|
||||
def get_clean_monday(self, year):
|
||||
"Return the clean monday date"
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return sunday - timedelta(days=48)
|
||||
|
||||
def get_easter_saturday(self, year):
|
||||
"Return the Easter Saturday date"
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return sunday - timedelta(days=1)
|
||||
|
||||
def get_easter_sunday(self, year):
|
||||
"Return the date of the easter (sunday) -- following the easter method"
|
||||
return easter.easter(year, self.EASTER_METHOD)
|
||||
|
||||
def get_easter_monday(self, year):
|
||||
"Return the date of the monday after easter"
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return sunday + timedelta(days=1)
|
||||
|
||||
def get_ascension_thursday(self, year):
|
||||
easter = self.get_easter_sunday(year)
|
||||
return easter + timedelta(days=39)
|
||||
|
||||
def get_whit_monday(self, year):
|
||||
easter = self.get_easter_sunday(year)
|
||||
return easter + timedelta(days=50)
|
||||
|
||||
def get_whit_sunday(self, year):
|
||||
easter = self.get_easter_sunday(year)
|
||||
return easter + timedelta(days=49)
|
||||
|
||||
def get_corpus_christi(self, year):
|
||||
return self.get_easter_sunday(year) + timedelta(days=60)
|
||||
|
||||
def shift_christmas_boxing_days(self, year):
|
||||
""" When Christmas and/or Boxing Day falls on a weekend, it is rolled
|
||||
forward to the next weekday.
|
||||
"""
|
||||
christmas = date(year, 12, 25)
|
||||
boxing_day = date(year, 12, 26)
|
||||
boxing_day_label = "{} Shift".format(self.boxing_day_label)
|
||||
results = []
|
||||
if christmas.weekday() in self.get_weekend_days():
|
||||
shift = self.find_following_working_day(christmas)
|
||||
results.append((shift, "Christmas Shift"))
|
||||
results.append((shift + timedelta(days=1), boxing_day_label))
|
||||
elif boxing_day.weekday() in self.get_weekend_days():
|
||||
shift = self.find_following_working_day(boxing_day)
|
||||
results.append((shift, boxing_day_label))
|
||||
return results
|
||||
|
||||
def get_variable_days(self, year): # noqa
|
||||
"Return the christian holidays list according to the mixin"
|
||||
days = super().get_variable_days(year)
|
||||
if self.include_epiphany:
|
||||
days.append((date(year, 1, 6), "Epiphany"))
|
||||
if self.include_clean_monday:
|
||||
days.append((self.get_clean_monday(year), "Clean Monday"))
|
||||
if self.include_annunciation:
|
||||
days.append((date(year, 3, 25), "Annunciation"))
|
||||
if self.include_fat_tuesday:
|
||||
days.append(
|
||||
(self.get_fat_tuesday(year), self.fat_tuesday_label)
|
||||
)
|
||||
if self.include_ash_wednesday:
|
||||
days.append(
|
||||
(self.get_ash_wednesday(year), self.ash_wednesday_label)
|
||||
)
|
||||
if self.include_palm_sunday:
|
||||
days.append((self.get_palm_sunday(year), "Palm Sunday"))
|
||||
if self.include_holy_thursday:
|
||||
days.append((self.get_holy_thursday(year), "Holy Thursday"))
|
||||
if self.include_good_friday:
|
||||
days.append((self.get_good_friday(year), self.good_friday_label))
|
||||
if self.include_easter_saturday:
|
||||
days.append((self.get_easter_saturday(year), "Easter Saturday"))
|
||||
if self.include_easter_sunday:
|
||||
days.append((self.get_easter_sunday(year), "Easter Sunday"))
|
||||
if self.include_easter_monday:
|
||||
days.append((self.get_easter_monday(year), "Easter Monday"))
|
||||
if self.include_assumption:
|
||||
days.append((date(year, 8, 15), "Assumption of Mary to Heaven"))
|
||||
if self.include_all_saints:
|
||||
days.append((date(year, 11, 1), "All Saints Day"))
|
||||
if self.include_all_souls:
|
||||
days.append((date(year, 11, 2), "All Souls Day"))
|
||||
if self.include_immaculate_conception:
|
||||
days.append((date(year, 12, 8), self.immaculate_conception_label))
|
||||
if self.include_christmas:
|
||||
days.append((date(year, 12, 25), "Christmas Day"))
|
||||
if self.include_christmas_eve:
|
||||
days.append((date(year, 12, 24), "Christmas Eve"))
|
||||
if self.include_boxing_day:
|
||||
days.append((date(year, 12, 26), self.boxing_day_label))
|
||||
if self.include_ascension:
|
||||
days.append((
|
||||
self.get_ascension_thursday(year), "Ascension Thursday"))
|
||||
if self.include_whit_monday:
|
||||
days.append((self.get_whit_monday(year), self.whit_monday_label))
|
||||
if self.include_whit_sunday:
|
||||
days.append((self.get_whit_sunday(year), self.whit_sunday_label))
|
||||
if self.include_corpus_christi:
|
||||
days.append((self.get_corpus_christi(year), "Corpus Christi"))
|
||||
return days
|
||||
class Calendar(CoreCalendar):
|
||||
pass
|
||||
|
||||
|
||||
class WesternCalendar(Calendar):
|
||||
class WesternCalendar(NewYearsDayMixin, WesternMixin, Calendar):
|
||||
"""
|
||||
General usage calendar for Western countries.
|
||||
|
||||
(chiefly Europe and Northern America)
|
||||
|
||||
A Christian calendar using Western definition for Easter.
|
||||
"""
|
||||
EASTER_METHOD = easter.EASTER_WESTERN
|
||||
|
||||
|
||||
class OrthodoxCalendar(NewYearsDayMixin, OrthodoxMixin, Calendar):
|
||||
"""
|
||||
A Christian calendar using Orthodox definition for Easter.
|
||||
"""
|
||||
|
||||
|
||||
class ChineseNewYearCalendar(ChineseNewYearMixin, Calendar):
|
||||
"""
|
||||
Chinese Calendar, using Chinese New Year computation.
|
||||
"""
|
||||
# There are regional exceptions to those week-end days, to define locally.
|
||||
WEEKEND_DAYS = (SAT, SUN)
|
||||
shift_new_years_day = False
|
||||
|
||||
FIXED_HOLIDAYS = (
|
||||
(1, 1, 'New year'),
|
||||
)
|
||||
|
||||
def get_variable_days(self, year):
|
||||
days = super().get_variable_days(year)
|
||||
new_year = date(year, 1, 1)
|
||||
if self.shift_new_years_day:
|
||||
if new_year.weekday() in self.get_weekend_days():
|
||||
days.append((
|
||||
self.find_following_working_day(new_year),
|
||||
"New Year shift"))
|
||||
return days
|
||||
|
||||
|
||||
class OrthodoxMixin(ChristianMixin):
|
||||
EASTER_METHOD = easter.EASTER_ORTHODOX
|
||||
|
||||
|
||||
class LunarCalendar(Calendar):
|
||||
class IslamicCalendar(IslamicMixin, Calendar):
|
||||
"""
|
||||
Calendar ready to compute luncar calendar days
|
||||
Islamic calendar
|
||||
"""
|
||||
@staticmethod
|
||||
def lunar(year, month, day):
|
||||
return LunarDate(year, month, day).toSolarDate()
|
||||
|
||||
|
||||
class ChineseNewYearCalendar(LunarCalendar):
|
||||
class IslamoWesternCalendar(IslamicMixin, WesternMixin, Calendar):
|
||||
"""
|
||||
Calendar including toolsets to compute the Chinese New Year holidays.
|
||||
Mix of Islamic and Western calendars.
|
||||
|
||||
When countries have both Islamic and Western-Christian holidays.
|
||||
"""
|
||||
include_chinese_new_year_eve = False
|
||||
chinese_new_year_eve_label = "Chinese New Year's eve"
|
||||
# Chinese New Year will be included by default
|
||||
include_chinese_new_year = True
|
||||
chinese_new_year_label = 'Chinese New Year'
|
||||
# Some countries include the 2nd lunar day as a holiday
|
||||
include_chinese_second_day = False
|
||||
chinese_second_day_label = "Chinese New Year (2nd day)"
|
||||
include_chinese_third_day = False
|
||||
chinese_third_day_label = "Chinese New Year (3rd day)"
|
||||
shift_sunday_holidays = False
|
||||
# Some calendars roll a starting Sunday CNY to Sat
|
||||
shift_start_cny_sunday = False
|
||||
|
||||
def get_chinese_new_year(self, year):
|
||||
"""
|
||||
Compute Chinese New Year days. To return a list of holidays.
|
||||
|
||||
By default, it'll at least return the Chinese New Year holidays chosen
|
||||
using the following options:
|
||||
|
||||
* ``include_chinese_new_year_eve``
|
||||
* ``include_chinese_new_year`` (on by default)
|
||||
* ``include_chinese_second_day``
|
||||
|
||||
If the ``shift_sunday_holidays`` option is on, the rules are the
|
||||
following.
|
||||
|
||||
* If the CNY1 falls on MON-FRI, there's not shift.
|
||||
* If the CNY1 falls on SAT, the CNY2 is shifted to the Monday after.
|
||||
* If the CNY1 falls on SUN, the CNY1 is shifted to the Monday after,
|
||||
and CNY2 is shifted to the Tuesday after.
|
||||
"""
|
||||
days = []
|
||||
|
||||
lunar_first_day = ChineseNewYearCalendar.lunar(year, 1, 1)
|
||||
# Chinese new year's eve
|
||||
if self.include_chinese_new_year_eve:
|
||||
days.append((
|
||||
lunar_first_day - timedelta(days=1),
|
||||
self.chinese_new_year_eve_label
|
||||
))
|
||||
# Chinese new year (is included by default)
|
||||
if self.include_chinese_new_year:
|
||||
days.append((lunar_first_day, self.chinese_new_year_label))
|
||||
|
||||
if self.include_chinese_second_day:
|
||||
lunar_second_day = lunar_first_day + timedelta(days=1)
|
||||
days.append((
|
||||
lunar_second_day,
|
||||
self.chinese_second_day_label
|
||||
))
|
||||
if self.include_chinese_third_day:
|
||||
lunar_third_day = lunar_first_day + timedelta(days=2)
|
||||
days.append((
|
||||
lunar_third_day,
|
||||
self.chinese_third_day_label
|
||||
))
|
||||
|
||||
if self.shift_sunday_holidays:
|
||||
if lunar_first_day.weekday() == SUN:
|
||||
if self.shift_start_cny_sunday:
|
||||
days.append(
|
||||
(lunar_first_day - timedelta(days=1),
|
||||
"Chinese Lunar New Year shift"),
|
||||
)
|
||||
else:
|
||||
if self.include_chinese_third_day:
|
||||
shift_day = lunar_third_day
|
||||
else:
|
||||
shift_day = lunar_second_day
|
||||
days.append(
|
||||
(shift_day + timedelta(days=1),
|
||||
"Chinese Lunar New Year shift"),
|
||||
)
|
||||
if (lunar_second_day.weekday() == SUN
|
||||
and self.include_chinese_third_day):
|
||||
days.append(
|
||||
(lunar_third_day + timedelta(days=1),
|
||||
"Chinese Lunar New Year shift"),
|
||||
)
|
||||
return days
|
||||
|
||||
def get_variable_days(self, year):
|
||||
days = super().get_variable_days(year)
|
||||
days.extend(self.get_chinese_new_year(year))
|
||||
return days
|
||||
|
||||
def get_shifted_holidays(self, dates):
|
||||
"""
|
||||
Taking a list of existing holidays, yield a list of 'shifted' days if
|
||||
the holiday falls on SUN.
|
||||
"""
|
||||
for holiday, label in dates:
|
||||
if holiday.weekday() == SUN:
|
||||
yield (
|
||||
holiday + timedelta(days=1),
|
||||
label + ' shift'
|
||||
)
|
||||
|
||||
def get_calendar_holidays(self, year):
|
||||
"""
|
||||
Take into account the eventual shift to the next MON if any holiday
|
||||
falls on SUN.
|
||||
"""
|
||||
# Unshifted days are here:
|
||||
days = super().get_calendar_holidays(year)
|
||||
if self.shift_sunday_holidays:
|
||||
days_to_inspect = copy(days)
|
||||
for day_shifted in self.get_shifted_holidays(days_to_inspect):
|
||||
days.append(day_shifted)
|
||||
return days
|
||||
|
||||
|
||||
class CalverterMixin(Calendar):
|
||||
conversion_method = None
|
||||
ISLAMIC_HOLIDAYS = ()
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.calverter = Calverter()
|
||||
if self.conversion_method is None:
|
||||
raise NotImplementedError
|
||||
|
||||
def converted(self, year):
|
||||
conversion_method = getattr(
|
||||
self.calverter, 'jd_to_%s' % self.conversion_method)
|
||||
current = date(year, 1, 1)
|
||||
days = []
|
||||
while current.year == year:
|
||||
julian_day = self.calverter.gregorian_to_jd(
|
||||
current.year,
|
||||
current.month,
|
||||
current.day)
|
||||
days.append(conversion_method(julian_day))
|
||||
current = current + timedelta(days=1)
|
||||
return days
|
||||
|
||||
def calverted_years(self, year):
|
||||
converted = self.converted(year)
|
||||
generator = (y for y, m, d in converted)
|
||||
return sorted(list(set(generator)))
|
||||
|
||||
def get_islamic_holidays(self):
|
||||
return self.ISLAMIC_HOLIDAYS
|
||||
|
||||
def get_delta_islamic_holidays(self, year):
|
||||
"""
|
||||
Return the delta to add/substract according to the year or customs.
|
||||
|
||||
By default, to return None or timedelta(days=0)
|
||||
"""
|
||||
return None
|
||||
|
||||
def get_variable_days(self, year):
|
||||
warnings.warn('Please take note that, due to arbitrary decisions, '
|
||||
'this Islamic calendar computation may be wrong.')
|
||||
days = super().get_variable_days(year)
|
||||
years = self.calverted_years(year)
|
||||
conversion_method = getattr(
|
||||
self.calverter, '%s_to_jd' % self.conversion_method)
|
||||
for month, day, label in self.get_islamic_holidays():
|
||||
for y in years:
|
||||
jd = conversion_method(y, month, day)
|
||||
g_year, g_month, g_day = self.calverter.jd_to_gregorian(jd)
|
||||
holiday = date(g_year, g_month, g_day)
|
||||
|
||||
# Only add a delta if necessary
|
||||
delta = self.get_delta_islamic_holidays(year)
|
||||
if delta:
|
||||
holiday += delta
|
||||
|
||||
if holiday.year == year:
|
||||
days.append((holiday, label))
|
||||
return days
|
||||
|
||||
|
||||
class IslamicMixin(CalverterMixin):
|
||||
conversion_method = 'islamic'
|
||||
include_prophet_birthday = False
|
||||
include_day_after_prophet_birthday = False
|
||||
include_start_ramadan = False
|
||||
include_eid_al_fitr = False
|
||||
length_eid_al_fitr = 1
|
||||
eid_al_fitr_label = "Eid al-Fitr"
|
||||
include_eid_al_adha = False
|
||||
length_eid_al_adha = 1
|
||||
include_day_of_sacrifice = False
|
||||
day_of_sacrifice_label = "Eid al-Adha"
|
||||
include_islamic_new_year = False
|
||||
include_laylat_al_qadr = False
|
||||
include_nuzul_al_quran = False
|
||||
|
||||
def get_islamic_holidays(self):
|
||||
"""Return a list of Islamic (month, day, label) for islamic holidays.
|
||||
Please take note that these dates must be expressed using the Islamic
|
||||
Calendar"""
|
||||
days = list(super().get_islamic_holidays())
|
||||
|
||||
if self.include_islamic_new_year:
|
||||
days.append((1, 1, "Islamic New Year"))
|
||||
if self.include_prophet_birthday:
|
||||
days.append((3, 12, "Prophet's Birthday"))
|
||||
if self.include_day_after_prophet_birthday:
|
||||
days.append((3, 13, "Day after Prophet's Birthday"))
|
||||
if self.include_start_ramadan:
|
||||
days.append((9, 1, "Start of ramadan"))
|
||||
if self.include_nuzul_al_quran:
|
||||
days.append((9, 17, "Nuzul Al-Qur'an"))
|
||||
if self.include_eid_al_fitr:
|
||||
for x in range(self.length_eid_al_fitr):
|
||||
days.append((10, x + 1, self.eid_al_fitr_label))
|
||||
if self.include_eid_al_adha:
|
||||
for x in range(self.length_eid_al_adha):
|
||||
days.append((12, x + 10, "Eid al-Adha"))
|
||||
if self.include_day_of_sacrifice:
|
||||
days.append((12, 10, self.day_of_sacrifice_label))
|
||||
if self.include_laylat_al_qadr:
|
||||
warnings.warn("The Islamic holiday named Laylat al-Qadr is decided"
|
||||
" by the religious authorities. It is not possible"
|
||||
" to compute it. You'll have to add it manually.")
|
||||
return tuple(days)
|
||||
|
||||
|
||||
class JalaliMixin(CalverterMixin):
|
||||
conversion_method = 'jalali'
|
||||
FIXED_HOLIDAYS = Calendar.FIXED_HOLIDAYS
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('AT')
|
||||
class Austria(WesternCalendar, ChristianMixin):
|
||||
class Austria(WesternCalendar):
|
||||
'Austria'
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
from datetime import timedelta
|
||||
from ..core import WesternCalendar, OrthodoxMixin
|
||||
from ..core import OrthodoxCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('BY')
|
||||
class Belarus(WesternCalendar, OrthodoxMixin):
|
||||
class Belarus(OrthodoxCalendar):
|
||||
'Belarus'
|
||||
"as of http://president.gov.by/en/holidays_en/"
|
||||
|
||||
include_christmas = False
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = OrthodoxCalendar.FIXED_HOLIDAYS + (
|
||||
(1, 2, "Day After New Year"),
|
||||
(1, 7, "Christmas (Orthodox)"),
|
||||
(3, 8, "International Women's Day"),
|
||||
|
@ -24,15 +24,10 @@ class Belarus(WesternCalendar, OrthodoxMixin):
|
|||
# https://en.wikipedia.org/wiki/Radonitsa
|
||||
|
||||
def get_radonitsa(self, year):
|
||||
# Second Monday after easter sunday
|
||||
return self.get_easter_sunday(year) + timedelta(days=15)
|
||||
|
||||
def get_day_after_radonitsa(self, year):
|
||||
# one day after the Radonsista Monday
|
||||
return self.get_radonitsa(year) + timedelta(days=1)
|
||||
# 9 Days after the Orthodox easter sunday
|
||||
return self.get_easter_sunday(year) + timedelta(days=9)
|
||||
|
||||
def get_variable_days(self, year):
|
||||
days = super().get_variable_days(year)
|
||||
days.append((self.get_radonitsa(year), "Radonista"))
|
||||
days.append((self.get_day_after_radonitsa(year), "Radonista Holiday"))
|
||||
days.append((self.get_radonitsa(year), "Radonitsa"))
|
||||
return days
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('BE')
|
||||
class Belgium(WesternCalendar, ChristianMixin):
|
||||
class Belgium(WesternCalendar):
|
||||
'Belgium'
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('BG')
|
||||
class Bulgaria(WesternCalendar, ChristianMixin):
|
||||
class Bulgaria(WesternCalendar):
|
||||
'Bulgaria'
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from datetime import date, timedelta
|
||||
|
||||
from ..core import WesternCalendar, ChristianMixin, MON, SAT
|
||||
from ..core import WesternCalendar, MON, SAT
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
|
@ -11,7 +11,7 @@ QUEENS_BIRTHDAY_EXCEPTIONS = {
|
|||
|
||||
|
||||
@iso_register('KY')
|
||||
class CaymanIslands(WesternCalendar, ChristianMixin):
|
||||
class CaymanIslands(WesternCalendar):
|
||||
"Cayman Islands"
|
||||
include_ash_wednesday = True
|
||||
include_good_friday = True
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from datetime import date
|
||||
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('HR')
|
||||
class Croatia(WesternCalendar, ChristianMixin):
|
||||
class Croatia(WesternCalendar):
|
||||
'Croatia'
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import timedelta
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('CY')
|
||||
class Cyprus(WesternCalendar, ChristianMixin):
|
||||
class Cyprus(WesternCalendar):
|
||||
'Cyprus'
|
||||
|
||||
include_epiphany = True
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('CZ')
|
||||
class CzechRepublic(WesternCalendar, ChristianMixin):
|
||||
class CzechRepublic(WesternCalendar):
|
||||
'Czech Republic'
|
||||
|
||||
include_easter_monday = True
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import timedelta
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('DK')
|
||||
class Denmark(WesternCalendar, ChristianMixin):
|
||||
class Denmark(WesternCalendar):
|
||||
'Denmark'
|
||||
|
||||
include_holy_thursday = True
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('EE')
|
||||
class Estonia(WesternCalendar, ChristianMixin):
|
||||
class Estonia(WesternCalendar):
|
||||
'Estonia'
|
||||
|
||||
include_good_friday = True
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
|
||||
|
||||
class EuropeanCentralBank(WesternCalendar, ChristianMixin):
|
||||
class EuropeanCentralBank(WesternCalendar):
|
||||
"European Central Bank"
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import date
|
||||
from ..core import WesternCalendar, ChristianMixin, FRI, SAT
|
||||
from ..core import WesternCalendar, FRI, SAT
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('FI')
|
||||
class Finland(WesternCalendar, ChristianMixin):
|
||||
class Finland(WesternCalendar):
|
||||
'Finland'
|
||||
|
||||
include_epiphany = True
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('FR')
|
||||
class France(WesternCalendar, ChristianMixin):
|
||||
class France(WesternCalendar):
|
||||
'France'
|
||||
|
||||
include_easter_monday = True
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import date, timedelta
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('DE')
|
||||
class Germany(WesternCalendar, ChristianMixin):
|
||||
class Germany(WesternCalendar):
|
||||
'Germany'
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
from ..core import WesternCalendar, OrthodoxMixin
|
||||
from ..core import OrthodoxCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('GR')
|
||||
class Greece(OrthodoxMixin, WesternCalendar):
|
||||
class Greece(OrthodoxCalendar):
|
||||
'Greece'
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = OrthodoxCalendar.FIXED_HOLIDAYS + (
|
||||
(3, 25, "Independence Day"),
|
||||
(5, 1, "Labour Day"),
|
||||
(10, 28, "Ohi Day"),
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('HU')
|
||||
class Hungary(WesternCalendar, ChristianMixin):
|
||||
class Hungary(WesternCalendar):
|
||||
'Hungary'
|
||||
|
||||
include_easter_sunday = True
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import date
|
||||
from ..core import WesternCalendar, ChristianMixin, THU, MON
|
||||
from ..core import WesternCalendar, THU, MON
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('IS')
|
||||
class Iceland(WesternCalendar, ChristianMixin):
|
||||
class Iceland(WesternCalendar):
|
||||
'Iceland'
|
||||
|
||||
include_holy_thursday = True
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import date, timedelta
|
||||
from ..core import WesternCalendar, ChristianMixin, MON
|
||||
from ..core import WesternCalendar, MON
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('IE')
|
||||
class Ireland(WesternCalendar, ChristianMixin):
|
||||
class Ireland(WesternCalendar):
|
||||
'Ireland'
|
||||
|
||||
include_easter_monday = True
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('IT')
|
||||
class Italy(WesternCalendar, ChristianMixin):
|
||||
class Italy(WesternCalendar):
|
||||
'Italy'
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import date
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('LV')
|
||||
class Latvia(WesternCalendar, ChristianMixin):
|
||||
class Latvia(WesternCalendar):
|
||||
'Latvia'
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin, SUN
|
||||
from ..core import WesternCalendar, SUN
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('LT')
|
||||
class Lithuania(WesternCalendar, ChristianMixin):
|
||||
class Lithuania(WesternCalendar):
|
||||
'Lithuania'
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import date
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('LU')
|
||||
class Luxembourg(WesternCalendar, ChristianMixin):
|
||||
class Luxembourg(WesternCalendar):
|
||||
'Luxembourg'
|
||||
|
||||
include_easter_monday = True
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('MT')
|
||||
class Malta(WesternCalendar, ChristianMixin):
|
||||
class Malta(WesternCalendar):
|
||||
'Malta'
|
||||
|
||||
include_good_friday = True
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import date, timedelta
|
||||
from ..core import WesternCalendar, ChristianMixin, SUN
|
||||
from ..core import WesternCalendar, SUN
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('NL')
|
||||
class Netherlands(WesternCalendar, ChristianMixin):
|
||||
class Netherlands(WesternCalendar):
|
||||
'Netherlands'
|
||||
|
||||
include_good_friday = True
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('NO')
|
||||
class Norway(WesternCalendar, ChristianMixin):
|
||||
class Norway(WesternCalendar):
|
||||
'Norway'
|
||||
|
||||
include_holy_thursday = True
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('PL')
|
||||
class Poland(WesternCalendar, ChristianMixin):
|
||||
class Poland(WesternCalendar):
|
||||
'Poland'
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import date
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('PT')
|
||||
class Portugal(WesternCalendar, ChristianMixin):
|
||||
class Portugal(WesternCalendar):
|
||||
'Portugal'
|
||||
|
||||
include_good_friday = True
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
from datetime import date
|
||||
from ..core import WesternCalendar, OrthodoxMixin
|
||||
from ..core import OrthodoxCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('RO')
|
||||
class Romania(OrthodoxMixin, WesternCalendar):
|
||||
class Romania(OrthodoxCalendar):
|
||||
'Romania'
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
(1, 2, "Day After New Years"),
|
||||
FIXED_HOLIDAYS = OrthodoxCalendar.FIXED_HOLIDAYS + (
|
||||
(1, 2, "Day After New Year"),
|
||||
(1, 24, "Union Day"),
|
||||
(5, 1, "Labour Day"),
|
||||
(8, 15, "Dormition of the Theotokos"),
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
from ..core import WesternCalendar
|
||||
from ..core import OrthodoxCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('RU')
|
||||
class Russia(WesternCalendar):
|
||||
class Russia(OrthodoxCalendar):
|
||||
'Russia'
|
||||
|
||||
shift_new_years_day = True
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = OrthodoxCalendar.FIXED_HOLIDAYS + (
|
||||
(1, 2, "Day After New Year"),
|
||||
(1, 7, "Christmas"),
|
||||
(2, 23, "Defendence of the Fatherland"),
|
||||
|
|
|
@ -24,7 +24,7 @@ FIXME:
|
|||
# necessary to split this module and associated tests
|
||||
from datetime import date, timedelta
|
||||
import warnings
|
||||
from ...core import WesternCalendar, ChristianMixin, MON, THU, FRI
|
||||
from ...core import WesternCalendar, MON, THU, FRI
|
||||
from .mixins import (
|
||||
SpringHolidayFirstMondayApril,
|
||||
SpringHolidaySecondMondayApril,
|
||||
|
@ -51,7 +51,7 @@ from .mixins import (
|
|||
)
|
||||
|
||||
|
||||
class Scotland(WesternCalendar, ChristianMixin):
|
||||
class Scotland(WesternCalendar):
|
||||
"Scotland"
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
(1, 2, "New Year Holiday"),
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
from ..core import WesternCalendar, OrthodoxMixin
|
||||
from ..core import OrthodoxCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('RS')
|
||||
class Serbia(OrthodoxMixin, WesternCalendar):
|
||||
class Serbia(OrthodoxCalendar):
|
||||
'Serbia'
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = OrthodoxCalendar.FIXED_HOLIDAYS + (
|
||||
(1, 2, "Day After New Year"),
|
||||
(1, 7, "Christmas"),
|
||||
(2, 15, "Statehood Day"),
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('SK')
|
||||
class Slovakia(WesternCalendar, ChristianMixin):
|
||||
class Slovakia(WesternCalendar):
|
||||
'Slovakia'
|
||||
|
||||
include_epiphany = True
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import date
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('SI')
|
||||
class Slovenia(WesternCalendar, ChristianMixin):
|
||||
class Slovenia(WesternCalendar):
|
||||
'Slovenia'
|
||||
|
||||
include_easter_sunday = True
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('ES')
|
||||
class Spain(WesternCalendar, ChristianMixin):
|
||||
class Spain(WesternCalendar):
|
||||
'Spain'
|
||||
|
||||
include_epiphany = True
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import date
|
||||
from ..core import WesternCalendar, ChristianMixin, FRI, SAT
|
||||
from ..core import WesternCalendar, FRI, SAT
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('SE')
|
||||
class Sweden(WesternCalendar, ChristianMixin):
|
||||
class Sweden(WesternCalendar):
|
||||
'Sweden'
|
||||
|
||||
include_epiphany = True
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import date, timedelta
|
||||
from ..core import WesternCalendar, ChristianMixin, SUN
|
||||
from ..core import WesternCalendar, SUN
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('CH')
|
||||
class Switzerland(WesternCalendar, ChristianMixin):
|
||||
class Switzerland(WesternCalendar):
|
||||
'Switzerland'
|
||||
|
||||
# ChristianMixin entries common to (most) cantons - opt out
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
from datetime import timedelta
|
||||
from ..core import WesternCalendar, IslamicMixin
|
||||
from ..core import NewYearsDayMixin, IslamicCalendar, SAT, SUN
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('TR')
|
||||
class Turkey(WesternCalendar, IslamicMixin):
|
||||
class Turkey(NewYearsDayMixin, IslamicCalendar):
|
||||
'Turkey'
|
||||
|
||||
shift_new_years_day = True
|
||||
# Even though they're using an islamic calendar, the work week is MON->FRI
|
||||
WEEKEND_DAYS = (SAT, SUN)
|
||||
|
||||
# Islamic Holidays
|
||||
include_eid_al_fitr = True
|
||||
|
@ -15,7 +16,7 @@ class Turkey(WesternCalendar, IslamicMixin):
|
|||
include_eid_al_adha = True
|
||||
length_eid_al_adha = 4
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
(4, 23, "National Sovereignty and Children's Day"),
|
||||
(5, 1, "Labor and Solidarity Day"),
|
||||
(5, 19, "Commemoration of Atatürk, Youth and Sports Day"),
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
from datetime import date
|
||||
from ..core import WesternCalendar, OrthodoxMixin
|
||||
from ..core import OrthodoxCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('UA')
|
||||
class Ukraine(OrthodoxMixin, WesternCalendar):
|
||||
class Ukraine(OrthodoxCalendar):
|
||||
'Ukraine'
|
||||
|
||||
shift_sunday_holidays = True
|
||||
shift_new_years_day = True
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = OrthodoxCalendar.FIXED_HOLIDAYS + (
|
||||
(3, 8, "International Women’s Day"),
|
||||
(5, 1, "Workers Solidarity Day"),
|
||||
(5, 9, "Victory Day"),
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import date
|
||||
from ..core import WesternCalendar, ChristianMixin, MON
|
||||
from ..core import WesternCalendar, MON
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('GB')
|
||||
class UnitedKingdom(WesternCalendar, ChristianMixin):
|
||||
class UnitedKingdom(WesternCalendar):
|
||||
'United Kingdom'
|
||||
|
||||
include_good_friday = True
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
from datetime import date, timedelta
|
||||
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import MON, TUE, SAT, SUN
|
||||
from ..core import WesternCalendar, MON, TUE, SAT, SUN
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('AU')
|
||||
class Australia(WesternCalendar, ChristianMixin):
|
||||
class Australia(WesternCalendar):
|
||||
"Australia"
|
||||
include_good_friday = True
|
||||
include_easter_monday = True
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import FRI
|
||||
from ..core import WesternCalendar, FRI
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('MH')
|
||||
class MarshallIslands(WesternCalendar, ChristianMixin):
|
||||
class MarshallIslands(WesternCalendar):
|
||||
"Marshall Islands"
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
(3, 3, "Remembrance Day"),
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from datetime import date, timedelta
|
||||
|
||||
from ..core import WesternCalendar, ChristianMixin, MON, SAT, SUN
|
||||
from ..core import WesternCalendar, MON, SAT, SUN
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register("NZ")
|
||||
class NewZealand(WesternCalendar, ChristianMixin):
|
||||
class NewZealand(WesternCalendar):
|
||||
"New Zealand"
|
||||
include_good_friday = True
|
||||
include_easter_monday = True
|
||||
|
|
|
@ -5,11 +5,26 @@ from unittest import TestCase
|
|||
from ..core import Calendar
|
||||
|
||||
|
||||
class GenericCalendarTest(TestCase):
|
||||
class CoreCalendarTest(TestCase):
|
||||
cal_class = Calendar
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
warnings.simplefilter('ignore')
|
||||
self.year = date.today().year
|
||||
self.cal = self.cal_class()
|
||||
|
||||
|
||||
class GenericCalendarTest(CoreCalendarTest):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
warnings.simplefilter('ignore')
|
||||
|
||||
def test_weekend_days(self):
|
||||
class_name = self.cal_class.__name__
|
||||
if class_name in ('Calendar',):
|
||||
return
|
||||
try:
|
||||
self.cal.get_weekend_days()
|
||||
except NotImplementedError:
|
||||
assert False, (self.cal, class_name)
|
||||
|
|
|
@ -4,16 +4,16 @@ from unittest import TestCase
|
|||
|
||||
import pandas
|
||||
|
||||
from . import GenericCalendarTest
|
||||
from . import CoreCalendarTest
|
||||
from ..core import (
|
||||
MON, TUE, THU, FRI, WED, SAT, SUN,
|
||||
Calendar, LunarCalendar, WesternCalendar,
|
||||
IslamicMixin, JalaliMixin, ChristianMixin
|
||||
Calendar, LunarMixin, WesternCalendar,
|
||||
IslamicMixin, JalaliMixin
|
||||
)
|
||||
from ..exceptions import UnsupportedDateType
|
||||
|
||||
|
||||
class CalendarTest(GenericCalendarTest):
|
||||
class CalendarTest(CoreCalendarTest):
|
||||
|
||||
def test_private_variables(self):
|
||||
self.assertTrue(hasattr(self.cal, '_holidays'))
|
||||
|
@ -104,12 +104,11 @@ class CalendarTest(GenericCalendarTest):
|
|||
)
|
||||
|
||||
|
||||
class LunarCalendarTest(GenericCalendarTest):
|
||||
cal_class = LunarCalendar
|
||||
class LunarCalendarTest(TestCase):
|
||||
|
||||
def test_new_year(self):
|
||||
def test_lunar_new_year(self):
|
||||
self.assertEquals(
|
||||
self.cal.lunar(2014, 1, 1),
|
||||
LunarMixin.lunar(2014, 1, 1),
|
||||
date(2014, 1, 31)
|
||||
)
|
||||
|
||||
|
@ -126,7 +125,7 @@ class MockCalendar(Calendar):
|
|||
return [] # no week-end, yes, it's sad
|
||||
|
||||
|
||||
class MockCalendarTest(GenericCalendarTest):
|
||||
class MockCalendarTest(CoreCalendarTest):
|
||||
cal_class = MockCalendar
|
||||
|
||||
def test_holidays_set(self):
|
||||
|
@ -239,7 +238,7 @@ class MockCalendarTest(GenericCalendarTest):
|
|||
)
|
||||
|
||||
|
||||
class IslamicMixinTest(GenericCalendarTest):
|
||||
class IslamicMixinTest(CoreCalendarTest):
|
||||
cal_class = IslamicMixin
|
||||
|
||||
def test_year_conversion(self):
|
||||
|
@ -247,7 +246,7 @@ class IslamicMixinTest(GenericCalendarTest):
|
|||
self.assertEquals(len(days), 365)
|
||||
|
||||
|
||||
class JalaliMixinTest(GenericCalendarTest):
|
||||
class JalaliMixinTest(CoreCalendarTest):
|
||||
cal_class = JalaliMixin
|
||||
|
||||
def test_year_conversion(self):
|
||||
|
@ -255,11 +254,12 @@ class JalaliMixinTest(GenericCalendarTest):
|
|||
self.assertEquals(len(days), 365)
|
||||
|
||||
|
||||
class MockChristianCalendar(WesternCalendar, ChristianMixin):
|
||||
class MockChristianCalendar(WesternCalendar):
|
||||
# WesternCalendar inherits from ChristianMixin
|
||||
pass
|
||||
|
||||
|
||||
class MockChristianCalendarTest(GenericCalendarTest):
|
||||
class MockChristianCalendarTest(CoreCalendarTest):
|
||||
cal_class = MockChristianCalendar
|
||||
|
||||
def test_year_2014(self):
|
||||
|
@ -297,7 +297,7 @@ class NoWeekendCalendar(Calendar):
|
|||
"""
|
||||
|
||||
|
||||
class NoWeekendCalendarTest(GenericCalendarTest):
|
||||
class NoWeekendCalendarTest(CoreCalendarTest):
|
||||
cal_class = NoWeekendCalendar
|
||||
|
||||
def test_weekend(self):
|
||||
|
@ -317,7 +317,7 @@ class WeekendOnWednesdayCalendar(Calendar):
|
|||
WEEKEND_DAYS = (WED,)
|
||||
|
||||
|
||||
class WeekendOnWednesdayCalendarTest(GenericCalendarTest):
|
||||
class WeekendOnWednesdayCalendarTest(CoreCalendarTest):
|
||||
cal_class = WeekendOnWednesdayCalendar
|
||||
|
||||
def test_weekend(self):
|
||||
|
@ -337,7 +337,7 @@ class OverwriteGetWeekendDaysCalendar(Calendar):
|
|||
return (WED,)
|
||||
|
||||
|
||||
class OverwriteGetWeekendDaysCalendarTest(GenericCalendarTest):
|
||||
class OverwriteGetWeekendDaysCalendarTest(CoreCalendarTest):
|
||||
cal_class = OverwriteGetWeekendDaysCalendar
|
||||
|
||||
def test_weekend(self):
|
||||
|
@ -487,7 +487,7 @@ class CalendarClassName(TestCase):
|
|||
)
|
||||
|
||||
|
||||
class TestAcceptableDateTypes(GenericCalendarTest):
|
||||
class TestAcceptableDateTypes(CoreCalendarTest):
|
||||
"""
|
||||
Test cases about accepted date and datetime types.
|
||||
"""
|
||||
|
@ -642,7 +642,7 @@ class TestAcceptableDateTypes(GenericCalendarTest):
|
|||
self.cal.get_holiday_label(datetime(2014, 1, 2)))
|
||||
|
||||
|
||||
class PandasTimestampTest(GenericCalendarTest):
|
||||
class PandasTimestampTest(CoreCalendarTest):
|
||||
cal_class = MockCalendar
|
||||
|
||||
def test_panda_type_is_working_day(self):
|
||||
|
|
|
@ -72,8 +72,7 @@ class BelarusTest(GenericCalendarTest):
|
|||
self.assertIn(date(2019, 1, 7), holidays) # Christmas (Orthodox)
|
||||
self.assertIn(date(2019, 3, 8), holidays) # International Women's Day
|
||||
self.assertIn(date(2019, 5, 1), holidays) # Labour Day
|
||||
self.assertIn(date(2019, 5, 6), holidays) # Radonista
|
||||
self.assertIn(date(2019, 5, 7), holidays) # Radonista Holiday
|
||||
self.assertIn(date(2019, 5, 7), holidays) # Radonitsa
|
||||
self.assertIn(date(2019, 5, 9), holidays) # Victory Day
|
||||
self.assertIn(date(2019, 7, 3), holidays) # Republic Day
|
||||
self.assertIn(date(2019, 11, 7), holidays) # October Revolution Day
|
||||
|
@ -85,8 +84,7 @@ class BelarusTest(GenericCalendarTest):
|
|||
self.assertIn(date(2020, 1, 2), holidays) # Day after NYE
|
||||
self.assertIn(date(2020, 1, 7), holidays) # Christmas (Orthodox)
|
||||
self.assertIn(date(2020, 3, 8), holidays) # International Women's Day
|
||||
self.assertIn(date(2020, 4, 27), holidays) # Radonista
|
||||
self.assertIn(date(2020, 4, 28), holidays) # Radonista Holiday
|
||||
self.assertIn(date(2020, 4, 28), holidays) # Radonitsa
|
||||
self.assertIn(date(2020, 5, 1), holidays) # Labour Day
|
||||
self.assertIn(date(2020, 5, 9), holidays) # Victory Day
|
||||
self.assertIn(date(2020, 7, 3), holidays) # Republic Day
|
||||
|
@ -569,6 +567,24 @@ class GreeceTest(GenericCalendarTest):
|
|||
self.assertIn(date(2013, 12, 25), holidays) # XMas
|
||||
self.assertIn(date(2013, 12, 26), holidays) # Glorifying mother of God
|
||||
|
||||
def test_year_2020(self):
|
||||
holidays = self.cal.holidays_set(2020)
|
||||
self.assertIn(date(2020, 1, 1), holidays) # new year
|
||||
self.assertIn(date(2020, 1, 6), holidays) # epiphany
|
||||
self.assertIn(date(2020, 3, 2), holidays) # Clean monday
|
||||
# Annunciation & Independence day
|
||||
self.assertIn(date(2020, 3, 25), holidays)
|
||||
self.assertIn(date(2020, 4, 17), holidays) # good friday
|
||||
self.assertIn(date(2020, 4, 19), holidays) # easter
|
||||
self.assertIn(date(2020, 4, 20), holidays) # easter monday
|
||||
self.assertIn(date(2020, 5, 1), holidays) # labour day
|
||||
self.assertIn(date(2020, 6, 7), holidays) # pentecost sunday
|
||||
self.assertIn(date(2020, 6, 8), holidays) # whit monday
|
||||
self.assertIn(date(2020, 8, 15), holidays) # Assumption
|
||||
self.assertIn(date(2020, 10, 28), holidays) # Ochi Day
|
||||
self.assertIn(date(2020, 12, 25), holidays) # XMas
|
||||
self.assertIn(date(2020, 12, 26), holidays) # Glorifying mother of God
|
||||
|
||||
|
||||
class HungaryTest(GenericCalendarTest):
|
||||
cal_class = Hungary
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
from datetime import date, timedelta
|
||||
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..core import WesternCalendar
|
||||
from ..core import SUN, MON, TUE, WED, THU, FRI, SAT
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('US')
|
||||
class UnitedStates(WesternCalendar, ChristianMixin):
|
||||
class UnitedStates(WesternCalendar):
|
||||
"United States of America"
|
||||
|
||||
FIXED_HOLIDAYS = WesternCalendar.FIXED_HOLIDAYS + (
|
||||
|
|
Loading…
Reference in New Issue