Moving Fat Tuesday calculation into the `workalendar.core` module
Also known as Mardi Gras, Carnaval, etc. it's used in at least 3 countries and some States / Counties in the USA.
This commit is contained in:
parent
6be0d0dcd0
commit
d1d9a183a5
|
@ -3,6 +3,7 @@
|
|||
## master (unreleased)
|
||||
|
||||
- Small fixes (docstrings, use of extends, etc) on Cayman Islands calendar (#507).
|
||||
- Moving Carnaval / Mardi Gras / Fat Tuesday calculation into the `workalendar.core` module, because it's used in at least 3 countries and some States / Counties in the USA.
|
||||
|
||||
## v10.0.0 (2020-06-05)
|
||||
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
from datetime import timedelta
|
||||
from ..core import WesternCalendar, ChristianMixin
|
||||
from ..registry_tools import iso_register
|
||||
|
||||
|
||||
@iso_register('AO')
|
||||
class Angola(WesternCalendar, ChristianMixin):
|
||||
"""Angola"""
|
||||
"Angola"
|
||||
|
||||
include_fat_tuesday = True
|
||||
fat_tuesday_label = "Dia de Carnaval"
|
||||
include_good_friday = True
|
||||
include_easter_sunday = True
|
||||
include_christmas = True
|
||||
|
@ -20,12 +21,3 @@ class Angola(WesternCalendar, ChristianMixin):
|
|||
(9, 17, "Dia do Fundador da Nação e do Herói Nacional"),
|
||||
(11, 11, "Dia da Independência Nacional"),
|
||||
)
|
||||
|
||||
def get_variable_entrudo(self, year):
|
||||
easter_sunday = self.get_easter_sunday(year)
|
||||
return easter_sunday - timedelta(days=47)
|
||||
|
||||
def get_variable_days(self, year):
|
||||
days = super().get_variable_days(year)
|
||||
days.append((self.get_variable_entrudo(year), "Dia de Carnaval"))
|
||||
return days
|
||||
|
|
|
@ -10,6 +10,8 @@ from ..registry_tools import iso_register
|
|||
class Argentina(WesternCalendar, ChristianMixin):
|
||||
'Argentina'
|
||||
|
||||
include_fat_tuesday = True
|
||||
fat_tuesday_label = "Carnival"
|
||||
include_good_friday = True
|
||||
include_easter_saturday = True
|
||||
include_easter_sunday = True
|
||||
|
@ -130,10 +132,6 @@ class Argentina(WesternCalendar, ChristianMixin):
|
|||
(self.get_easter_sunday(year) - timedelta(days=48),
|
||||
"Carnival Lunes"))
|
||||
|
||||
days.append(
|
||||
(self.get_easter_sunday(year) - timedelta(days=47),
|
||||
"Carnival"))
|
||||
|
||||
days.append(
|
||||
self.get_malvinas_day(year))
|
||||
|
||||
|
|
|
@ -33,14 +33,6 @@ class Brazil(WesternCalendar, ChristianMixin):
|
|||
include_nossa_senhora_conceicao = False
|
||||
include_easter_sunday = True
|
||||
|
||||
def get_carnaval(self, year):
|
||||
"""
|
||||
Return the third day of Carnaval (Tuesday)
|
||||
|
||||
This day is shared holidays by several Brazil states.
|
||||
"""
|
||||
return self.get_easter_sunday(year) - timedelta(days=47)
|
||||
|
||||
def get_variable_days(self, year):
|
||||
days = super().get_variable_days(year)
|
||||
if self.include_sao_jose:
|
||||
|
@ -231,6 +223,8 @@ class BrazilRioDeJaneiro(Brazil):
|
|||
(4, 23, "Dia de São Jorge"),
|
||||
(3, 1, "Aniversário da Cidade do Rio de Janeiro"),
|
||||
)
|
||||
include_fat_tuesday = True
|
||||
fat_tuesday_label = "Carnaval"
|
||||
include_servidor_publico = True
|
||||
servidor_publico_label = "Dia do Funcionário Público"
|
||||
include_consciencia_negra = True
|
||||
|
@ -247,7 +241,6 @@ class BrazilRioDeJaneiro(Brazil):
|
|||
|
||||
def get_variable_days(self, year):
|
||||
days = super().get_variable_days(year)
|
||||
days.append((self.get_carnaval(year), "Carnaval"))
|
||||
days.append((self.get_dia_do_comercio(year), "Dia do Comércio"))
|
||||
return days
|
||||
|
||||
|
@ -309,6 +302,8 @@ class BrazilSaoPauloCity(BrazilSaoPauloState):
|
|||
FIXED_HOLIDAYS = BrazilSaoPauloState.FIXED_HOLIDAYS + (
|
||||
(1, 25, "Anniversary of the city of São Paulo"),
|
||||
)
|
||||
include_fat_tuesday = True
|
||||
fat_tuesday_label = "Carnaval"
|
||||
include_easter_sunday = True
|
||||
include_corpus_christi = True
|
||||
include_good_friday = True
|
||||
|
@ -316,11 +311,6 @@ class BrazilSaoPauloCity(BrazilSaoPauloState):
|
|||
include_consciencia_negra = True
|
||||
consciencia_negra_label = "Dia da Consciência Negra"
|
||||
|
||||
def get_variable_days(self, year):
|
||||
days = super().get_variable_days(year)
|
||||
days.append((self.get_carnaval(year), "Carnaval"))
|
||||
return days
|
||||
|
||||
|
||||
@iso_register('BR-SE')
|
||||
class BrazilSergipe(Brazil):
|
||||
|
@ -388,6 +378,8 @@ class BrazilSerraCity(BrazilEspiritoSanto):
|
|||
FIXED_HOLIDAYS = BrazilEspiritoSanto.FIXED_HOLIDAYS + (
|
||||
(12, 26, "Dia do Serrano"),
|
||||
)
|
||||
include_fat_tuesday = True
|
||||
fat_tuesday_label = "Carnaval"
|
||||
include_ash_wednesday = True
|
||||
ash_wednesday_label = "Quarta-feira de cinzas"
|
||||
include_good_friday = True
|
||||
|
@ -397,9 +389,8 @@ class BrazilSerraCity(BrazilEspiritoSanto):
|
|||
|
||||
def get_variable_days(self, year):
|
||||
days = super().get_variable_days(year)
|
||||
carnaval_tuesday = self.get_carnaval(year)
|
||||
carnaval_tuesday = self.get_fat_tuesday(year)
|
||||
days.append((carnaval_tuesday - timedelta(days=1), "Carnaval Monday"))
|
||||
days.append((carnaval_tuesday, "Carnaval"))
|
||||
return days
|
||||
|
||||
|
||||
|
@ -583,6 +574,8 @@ class BrazilBankCalendar(Brazil):
|
|||
Calendar that considers only working days for bank transactions
|
||||
for companies and the general public
|
||||
"""
|
||||
include_fat_tuesday = True
|
||||
fat_tuesday_label = "Tuesday carnaval"
|
||||
include_good_friday = True
|
||||
include_ash_wednesday = True
|
||||
include_corpus_christi = True
|
||||
|
@ -610,22 +603,17 @@ class BrazilBankCalendar(Brazil):
|
|||
day for only internal bank transactions
|
||||
"""
|
||||
days = super().get_variable_days(year)
|
||||
tuesday_carnaval = self.get_carnaval(year)
|
||||
tuesday_carnaval = self.get_fat_tuesday(year)
|
||||
monday_carnaval = tuesday_carnaval - timedelta(days=1)
|
||||
|
||||
carnaval_days = [
|
||||
(monday_carnaval, "Monday carnaval"),
|
||||
(tuesday_carnaval, "Tuesday carnaval"),
|
||||
]
|
||||
days.append((monday_carnaval, "Monday carnaval"))
|
||||
|
||||
non_working_days = [
|
||||
(
|
||||
self.get_last_day_of_year_for_only_internal_bank_trans(year),
|
||||
"Last day of year for only internal bank transactions"
|
||||
)
|
||||
]
|
||||
days.append((
|
||||
self.get_last_day_of_year_for_only_internal_bank_trans(year),
|
||||
"Last day of year for only internal bank transactions"
|
||||
))
|
||||
|
||||
return days + carnaval_days + non_working_days
|
||||
return days
|
||||
|
||||
def find_following_working_day(self, day):
|
||||
"""
|
||||
|
|
|
@ -10,7 +10,7 @@ from calverter import Calverter
|
|||
from dateutil import easter
|
||||
from lunardate import LunarDate
|
||||
|
||||
from .exceptions import UnsupportedDateType
|
||||
from .exceptions import UnsupportedDateType, CalendarError
|
||||
|
||||
MON, TUE, WED, THU, FRI, SAT, SUN = range(7)
|
||||
|
||||
|
@ -373,6 +373,10 @@ class ChristianMixin(Calendar):
|
|||
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
|
||||
|
@ -398,6 +402,14 @@ class ChristianMixin(Calendar):
|
|||
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)
|
||||
|
@ -476,6 +488,10 @@ class ChristianMixin(Calendar):
|
|||
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)
|
||||
|
|
|
@ -549,6 +549,12 @@ class AngolaTest(GenericCalendarTest):
|
|||
# Dia do Natal – 25 de Dezembro
|
||||
self.assertIn(date(2018, 12, 25), holidays) # Natal
|
||||
|
||||
def test_carnaval_label(self):
|
||||
holidays = self.cal.holidays(2018)
|
||||
holidays_dict = dict(holidays)
|
||||
label_carnaval = holidays_dict[date(2018, 2, 13)]
|
||||
self.assertEqual(label_carnaval, "Dia de Carnaval")
|
||||
|
||||
|
||||
class KenyaTest(GenericCalendarTest):
|
||||
cal_class = Kenya
|
||||
|
|
|
@ -118,6 +118,12 @@ class ArgentinaTest(GenericCalendarTest):
|
|||
"Día Nacional de la Memoria por la Verdad y la Justicia"
|
||||
)
|
||||
|
||||
def test_carnival_label(self):
|
||||
holidays = self.cal.holidays(2020)
|
||||
holidays = dict(holidays)
|
||||
label_carnival = holidays[date(2020, 2, 25)]
|
||||
self.assertEqual(label_carnival, "Carnival")
|
||||
|
||||
|
||||
class ChileTest(GenericCalendarTest):
|
||||
cal_class = Chile
|
||||
|
|
|
@ -246,6 +246,12 @@ class BrazilRioDeJaneiroTest(BrazilTest):
|
|||
# Dia de Nossa Senhora da Conceição
|
||||
self.assertIn(date(2017, 12, 8), holidays)
|
||||
|
||||
def test_carnaval_label(self):
|
||||
holidays = self.cal.holidays(2017)
|
||||
holidays_dict = dict(holidays)
|
||||
label_carnaval = holidays_dict[date(2017, 2, 28)]
|
||||
self.assertEqual(label_carnaval, "Carnaval")
|
||||
|
||||
|
||||
class BrazilRioGrandeDoNorteTest(BrazilTest):
|
||||
cal_class = BrazilRioGrandeDoNorte
|
||||
|
@ -338,6 +344,12 @@ class SaoPauloCityTest(SaoPauloStateTest):
|
|||
"Sexta-feira da Paixão",
|
||||
)
|
||||
|
||||
def test_carnaval_label(self):
|
||||
holidays = self.cal.holidays(2013)
|
||||
holidays_dict = dict(holidays)
|
||||
label_carnaval = holidays_dict[date(2013, 2, 12)]
|
||||
self.assertEqual(label_carnaval, "Carnaval")
|
||||
|
||||
|
||||
class BrazilSergipeTest(BrazilTest):
|
||||
cal_class = BrazilSergipe
|
||||
|
@ -481,6 +493,12 @@ class BrazilSerraCityTest(BrazilEspiritoSantoTest):
|
|||
"Paixão do Cristo",
|
||||
)
|
||||
|
||||
def test_carnaval_label(self):
|
||||
holidays = self.cal.holidays(2017)
|
||||
holidays_dict = dict(holidays)
|
||||
label_carnaval = holidays_dict[date(2017, 2, 28)]
|
||||
self.assertEqual(label_carnaval, "Carnaval")
|
||||
|
||||
|
||||
class BrazilRioBrancoCityTest(BrazilAcreTest):
|
||||
"""
|
||||
|
@ -899,6 +917,12 @@ class BrazilBankCalendarTest(BrazilTest):
|
|||
working_day = self.cal.find_following_working_day(already_working_day)
|
||||
self.assertEquals(working_day, date(2017, 7, 25))
|
||||
|
||||
def test_carnaval_label(self):
|
||||
holidays = self.cal.holidays(2017)
|
||||
holidays_dict = dict(holidays)
|
||||
label_carnaval = holidays_dict[date(2017, 2, 28)]
|
||||
self.assertEqual(label_carnaval, "Tuesday carnaval")
|
||||
|
||||
|
||||
class TestIBGERegister(TestCase):
|
||||
|
||||
|
|
|
@ -207,7 +207,7 @@ class UnitedStatesTest(GenericCalendarTest):
|
|||
|
||||
def test_mardi_gras(self):
|
||||
year = 2017
|
||||
day, _ = self.cal.get_mardi_gras(year)
|
||||
day = self.cal.get_fat_tuesday(year)
|
||||
holidays = self.cal.holidays_set(year)
|
||||
self.assertNotIn(day, holidays)
|
||||
|
||||
|
@ -316,9 +316,11 @@ class IncludeMardiGras:
|
|||
"""
|
||||
def test_mardi_gras(self):
|
||||
year = 2017
|
||||
day, _ = self.cal.get_mardi_gras(year)
|
||||
holidays = self.cal.holidays_set(year)
|
||||
self.assertIn(day, holidays)
|
||||
day = self.cal.get_fat_tuesday(year)
|
||||
holidays = self.cal.holidays(year)
|
||||
holidays_dict = dict(holidays)
|
||||
self.assertIn(day, holidays_dict)
|
||||
self.assertEqual(holidays_dict[day], "Mardi Gras")
|
||||
|
||||
|
||||
class AlabamaTest(UnitedStatesTest):
|
||||
|
|
|
@ -16,12 +16,12 @@ class Alabama(UnitedStates):
|
|||
|
||||
class AlabamaBaldwinCounty(Alabama):
|
||||
"Baldwin County, Alabama"
|
||||
include_mardi_gras = True
|
||||
include_fat_tuesday = True
|
||||
|
||||
|
||||
class AlabamaMobileCounty(Alabama):
|
||||
"Mobile County, Alabama"
|
||||
include_mardi_gras = True
|
||||
include_fat_tuesday = True
|
||||
|
||||
|
||||
class AlabamaPerryCounty(Alabama):
|
||||
|
|
|
@ -59,7 +59,8 @@ class UnitedStates(WesternCalendar, ChristianMixin):
|
|||
national_memorial_day_label = "Memorial Day"
|
||||
|
||||
# Some regional variants
|
||||
include_mardi_gras = False
|
||||
include_fat_tuesday = False
|
||||
fat_tuesday_label = "Mardi Gras"
|
||||
|
||||
# Shift day mechanism
|
||||
# These days won't be shifted to next MON or previous FRI
|
||||
|
@ -272,13 +273,6 @@ class UnitedStates(WesternCalendar, ChristianMixin):
|
|||
self.national_memorial_day_label
|
||||
)
|
||||
|
||||
def get_mardi_gras(self, year):
|
||||
"""
|
||||
Mardi Gras is the Tuesday happening 47 days before Easter
|
||||
"""
|
||||
sunday = self.get_easter_sunday(year)
|
||||
return (sunday - timedelta(days=47), "Mardi Gras")
|
||||
|
||||
def get_variable_days(self, year):
|
||||
# usual variable days
|
||||
days = super().get_variable_days(year)
|
||||
|
@ -295,9 +289,6 @@ class UnitedStates(WesternCalendar, ChristianMixin):
|
|||
"Thanksgiving Day"),
|
||||
])
|
||||
|
||||
if self.include_mardi_gras:
|
||||
days.append(self.get_mardi_gras(year))
|
||||
|
||||
if self.include_federal_presidents_day:
|
||||
days.append(self.get_presidents_day(year))
|
||||
|
||||
|
|
|
@ -78,7 +78,7 @@ class FloridaLegal(Florida):
|
|||
(4, 2, 'Pascua Florida Day'),
|
||||
(6, 14, 'Flag Day'),
|
||||
)
|
||||
include_mardi_gras = True
|
||||
include_fat_tuesday = True
|
||||
include_lincoln_birthday = True
|
||||
include_federal_presidents_day = True
|
||||
include_good_friday = True
|
||||
|
|
|
@ -8,4 +8,4 @@ class Louisiana(UnitedStates):
|
|||
include_good_friday = True
|
||||
include_election_day_even = True
|
||||
include_columbus_day = False
|
||||
include_mardi_gras = True
|
||||
include_fat_tuesday = True
|
||||
|
|
Loading…
Reference in New Issue