Declaring the New year's Day as a worldwide holiday
To date, there are only two exceptions: Israel & Qatar refs #511
This commit is contained in:
parent
b347472334
commit
b3d7a11105
|
@ -3,6 +3,7 @@
|
|||
## master (unreleased)
|
||||
|
||||
- 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).
|
||||
- Declaring the New year's Day as a worldwide holiday, with only two exceptions (to date): Israel & Qatar (#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.
|
||||
|
|
|
@ -117,7 +117,7 @@ workon WORKALENDAR
|
|||
pip install tox
|
||||
```
|
||||
|
||||
With the `WesternCalendar` base class you have at least one holiday as a bonus: the New year's day, which is commonly a holiday.
|
||||
With the `WesternCalendar` base class you have at least one holiday as a bonus: the New Year's day, which is almost a worldwide holiday.
|
||||
|
||||
#### Add fixed days
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import IslamicCalendar, NewYearsDayMixin
|
||||
from ..core import IslamicCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('DZ')
|
||||
class Algeria(NewYearsDayMixin, IslamicCalendar):
|
||||
class Algeria(IslamicCalendar):
|
||||
"Algeria"
|
||||
# Islamic holidays
|
||||
include_prophet_birthday = True
|
||||
|
@ -11,8 +11,7 @@ class Algeria(NewYearsDayMixin, IslamicCalendar):
|
|||
include_day_of_sacrifice = True
|
||||
include_islamic_new_year = True
|
||||
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + \
|
||||
IslamicCalendar.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = IslamicCalendar.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
(7, 5, "Independence Day"),
|
||||
(11, 1, "Anniversary of the revolution"),
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import NewYearsDayMixin, IslamoWesternCalendar, SAT, SUN
|
||||
from ..core import IslamoWesternCalendar, SAT, SUN
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('BJ')
|
||||
class Benin(NewYearsDayMixin, IslamoWesternCalendar):
|
||||
class Benin(IslamoWesternCalendar):
|
||||
"Benin"
|
||||
# Christian holidays
|
||||
include_easter_monday = True
|
||||
|
@ -17,7 +17,7 @@ class Benin(NewYearsDayMixin, IslamoWesternCalendar):
|
|||
include_day_of_sacrifice = True
|
||||
include_day_of_sacrifice_label = "Tabaski"
|
||||
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = IslamoWesternCalendar.FIXED_HOLIDAYS + (
|
||||
(1, 10, "Traditional Day"),
|
||||
(5, 1, "Labour Day"),
|
||||
(8, 1, "Independence Day"),
|
||||
|
@ -25,5 +25,5 @@ class Benin(NewYearsDayMixin, IslamoWesternCalendar):
|
|||
(11, 30, "National Day"),
|
||||
)
|
||||
|
||||
# Explicitely assign these WE days, Benin has adopted the western workweek
|
||||
# Explicitly assign these WE days, Benin has adopted the western workweek
|
||||
WEEKEND_DAYS = (SAT, SUN)
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
from ..core import NewYearsDayMixin, IslamoWesternCalendar, SAT, SUN
|
||||
from ..core import IslamoWesternCalendar, SAT, SUN
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('CI')
|
||||
class IvoryCoast(NewYearsDayMixin, IslamoWesternCalendar):
|
||||
class IvoryCoast(IslamoWesternCalendar):
|
||||
"Ivory Coast"
|
||||
# Christian holidays
|
||||
include_easter_monday = True
|
||||
|
@ -17,7 +17,7 @@ class IvoryCoast(NewYearsDayMixin, IslamoWesternCalendar):
|
|||
include_day_of_sacrifice = True
|
||||
include_day_of_sacrifice_label = "Feast of the Sacrifice"
|
||||
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = IslamoWesternCalendar.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
(8, 7, "Independence Day"),
|
||||
(11, 15, "National Peace Day"),
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
from copy import copy
|
||||
from datetime import timedelta, date
|
||||
|
||||
from ..core import NewYearsDayMixin, IslamoWesternCalendar, SAT, SUN
|
||||
from ..core import IslamoWesternCalendar, SAT, SUN
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('KE')
|
||||
class Kenya(NewYearsDayMixin, IslamoWesternCalendar):
|
||||
class Kenya(IslamoWesternCalendar):
|
||||
"Kenya"
|
||||
# Christian holidays
|
||||
include_good_friday = True
|
||||
|
@ -16,10 +16,10 @@ class Kenya(NewYearsDayMixin, IslamoWesternCalendar):
|
|||
include_day_of_sacrifice = True
|
||||
shift_sunday_holidays = True
|
||||
|
||||
# Explicitely assign these WE days, Kenya has adopted the western workweek
|
||||
# Explicitly assign these WE days, Kenya has adopted the western workweek
|
||||
WEEKEND_DAYS = (SAT, SUN)
|
||||
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = IslamoWesternCalendar.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
(6, 1, "Madaraka Day"),
|
||||
(10, 20, "Mashujaa Day"),
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from datetime import date
|
||||
import warnings
|
||||
|
||||
from ..core import ChineseNewYearCalendar, NewYearsDayMixin
|
||||
from ..core import ChineseNewYearCalendar
|
||||
from ..registry_tools import iso_register
|
||||
from ..exceptions import CalendarError
|
||||
|
||||
|
@ -56,12 +56,12 @@ workdays = {
|
|||
|
||||
|
||||
@iso_register('CN')
|
||||
class China(NewYearsDayMixin, ChineseNewYearCalendar):
|
||||
class China(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 = NewYearsDayMixin.FIXED_HOLIDAYS + tuple(national_days)
|
||||
FIXED_HOLIDAYS = tuple(national_days)
|
||||
|
||||
include_chinese_new_year_eve = True
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
from datetime import date, timedelta
|
||||
|
||||
from ..core import (
|
||||
ChineseNewYearCalendar, NewYearsDayMixin, WesternMixin,
|
||||
ChineseNewYearCalendar, WesternMixin,
|
||||
SUN, SAT
|
||||
)
|
||||
from ..astronomy import solar_term
|
||||
|
@ -9,7 +9,7 @@ from ..registry_tools import iso_register
|
|||
|
||||
|
||||
@iso_register('HK')
|
||||
class HongKong(NewYearsDayMixin, WesternMixin, ChineseNewYearCalendar):
|
||||
class HongKong(WesternMixin, ChineseNewYearCalendar):
|
||||
"Hong Kong"
|
||||
include_good_friday = True
|
||||
include_easter_saturday = True
|
||||
|
@ -18,7 +18,7 @@ class HongKong(NewYearsDayMixin, WesternMixin, ChineseNewYearCalendar):
|
|||
|
||||
WEEKEND_DAYS = (SUN,)
|
||||
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = ChineseNewYearCalendar.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
(7, 1, "SAR Establishment Day"),
|
||||
(10, 1, "National Day"),
|
||||
|
|
|
@ -7,7 +7,7 @@ from ..registry_tools import iso_register
|
|||
@iso_register("IL")
|
||||
class Israel(Calendar):
|
||||
"Israel"
|
||||
|
||||
include_new_years_day = False
|
||||
WEEKEND_DAYS = (SAT, FRI)
|
||||
|
||||
def get_variable_days(self, year):
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
from datetime import date
|
||||
|
||||
from ..core import NewYearsDayMixin, Calendar, MON, SAT, SUN
|
||||
from ..core import Calendar, MON, SAT, SUN
|
||||
from ..astronomy import calculate_equinoxes
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('JP')
|
||||
class Japan(NewYearsDayMixin, Calendar):
|
||||
class Japan(Calendar):
|
||||
"Japan"
|
||||
|
||||
# Japan uses the "western" workweek
|
||||
WEEKEND_DAYS = (SAT, SUN)
|
||||
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = Calendar.FIXED_HOLIDAYS + (
|
||||
(2, 11, "Foundation Day"),
|
||||
(4, 29, "Showa Day"),
|
||||
(5, 3, "Constitution Memorial Day"),
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
from datetime import date
|
||||
|
||||
from ..core import (
|
||||
NewYearsDayMixin, IslamicMixin, ChineseNewYearCalendar,
|
||||
IslamicMixin, ChineseNewYearCalendar,
|
||||
SAT, SUN
|
||||
)
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('MY')
|
||||
class Malaysia(NewYearsDayMixin, IslamicMixin, ChineseNewYearCalendar):
|
||||
class Malaysia(IslamicMixin, ChineseNewYearCalendar):
|
||||
"Malaysia"
|
||||
include_nuzul_al_quran = True
|
||||
include_eid_al_fitr = True
|
||||
|
@ -23,7 +23,7 @@ class Malaysia(NewYearsDayMixin, IslamicMixin, ChineseNewYearCalendar):
|
|||
WEEKEND_DAYS = (SAT, SUN)
|
||||
# TODO: Add calendar exceptions
|
||||
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = ChineseNewYearCalendar.FIXED_HOLIDAYS + (
|
||||
(2, 1, "Federal Territory Day"),
|
||||
(5, 1, "Workers' Day"),
|
||||
(8, 31, "National Day"),
|
||||
|
|
|
@ -6,6 +6,8 @@ from ..registry_tools import iso_register
|
|||
class Qatar(IslamicCalendar):
|
||||
"Qatar"
|
||||
|
||||
include_new_years_day = False
|
||||
|
||||
FIXED_HOLIDAYS = (
|
||||
(12, 18, "National Day"),
|
||||
)
|
||||
|
|
|
@ -1,15 +1,14 @@
|
|||
from datetime import date
|
||||
|
||||
from ..core import (
|
||||
NewYearsDayMixin, WesternMixin, IslamicMixin, ChineseNewYearCalendar,
|
||||
WesternMixin, IslamicMixin, ChineseNewYearCalendar,
|
||||
SAT, SUN
|
||||
)
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('SG')
|
||||
class Singapore(NewYearsDayMixin, WesternMixin, IslamicMixin,
|
||||
ChineseNewYearCalendar):
|
||||
class Singapore(WesternMixin, IslamicMixin, ChineseNewYearCalendar):
|
||||
"Singapore"
|
||||
# Christian holiday
|
||||
include_good_friday = True
|
||||
|
@ -20,12 +19,12 @@ class Singapore(NewYearsDayMixin, WesternMixin, IslamicMixin,
|
|||
include_day_of_sacrifice = True
|
||||
day_of_sacrifice_label = "Hari Raya Haji"
|
||||
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = ChineseNewYearCalendar.FIXED_HOLIDAYS + (
|
||||
(5, 1, "Labour Day"),
|
||||
(8, 9, "National Day"),
|
||||
)
|
||||
|
||||
# Explicitely assign these WE days, Singapore calendar is too much of a mix
|
||||
# Explicitly 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
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
from ..core import NewYearsDayMixin, ChineseNewYearCalendar
|
||||
from ..core import ChineseNewYearCalendar
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('KR')
|
||||
class SouthKorea(NewYearsDayMixin, ChineseNewYearCalendar):
|
||||
class SouthKorea(ChineseNewYearCalendar):
|
||||
"South Korea"
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = ChineseNewYearCalendar.FIXED_HOLIDAYS + (
|
||||
(3, 1, "Independence Day"),
|
||||
(5, 5, "Children's Day"),
|
||||
(6, 6, "Memorial Day"),
|
||||
|
|
|
@ -1,18 +1,15 @@
|
|||
from ..core import NewYearsDayMixin, ChineseNewYearCalendar
|
||||
from ..core import ChineseNewYearCalendar
|
||||
from ..astronomy import solar_term
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('TW')
|
||||
class Taiwan(NewYearsDayMixin, ChineseNewYearCalendar):
|
||||
class Taiwan(ChineseNewYearCalendar):
|
||||
"Taiwan (Republic of China)"
|
||||
FIXED_HOLIDAYS = (
|
||||
NewYearsDayMixin.FIXED_HOLIDAYS +
|
||||
(
|
||||
(2, 28, "228 Peace Memorial Day"),
|
||||
(4, 4, "Combination of Women's Day and Children's Day"),
|
||||
(10, 10, "National Day/Double Tenth Day"),
|
||||
)
|
||||
FIXED_HOLIDAYS = ChineseNewYearCalendar.FIXED_HOLIDAYS + (
|
||||
(2, 28, "228 Peace Memorial Day"),
|
||||
(4, 4, "Combination of Women's Day and Children's Day"),
|
||||
(10, 10, "National Day/Double Tenth Day"),
|
||||
)
|
||||
include_chinese_new_year_eve = True
|
||||
include_chinese_second_day = True
|
||||
|
|
|
@ -42,24 +42,6 @@ def cleaned_date(day, keep_datetime=False):
|
|||
return day
|
||||
|
||||
|
||||
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
|
||||
|
@ -813,16 +795,40 @@ class CoreCalendar:
|
|||
|
||||
|
||||
class Calendar(CoreCalendar):
|
||||
pass
|
||||
"""
|
||||
The cornerstone of Earth calendars.
|
||||
|
||||
Take care of the New Years Day, which is almost a worldwide holiday.
|
||||
"""
|
||||
include_new_years_day = True
|
||||
shift_new_years_day = False
|
||||
|
||||
def get_fixed_holidays(self, year):
|
||||
days = super().get_fixed_holidays(year)
|
||||
if self.include_new_years_day:
|
||||
days.insert(
|
||||
0, (date(year, 1, 1), "New year")
|
||||
)
|
||||
return days
|
||||
|
||||
def get_variable_days(self, year):
|
||||
days = super().get_variable_days(year)
|
||||
new_year = date(year, 1, 1)
|
||||
if self.include_new_years_day and 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 WesternCalendar(NewYearsDayMixin, WesternMixin, Calendar):
|
||||
class WesternCalendar(WesternMixin, Calendar):
|
||||
"""
|
||||
A Christian calendar using Western definition for Easter.
|
||||
"""
|
||||
|
||||
|
||||
class OrthodoxCalendar(NewYearsDayMixin, OrthodoxMixin, Calendar):
|
||||
class OrthodoxCalendar(OrthodoxMixin, Calendar):
|
||||
"""
|
||||
A Christian calendar using Orthodox definition for Easter.
|
||||
"""
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
from datetime import timedelta
|
||||
from ..core import NewYearsDayMixin, IslamicCalendar, SAT, SUN
|
||||
from ..core import IslamicCalendar, SAT, SUN
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('TR')
|
||||
class Turkey(NewYearsDayMixin, IslamicCalendar):
|
||||
class Turkey(IslamicCalendar):
|
||||
'Turkey'
|
||||
shift_new_years_day = True
|
||||
# Even though they're using an islamic calendar, the work week is MON->FRI
|
||||
|
@ -16,7 +16,7 @@ class Turkey(NewYearsDayMixin, IslamicCalendar):
|
|||
include_eid_al_adha = True
|
||||
length_eid_al_adha = 4
|
||||
|
||||
FIXED_HOLIDAYS = NewYearsDayMixin.FIXED_HOLIDAYS + (
|
||||
FIXED_HOLIDAYS = IslamicCalendar.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"),
|
||||
|
|
|
@ -15,6 +15,7 @@ class CoreCalendarTest(TestCase):
|
|||
|
||||
|
||||
class GenericCalendarTest(CoreCalendarTest):
|
||||
test_include_january_1st = True
|
||||
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
@ -28,3 +29,13 @@ class GenericCalendarTest(CoreCalendarTest):
|
|||
self.cal.get_weekend_days()
|
||||
except NotImplementedError:
|
||||
assert False, (self.cal, class_name)
|
||||
|
||||
def test_january_1st(self):
|
||||
class_name = self.cal_class.__name__
|
||||
if class_name in ('Calendar',):
|
||||
return
|
||||
holidays = self.cal.holidays_set(self.year)
|
||||
if self.test_include_january_1st:
|
||||
self.assertIn(date(self.year, 1, 1), holidays)
|
||||
else:
|
||||
self.assertNotIn(date(self.year, 1, 1), holidays)
|
||||
|
|
|
@ -440,6 +440,7 @@ class MalaysiaTest(GenericCalendarTest):
|
|||
|
||||
class QatarTest(GenericCalendarTest):
|
||||
cal_class = Qatar
|
||||
test_include_january_1st = False
|
||||
|
||||
def test_year_2013(self):
|
||||
holidays = self.cal.holidays_set(2013)
|
||||
|
@ -580,6 +581,7 @@ class TaiwanTest(GenericCalendarTest):
|
|||
class IsraelTest(GenericCalendarTest):
|
||||
|
||||
cal_class = Israel
|
||||
test_include_january_1st = False
|
||||
|
||||
def test_holidays_2017(self):
|
||||
calculated_holidays = self.cal.holidays_set(2017)
|
||||
|
|
|
@ -348,6 +348,7 @@ class OverwriteGetWeekendDaysCalendarTest(CoreCalendarTest):
|
|||
|
||||
|
||||
class NoHolidayCalendar(Calendar):
|
||||
include_new_years_day = False
|
||||
WEEKEND_DAYS = (SAT, SUN)
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue