class Taiwan(HolidayBase): """ https://en.wikipedia.org/wiki/Public_holidays_in_Taiwan """ country = "TW" def __init__(self, **kwargs): HolidayBase.__init__(self, **kwargs) self.cnls = ChineseLuniSolar() def _populate(self, year): # New Year's Day if year > 1911: self[ date(year, JAN, 1) ] = "Founding of the Republic of China (New Year's Day)" hol_date = self.cnls.lunar_n_y_date(year) self[hol_date + rd(days=-1)] = "Chinese New Year's Eve" self[hol_date] = "Spring Festival" self[hol_date + rd(days=1)] = "Spring Festival" self[hol_date + rd(days=2)] = "Spring Festival" self[date(year, APR, 4)] = "Children's Day" self[self.cnls.lunar_to_gre(year, 5, 5)] = "Dragon Boat Festival" self[self.cnls.lunar_to_gre(year, 8, 15)] = "Mid-Autumn Festival" self[date(year, OCT, 10)] = "National Day" self[date(year, OCT, 11)] = "National Day" if year > 1947: self[date(year, FEB, 28)] = "Peace Memorial Day" if year == 2021: hol_date = self.cnls.lunar_n_y_date(year) self[hol_date + rd(days=3)] = "Spring Festival" self[hol_date + rd(days=4)] = "Spring Festival"
def __init__( self, years: Union[int, Iterable[int]] = None, expand: bool = True, observed: bool = True, prov: Optional[str] = None, state: Optional[str] = None, ) -> None: """ An subclass of :py:class:`HolidayBase` representing public holidays in Malaysia. If ``state`` is not supplied, only nationwide holidays are returned. The following ``state`` codes are used (ISO 3166-2 subdivision codes are not yet supported): - JHR: Johor - KDH: Kedah - KTN: Kelantan - MLK: Melaka - NSN: Negeri Sembilan - PHG: Pahang - PRK: Perak - PLS: Perlis - PNG: Pulau Pinang - SBH: Sabah - SWK: Sarawak - SGR: Selangor - TRG: Terengganu - KUL: FT Kuala Lumpur - LBN: FT Labuan - PJY: FT Putrajaya Limitations: - Prior to 2021: holidays are not accurate. - 2027 and later: Thaipusam dates are are estimated, and so denoted. Reference: `Wikipedia <https://en.wikipedia.org/wiki/Public_holidays_in_Malaysia>`__ Country created by: `Eden <https://github.com/jusce17>`__ Country maintained by: `Mike Borsetti <https://github.com/mborsetti>`__ See parameters and usage in :py:class:`HolidayBase`. """ self.country = "MY" self.cnls = ChineseLuniSolar() super().__init__(years, expand, observed, prov, state)
def __init__( self, years: Union[int, Iterable[int]] = None, expand: bool = True, observed: bool = True, prov: Optional[str] = None, state: Optional[str] = None, ) -> None: """ An subclass of :py:class:`HolidayBase` representing public holidays in Singapore. Limitations: - Prior to 1969: holidays are estimated. - Prior to 2000: holidays may not be accurate. - 2022 and later: the following four moving date holidays (whose exact date is announced yearly) are estimated, and so denoted: - Hari Raya Puasa - Hari Raya Haji - Vesak Day - Deepavali Sources: - `Holidays Act <https://sso.agc.gov.sg/Act/HA1998>`__ (Act 24 of 1968—Holidays (Amendment) Act 1968) - `Ministry of Manpower <https://www.mom.gov.sg/employment-practices/public-holidays>`__ References: - `Wikipedia <https://en.wikipedia.org/wiki/Public_holidays_in_Singapore>`__ Country created and maintained by: `Mike Borsetti <https://github.com/mborsetti>`__ See parameters and usage in :py:class:`HolidayBase`. """ self.country = "SG" self.cnls = ChineseLuniSolar() super().__init__(years, expand, observed, prov, state)
class China(HolidayBase): """ https://en.wikipedia.org/wiki/Public_holidays_in_China """ country = "CN" def __init__(self, **kwargs): self.cnls = ChineseLuniSolar() HolidayBase.__init__(self, **kwargs) def _populate(self, year): # New Year's Day if year > 1949: self[date(year, JAN, 1)] = "New Year's Day" self[date(year, MAY, 1)] = "Labour Day" hol_date = self.cnls.lunar_n_y_date(year) self[hol_date] = "Chinese New Year (Spring Festival)" self[hol_date + rd(days=+1)] = "Chinese New Year (Spring Festival)" self[date(year, OCT, 1)] = "National Day" self[date(year, OCT, 2)] = "National Day" if year > 2007: self[date(year, APR, 5)] = "Tomb-Sweeping Day" self[self.cnls.lunar_to_gre(year, 5, 5)] = "Dragon Boat Festival" self[self.cnls.lunar_to_gre(year, 8, 15)] = "Mid-Autumn Festival" if (year > 1999) and (year <= 2007): self[date(year, MAY, 2)] = "Labour Day" self[date(year, MAY, 3)] = "Labour Day" if year > 1999: self[date(year, OCT, 3)] = "National Day" if (year > 1999) and (year <= 2007): self[date(year, MAY, 2)] = "Labour Day" self[date(year, MAY, 3)] = "Labour Day" if (year > 2007) and (year <= 2013): self[self.cnls.lunar_to_gre(year, 1, 1) + rd(days=-1)] = "Chinese New Year (Spring Festival)" elif year > 1949: self[self.cnls.lunar_to_gre( year, 1, 3)] = "Chinese New Year (Spring Festival)"
def __init__(self, **kwargs): self.country = "HK" self.cnls = ChineseLuniSolar() HolidayBase.__init__(self, **kwargs)
class HongKong(HolidayBase): # https://www.gov.hk/en/about/abouthk/holiday/2020.htm # https://en.wikipedia.org/wiki/Public_holidays_in_Hong_Kong def __init__(self, **kwargs): self.country = "HK" self.cnls = ChineseLuniSolar() HolidayBase.__init__(self, **kwargs) def _populate(self, year): day_following = "The day following " # The first day of January name = "The first day of January" first_date = date(year, JAN, 1) if self.observed: if first_date.weekday() == SUN: self[first_date + rd(days=+1)] = day_following + self.first_lower(name) first_date = first_date + rd(days=+1) else: self[first_date] = name else: self[first_date] = name # Lunar New Year name = "Lunar New Year's Day" preceding_day_lunar = "The day preceding Lunar New Year's Day" second_day_lunar = "The second day of Lunar New Year" third_day_lunar = "The third day of Lunar New Year" fourth_day_lunar = "The fourth day of Lunar New Year" dt = self.cnls.lunar_n_y_date(year) new_year_date = date(dt.year, dt.month, dt.day) if self.observed: self[new_year_date] = name if new_year_date.weekday() in [MON, TUE, WED, THU]: self[new_year_date] = name self[new_year_date + rd(days=+1)] = second_day_lunar self[new_year_date + rd(days=+2)] = third_day_lunar elif new_year_date.weekday() == FRI: self[new_year_date] = name self[new_year_date + rd(days=+1)] = second_day_lunar self[new_year_date + rd(days=+3)] = fourth_day_lunar elif new_year_date.weekday() == SAT: self[new_year_date] = name self[new_year_date + rd(days=+2)] = third_day_lunar self[new_year_date + rd(days=+3)] = fourth_day_lunar elif new_year_date.weekday() == SUN: if year in [2006, 2007, 2010]: self[new_year_date + rd(days=-1)] = preceding_day_lunar self[new_year_date + rd(days=+1)] = second_day_lunar self[new_year_date + rd(days=+2)] = third_day_lunar else: self[new_year_date + rd(days=+1)] = second_day_lunar self[new_year_date + rd(days=+2)] = third_day_lunar self[new_year_date + rd(days=+3)] = fourth_day_lunar else: self[new_year_date] = name self[new_year_date + rd(days=+1)] = second_day_lunar self[new_year_date + rd(days=+2)] = third_day_lunar # Ching Ming Festival name = "Ching Ming Festival" if self.is_leap_year(year) or (self.is_leap_year(year - 1) and year > 2008): ching_ming_date = date(year, APR, 4) else: ching_ming_date = date(year, APR, 5) if self.observed: if ching_ming_date.weekday() == SUN: self[ching_ming_date + rd(days=+1)] = day_following + name ching_ming_date = ching_ming_date + rd(days=+1) else: self[ching_ming_date] = name else: self[ching_ming_date] = name # Easter Holiday good_friday = "Good Friday" easter_monday = "Easter Monday" if self.observed: self[easter(year) + rd(weekday=FR(-1))] = good_friday self[easter(year) + rd(weekday=SA(-1))] = (day_following + good_friday) if ching_ming_date == easter(year) + rd(weekday=MO): self[easter(year) + rd(weekday=MO) + rd(days=+1)] = (day_following + easter_monday) else: self[easter(year) + rd(weekday=MO)] = easter_monday else: self[easter(year) + rd(weekday=FR(-1))] = good_friday self[easter(year) + rd(weekday=SA(-1))] = (day_following + good_friday) self[easter(year) + rd(weekday=MO)] = easter_monday # Birthday of the Buddha name = "Birthday of the Buddha" dt = self.cnls.lunar_to_gre(year, 4, 8) buddha_date = date(dt.year, dt.month, dt.day) if self.observed: if buddha_date.weekday() == SUN: self[buddha_date + rd(days=+1)] = day_following + name else: self[buddha_date] = name else: self[buddha_date] = name # Labour Day name = "Labour Day" labour_date = date(year, MAY, 1) if self.observed: if labour_date.weekday() == SUN: self[labour_date + rd(days=+1)] = day_following + name else: self[labour_date] = name else: self[labour_date] = name # Tuen Ng Festival name = "Tuen Ng Festival" dt = self.cnls.lunar_to_gre(year, 5, 5) tuen_ng_date = date(dt.year, dt.month, dt.day) if self.observed: if tuen_ng_date.weekday() == SUN: self[tuen_ng_date + rd(days=+1)] = day_following + name else: self[tuen_ng_date] = name else: self[tuen_ng_date] = name # Hong Kong Special Administrative Region Establishment Day name = "Hong Kong Special Administrative Region Establishment Day" hksar_date = date(year, JUL, 1) if self.observed: if hksar_date.weekday() == SUN: self[hksar_date + rd(days=+1)] = day_following + name else: self[hksar_date] = name else: self[hksar_date] = name # Special holiday on 2015 - The 70th anniversary day of the victory # of the Chinese people's war of resistance against Japanese aggression name = ("The 70th anniversary day of the victory of the Chinese " + "people's war of resistance against Japanese aggression") if year == 2015: self[date(year, SEP, 3)] = name # Chinese Mid-Autumn Festival name = "Chinese Mid-Autumn Festival" dt = self.cnls.lunar_to_gre(year, 8, 15) mid_autumn_date = date(dt.year, dt.month, dt.day) if self.observed: if mid_autumn_date.weekday() == SAT: self[mid_autumn_date] = name else: self[mid_autumn_date + rd(days=+1)] = (day_following + "the " + name) mid_autumn_date = mid_autumn_date + rd(days=+1) else: self[mid_autumn_date] = name # National Day name = "National Day" national_date = date(year, OCT, 1) if self.observed: if (national_date.weekday() == SUN or national_date == mid_autumn_date): self[national_date + rd(days=+1)] = day_following + name else: self[national_date] = name else: self[national_date] = name # Chung Yeung Festival name = "Chung Yeung Festival" dt = self.cnls.lunar_to_gre(year, 9, 9) chung_yeung_date = date(dt.year, dt.month, dt.day) if self.observed: if chung_yeung_date.weekday() == SUN: self[chung_yeung_date + rd(days=+1)] = day_following + name else: self[chung_yeung_date] = name else: self[chung_yeung_date] = name # Christmas Day name = "Christmas Day" first_after_christmas = "The first weekday after " + name second_after_christmas = "The second weekday after " + name christmas_date = date(year, DEC, 25) if self.observed: if christmas_date.weekday() == SUN: self[christmas_date] = name self[christmas_date + rd(days=+1)] = first_after_christmas self[christmas_date + rd(days=+2)] = second_after_christmas elif christmas_date.weekday() == SAT: self[christmas_date] = name self[christmas_date + rd(days=+2)] = first_after_christmas else: self[christmas_date] = name self[christmas_date + rd(days=+1)] = first_after_christmas else: self[christmas_date] = name self[christmas_date + rd(days=+1)] = day_following + name def is_leap_year(self, year): if year % 4 != 0: return False elif year % 100 != 0: return True elif year % 400 != 0: return False else: return True def first_lower(self, s): return s[0].lower() + s[1:]
class Singapore(HolidayBase): def __init__( self, years: Union[int, Iterable[int]] = None, expand: bool = True, observed: bool = True, prov: Optional[str] = None, state: Optional[str] = None, ) -> None: """ An subclass of :py:class:`HolidayBase` representing public holidays in Singapore. Limitations: - Prior to 1969: holidays are estimated. - Prior to 2000: holidays may not be accurate. - 2022 and later: the following four moving date holidays (whose exact date is announced yearly) are estimated, and so denoted: - Hari Raya Puasa - Hari Raya Haji - Vesak Day - Deepavali Sources: - `Holidays Act <https://sso.agc.gov.sg/Act/HA1998>`__ (Act 24 of 1968—Holidays (Amendment) Act 1968) - `Ministry of Manpower <https://www.mom.gov.sg/employment-practices/public-holidays>`__ References: - `Wikipedia <https://en.wikipedia.org/wiki/Public_holidays_in_Singapore>`__ Country created and maintained by: `Mike Borsetti <https://github.com/mborsetti>`__ See parameters and usage in :py:class:`HolidayBase`. """ self.country = "SG" self.cnls = ChineseLuniSolar() super().__init__(years, expand, observed, prov, state) def _populate(self, year): # New Year's Day self[date(year, JAN, 1)] = "New Year's Day" # Chinese New Year (two days) hol_date = self.cnls.lunar_n_y_date(year) self[hol_date] = "Chinese New Year" self[hol_date + rd(days=+1)] = "Chinese New Year" # Hari Raya Puasa # aka Eid al-Fitr # date of observance is announced yearly dates_obs = { 2001: [(DEC, 16)], 2002: [(DEC, 6)], 2003: [(NOV, 25)], 2004: [(NOV, 14)], 2005: [(NOV, 3)], 2006: [(OCT, 24)], 2007: [(OCT, 13)], 2008: [(OCT, 1)], 2009: [(SEP, 20)], 2010: [(SEP, 10)], 2011: [(AUG, 30)], 2012: [(AUG, 19)], 2013: [(AUG, 8)], 2014: [(JUL, 28)], 2015: [(JUL, 17)], 2016: [(JUL, 6)], 2017: [(JUN, 25)], 2018: [(JUN, 15)], 2019: [(JUN, 5)], 2020: [(MAY, 24)], 2021: [(MAY, 13)], 2022: [(MAY, 2)], } if year in dates_obs: for date_obs in dates_obs[year]: hol_date = date(year, *date_obs) self[hol_date] = "Hari Raya Puasa" # Second day of Hari Raya Puasa (up to and including 1968) # Removed since we don't have Hari Raya Puasa dates for the # the years <= 1968: # if year <= 1968: # self[hol_date + rd(days=+1), # "Second day of Hari Raya Puasa") else: for date_obs in islamic_to_gre(year, 10, 1): hol_date = date_obs self[hol_date] = "Hari Raya Puasa* (*estimated)" # Second day of Hari Raya Puasa (up to and including 1968) if year <= 1968: hol_date += rd(days=+1) self[hol_date] = ("Second day of Hari Raya Puasa*" " (*estimated)") # Hari Raya Haji # aka Eid al-Adha # date of observance is announced yearly dates_obs = { 2001: [(MAR, 6)], 2002: [(FEB, 23)], 2003: [(FEB, 12)], 2004: [(FEB, 1)], 2005: [(JAN, 21)], 2006: [(JAN, 10)], 2007: [(DEC, 20)], 2008: [(DEC, 8)], 2009: [(NOV, 27)], 2010: [(NOV, 17)], 2011: [(NOV, 6)], 2012: [(OCT, 26)], 2013: [(OCT, 15)], 2014: [(OCT, 5)], 2015: [(SEP, 24)], 2016: [(SEP, 12)], 2017: [(SEP, 1)], 2018: [(AUG, 22)], 2019: [(AUG, 11)], 2020: [(JUL, 31)], 2021: [(JUL, 20)], 2022: [(JUL, 9)], } if year in dates_obs: for date_obs in dates_obs[year]: hol_date = date(year, *date_obs) self[hol_date] = "Hari Raya Haji" else: for date_obs in islamic_to_gre(year, 12, 10): hol_date = date_obs self[hol_date] = "Hari Raya Haji* (*estimated)" # Holy Saturday (up to and including 1968) if year <= 1968: self[easter(year) + rd(weekday=SA(-1))] = "Holy Saturday" # Good Friday self[easter(year) + rd(weekday=FR(-1))] = "Good Friday" # Easter Monday if year <= 1968: self[easter(year) + rd(weekday=MO(1))] = "Easter Monday" # Labour Day self[date(year, MAY, 1)] = "Labour Day" # Vesak Day # date of observance is announced yearly # https://en.wikipedia.org/wiki/Vesak#Dates_of_observance dates_obs = { 2001: (MAY, 7), 2002: (MAY, 27), 2003: (MAY, 15), 2004: (JUN, 2), 2005: (MAY, 23), 2006: (MAY, 12), 2007: (MAY, 31), 2008: (MAY, 19), 2009: (MAY, 9), 2010: (MAY, 28), 2011: (MAY, 17), 2012: (MAY, 5), 2013: (MAY, 24), 2014: (MAY, 13), 2015: (JUN, 1), 2016: (MAY, 20), 2017: (MAY, 10), 2018: (MAY, 29), 2019: (MAY, 19), 2020: (MAY, 7), 2021: (MAY, 26), 2022: (MAY, 15), } if year in dates_obs: hol_date = date(year, *dates_obs[year]) self[hol_date] = "Vesak Day" else: hol_date = self.cnls.vesak_date(year) self[hol_date] = "Vesak Day* (*estimated; ~10% chance +/- 1 day)" # National Day self[date(year, AUG, 9)] = "National Day" # Deepavali # aka Diwali # date of observance is announced yearly dates_obs = { 2001: (NOV, 14), 2002: (NOV, 3), 2003: (OCT, 23), 2004: (NOV, 11), 2005: (NOV, 1), 2006: (OCT, 21), 2007: (NOV, 8), 2008: (OCT, 27), 2009: (OCT, 17), 2010: (NOV, 5), 2011: (OCT, 26), 2012: (NOV, 13), 2013: (NOV, 2), 2014: (OCT, 22), 2015: (NOV, 10), 2016: (OCT, 29), 2017: (OCT, 18), 2018: (NOV, 6), 2019: (OCT, 27), 2020: (NOV, 14), 2021: (NOV, 4), 2022: (NOV, 24), } if year in dates_obs: hol_date = date(year, *dates_obs[year]) self[hol_date] = "Deepavali" else: hol_date = self.cnls.s_diwali_date(year) self[hol_date] = "Deepavali* (*estimated; rarely on day after)" # Christmas Day self[date(year, DEC, 25)] = "Christmas Day" # Boxing day (up to and including 1968) if year <= 1968: self[date(year, DEC, 26)] = "Boxing Day" # Polling Day dates_obs = { 2001: (NOV, 3), 2006: (MAY, 6), 2011: (MAY, 7), 2015: (SEP, 11), 2020: (JUL, 10), } if year in dates_obs: self[date(year, *dates_obs[year])] = "Polling Day" # SG50 Public holiday # Announced on 14 March 2015 # https://www.mom.gov.sg/newsroom/press-releases/2015/sg50-public-holiday-on-7-august-2015 if year == 2015: self[date(2015, AUG, 7)] = "SG50 Public Holiday" # Check for holidays that fall on a Sunday and implement Section 4(2) # of the Holidays Act: "if any day specified in the Schedule falls on # a Sunday, the day next following not being itself a public holiday # is declared a public holiday in Singapore." for (hol_date, hol_name) in list(self.items()): if hol_date.year == year and hol_date.weekday() == SUN: self[hol_date] += " [Sunday]" in_lieu_date = hol_date + rd(days=+1) while in_lieu_date in self: in_lieu_date += rd(days=+1) self[in_lieu_date] = hol_name + " [In lieu]"
class Malaysia(HolidayBase): STATES = [ "JHR", "KDH", "KTN", "MLK", "NSN", "PHG", "PRK", "PLS", "PNG", "SBH", "SWK", "SGR", "TRG", "KUL", "LBN", "PJY", ] def __init__( self, years: Union[int, Iterable[int]] = None, expand: bool = True, observed: bool = True, prov: Optional[str] = None, state: Optional[str] = None, ) -> None: """ An subclass of :py:class:`HolidayBase` representing public holidays in Malaysia. If ``state`` is not supplied, only nationwide holidays are returned. The following ``state`` codes are used (ISO 3166-2 subdivision codes are not yet supported): - JHR: Johor - KDH: Kedah - KTN: Kelantan - MLK: Melaka - NSN: Negeri Sembilan - PHG: Pahang - PRK: Perak - PLS: Perlis - PNG: Pulau Pinang - SBH: Sabah - SWK: Sarawak - SGR: Selangor - TRG: Terengganu - KUL: FT Kuala Lumpur - LBN: FT Labuan - PJY: FT Putrajaya Limitations: - Prior to 2021: holidays are not accurate. - 2027 and later: Thaipusam dates are are estimated, and so denoted. Reference: `Wikipedia <https://en.wikipedia.org/wiki/Public_holidays_in_Malaysia>`__ Country created by: `Eden <https://github.com/jusce17>`__ Country maintained by: `Mike Borsetti <https://github.com/mborsetti>`__ See parameters and usage in :py:class:`HolidayBase`. """ self.country = "MY" self.cnls = ChineseLuniSolar() super().__init__(years, expand, observed, prov, state) def _populate(self, year): # New Year's Day if self.state not in ("JHR", "KDH", "KTN", "PLS", "TRG"): self[date(year, JAN, 1)] = "New Year's Day" # Birthday of the Prophet Muhammad (s.a.w.). # a.k.a. Hari Keputeraan Nabi Muhammad (Sabah Act) for hol_date in self.my_islamic_to_gre(year, 3, 12): self[ hol_date] = "Maulidur Rasul (Birthday of the Prophet Muhammad)" # Hari Kebangsaan or National Day. self[date(year, AUG, 31)] = "National Day" # Chinese New Year (one day in the States of Kelantan and Terengganu, # two days in the other States). hol_date = self.cnls.lunar_n_y_date(year) self[hol_date] = "Chinese New Year" # The second day of Chinese New Year is not a federal holiday in # Kelantan and Terengganu. However, it is gazetted as a state holiday # in both states, effectively making it a nationwide holiday. self[hol_date + rd(days=+1)] = "Chinese New Year Holiday" # Wesak Day. # Date of observance is announced yearly # https://en.wikipedia.org/wiki/Vesak#Dates_of_observance dates_obs = { 2001: (MAY, 7), 2002: (MAY, 27), 2003: (MAY, 15), 2004: (JUN, 2), 2005: (MAY, 23), 2006: (MAY, 12), 2007: (MAY, 31), 2008: (MAY, 19), 2009: (MAY, 9), 2010: (MAY, 28), 2011: (MAY, 17), 2012: (MAY, 5), 2013: (MAY, 24), 2014: (MAY, 13), 2015: (JUN, 1), 2016: (MAY, 20), 2017: (MAY, 10), 2018: (MAY, 29), 2019: (MAY, 19), 2020: (MAY, 7), 2021: (MAY, 26), 2022: (MAY, 15), } if year in dates_obs: hol_date = date(year, *dates_obs[year]) self[hol_date] = "Vesak Day" else: hol_date = self.cnls.vesak_may_date(year) self[hol_date] = "Vesak Day* (*estimated; ~10% chance +/- 1 day)" # Birthday of [His Majesty] the Yang di-Pertuan Agong. if year <= 2017: hol_date = rrule( MONTHLY, dtstart=date(year, JUN, 1), count=1, bysetpos=1, byweekday=SA, )[0] elif year == 2018: hol_date = date(2018, SEP, 9) else: hol_date = rrule( MONTHLY, dtstart=date(year, JUN, 1), count=1, bysetpos=1, byweekday=MO, )[0] self[hol_date] = "Birthday of SPB Yang di-Pertuan Agong" # Hari Raya Puasa (2 days). # aka Eid al-Fitr; # exact date of observance is announced yearly dates_obs = { 2001: [(DEC, 17)], 2002: [(DEC, 6)], 2003: [(NOV, 25)], 2004: [(NOV, 14)], 2005: [(NOV, 3)], 2006: [(OCT, 24)], 2007: [(OCT, 13)], 2008: [(OCT, 1)], 2009: [(SEP, 20)], 2010: [(SEP, 10)], 2011: [(AUG, 30)], 2012: [(AUG, 19)], 2013: [(AUG, 8)], 2014: [(JUL, 28)], 2015: [(JUL, 17)], 2016: [(JUL, 6)], 2017: [(JUN, 25)], 2018: [(JUN, 15)], 2019: [(JUN, 5)], 2020: [(MAY, 24)], 2021: [(MAY, 13)], 2022: [(MAY, 2)], } if year in dates_obs: for date_obs in dates_obs[year]: hol_date = date(year, *date_obs) self[hol_date] = "Hari Raya Puasa" self[hol_date + rd(days=+1)] = "Second day of Hari Raya Puasa" else: for date_obs in islamic_to_gre(year, 10, 1): hol_date = date_obs self[hol_date] = "Hari Raya Puasa* (*estimated)" self[hol_date + rd(days=+1)] = ("Second day of Hari Raya Puasa*" " (*estimated)") # Hari Raya Haji and Arafat Day. # Date of observance is announced yearly. dates_obs = { 2001: [(MAR, 6)], 2002: [(FEB, 23)], 2003: [(FEB, 12)], 2004: [(FEB, 1)], 2005: [(JAN, 21)], 2006: [(JAN, 10)], 2007: [(DEC, 20)], 2008: [(DEC, 8)], 2009: [(NOV, 27)], 2010: [(NOV, 17)], 2011: [(NOV, 6)], 2012: [(OCT, 26)], 2013: [(OCT, 15)], 2014: [(OCT, 5)], 2015: [(SEP, 24)], 2016: [(SEP, 12)], 2017: [(SEP, 1)], 2018: [(AUG, 22)], 2019: [(AUG, 11)], 2020: [(JUL, 31)], 2021: [(JUL, 20)], 2022: [(JUL, 9)], } if year in dates_obs: for date_obs in dates_obs[year]: hol_date = date(year, *date_obs) self[hol_date] = "Hari Raya Haji" if self.state == "TRG": # Arafat Day is one day before Eid al-Adha self[hol_date - rd(days=1)] = "Arafat Day" if self.state in ("KDH", "KTN", "PLS", "TRG"): # Second day self[hol_date + rd(days=1)] = "Hari Raya Haji Holiday" else: for date_obs in islamic_to_gre(year, 12, 10): hol_date = date_obs self[hol_date] = "Hari Raya Haji* (*estimated)" if self.state == "TRG": # Arafat Day is one day before Eid al-Adha self[hol_date - rd(days=1)] = "Arafat Day* (*estimated)" if self.state in ("KDH", "KTN", "PLS", "TRG"): # Second day self[hol_date + rd(days=1)] = "Hari Raya Haji Holiday* (*estimated)" # Deepavali. # aka Diwali; # date of observance is announced yearly if self.state != "SWK": dates_obs = { 2001: (NOV, 14), 2002: (NOV, 3), 2003: (OCT, 23), 2004: (NOV, 11), 2005: (NOV, 1), 2006: (OCT, 21), 2007: (NOV, 8), 2008: (OCT, 27), 2009: (OCT, 17), 2010: (NOV, 5), 2011: (OCT, 26), 2012: (NOV, 13), 2013: (NOV, 2), 2014: (OCT, 22), 2015: (NOV, 10), 2016: (OCT, 29), 2017: (OCT, 18), 2018: (NOV, 6), 2019: (OCT, 27), 2020: (NOV, 14), 2021: (NOV, 4), 2022: (NOV, 24), } if year in dates_obs: hol_date = date(year, *dates_obs[year]) self[hol_date] = "Deepavali" else: hol_date = self.cnls.s_diwali_date(year) self[hol_date] = "Deepavali* (*estimated; rarely on day after)" # Christmas day. self[date(year, DEC, 25)] = "Christmas Day" # Malaysia Day. self[date(year, SEP, 16)] = "Malaysia Day" # ---------------------------------------------------------# # Holidays from the Sarawak Ordinance (not included above) # # ---------------------------------------------------------# if self.state == "SWK": # Dayak Festival Day (the first day of June) and the following day. self[date(year, JUN, 1)] = "Gawai Dayak" self[date(year, JUN, 2)] = "Gawai Dayak (Second day)" # The first day of May—Worker’s Celebration Day. # Birthday of Tuan Yang Terutama Yang di-Pertua Negeri Sarawak (the # second Saturday of September). second_sat_oct = rrule( MONTHLY, dtstart=date(year, OCT, 1), count=1, bysetpos=2, byweekday=SA, )[0] self[second_sat_oct] = "Birthday of the Governor of Sarawak" # Sarawak Independence Day if year > 2016: self[date(year, JUL, 22)] = "Sarawak Day" # Check for holidays that fall on a Sunday and # implement Section 3 of Malaysian Holidays Act: # "if any day specified in the Schedule falls on # Sunday then the day following shall be a public # holiday and if such day is already a public holiday, # then the day following shall be a public holiday" for (hol_date, hol_name) in list(self.items()): if hol_date.year == year and hol_date.weekday() == SUN: self[hol_date] += " [Sunday]" in_lieu_date = hol_date + rd(days=+1) while in_lieu_date in self: in_lieu_date += rd(days=+1) self[in_lieu_date] = hol_name + " [In lieu]" # The last two days in May (Pesta Kaamatan). # (Sarawak Act) # Day following a Sunday is not a holiday if self.state in ("LBN", "SBH"): self[date(year, MAY, 30)] = "Pesta Kaamatan" self[date(year, MAY, 31)] = "Pesta Kaamatan (Second day)" # ------------------------------# # Other holidays (decrees etc.) # # ------------------------------# # Malaysia General Election Holiday. dates_obs = { # The years 1955 1959 1995 seems to have the elections # one weekday but I am not sure if they were marked as # holidays. 1999: (NOV, 29), 2018: (MAY, 9), } if year in dates_obs: self[date(year, *dates_obs[year])] = "Malaysia General Election Holiday" # Awal Muharram. for hol_date in self.my_islamic_to_gre(year, 1, 1): self[hol_date] = "Awal Muharram (Hijri New Year)" # Labour Day. self[date(year, MAY, 1)] = "Labour Day" # ---------------------------------# # State holidays (multiple states) # # ---------------------------------# # 1 January (or the following day if the 1 January should fall on a # weekly holiday in any State or in the Federal Territory). if self.state in ( "KUL", "LBN", "MLK", "NSN", "PHG", "PNG", "PRK", "PJY", "SBH", "SWK", "SGR", ): hol_date = date(year, JAN, 1) self[hol_date] = "New Year's Day" if hol_date == SUN: self[hol_date] += " [Sunday]" self[date(year, JAN, 2)] = "New Year's Day [In lieu]" # Isra and Mi'raj. if self.state in ("KDH", "NSN", "PLS", "TRG"): for hol_date in islamic_to_gre(year, 7, 27): self[hol_date] = "Isra and Mi'raj" # Beginning of Ramadan. if self.state in ("JHR", "KDH", "MLK"): for hol_date in islamic_to_gre(year, 9, 1): self[hol_date] = "Begining of Ramadan" # Nuzul Al-Quran Day. if self.state and self.state not in ( "JHR", "KDH", "MLK", "NSN", "SBH", "SWK", ): for hol_date in islamic_to_gre(year, 9, 17): self[hol_date] = "Nuzul Al-Quran Day" # Hari Raya Aidilfitri. # aka Eid al-Fitr; # date of observance is announced yearly dates_obs = { 2001: [(DEC, 16)], 2002: [(DEC, 6)], 2003: [(NOV, 25)], 2004: [(NOV, 14)], 2005: [(NOV, 3)], 2006: [(OCT, 24)], 2007: [(OCT, 13)], 2008: [(OCT, 1)], 2009: [(SEP, 20)], 2010: [(SEP, 10)], 2011: [(AUG, 30)], 2012: [(AUG, 19)], 2013: [(AUG, 8)], 2014: [(JUL, 28)], 2015: [(JUL, 17)], 2016: [(JUL, 6)], 2017: [(JUN, 25)], 2018: [(JUN, 15)], 2019: [(JUN, 5)], 2020: [(MAY, 24)], 2021: [(MAY, 13)], 2022: [(MAY, 2)], } if year in dates_obs: for date_obs in dates_obs[year]: hol_date = date(year, *date_obs) self[hol_date] = "Hari Raya Aidilfitri" hol_date += rd(days=+1) self[hol_date] = "Hari Raya Aidilfitri Holiday" else: for date_obs in islamic_to_gre(year, 10, 1): hol_date = date_obs self[hol_date] = "Hari Raya Aidilfitri* (*estimated)" hol_date += rd(days=+1) self[hol_date] = "Hari Raya Aidilfitri Holiday* (*estimated)" # Good Friday. if self.state in ("SBH", "SWK"): self[easter(year) + rd(weekday=FR(-1))] = "Good Friday" # Thaipusam. # An annual Hindu festival observed on the day of the first full moon # during the Tamil month of Thai if self.state in ("JHR", "KUL", "NSN", "PJY", "PNG", "PRK", "SGR"): dates_obs = { 2018: [(JAN, 31)], 2019: [(JAN, 21)], 2020: [(FEB, 8)], 2021: [(JAN, 28)], 2022: [(JAN, 18)], 2023: [(FEB, 4)], 2024: [(JAN, 25)], 2025: [(FEB, 11)], 2026: [(FEB, 1)], 2027: [(JAN, 22)], } if year in dates_obs: for date_obs in dates_obs[year]: hol_date = date(year, *date_obs) self[hol_date] = "Thaipusam" else: hol_date = self.cnls.thaipusam_date(year) self[hol_date] = "Thaipusam* (*estimated)" # Federal Territory Day. if self.state in ("KUL", "LBN", "PJY"): if year > 1973: self[date(year, FEB, 1)] = "Federal Territory Day" # State holidays (single state) # ----------------------------- if self.state == "JHR": if year > 2014: self[date(year, MAR, 23)] = "Birthday of the Sultan of Johor" for date_obs in islamic_to_gre(year, 2, 6): self[date_obs] = "Hari Hol of Sultan Iskandar of Johor" elif self.state == "KDH": third_sun_jun = rrule( MONTHLY, dtstart=date(year, JUN, 1), count=1, bysetpos=3, byweekday=SU, )[0] self[third_sun_jun] = "Birthday of The Sultan of Kedah" elif self.state == "KTN": self[date(year, NOV, 11)] = "Birthday of the Sultan of Kelantan" self[date(year, NOV, 12)] = "Birthday of the Sultan of Kelantan Holiday" elif self.state == "MLK": self[date( year, APR, 15)] = "Declaration of Malacca as a Historical City in Melaka" self[date(year, AUG, 24)] = "Birthday of the Governor of the State of Melaka" elif self.state == "NSN": self[date(year, JAN, 14)] = "Birthday of the Sultan of Negeri Sembilan" elif self.state == "PHG": self[date(year, MAY, 22)] = "Hari Hol of Pahang" self[date(year, JUL, 30)] = "Birthday of the Sultan of Pahang" elif self.state == "PNG": self[date(year, JUL, 7)] = "George Town Heritage Day" second_sat_jul = rrule( MONTHLY, dtstart=date(year, JUL, 1), count=1, bysetpos=2, byweekday=SA, )[0] self[second_sat_jul] = "Birthday of the Governor of Penang" elif self.state == "PRK": if year > 2016: first_fri_nov = rrule( MONTHLY, dtstart=date(year, NOV, 1), count=1, bysetpos=1, byweekday=FR, )[0] self[first_fri_nov] = "Birthday of the Sultan of Perak" else: # This Holiday used to be on 27th until 2017 # https://www.officeholidays.com/holidays/malaysia/birthday-of-the-sultan-of-perak # noqa: E501 self[date(year, NOV, 27)] = "Birthday of the Sultan of Perak" elif self.state == "PLS": self[date(year, JUL, 17)] = "Birthday of The Raja of Perlis" elif self.state == "SGR": self[date(year, DEC, 11)] = "Birthday of The Sultan of Selangor" elif self.state == "SBH": first_sat_oct = rrule( MONTHLY, dtstart=date(year, OCT, 1), count=1, bysetpos=1, byweekday=SA, )[0] self[first_sat_oct] = "Birthday of the Governor of Sabah" if year > 2018: self[date(year, DEC, 24)] = "Christmas Eve" elif self.state == "TRG": self[date( year, MAR, 4 )] = "Anniversary of the Installation of the Sultan of Terengganu" self[date(year, APR, 26)] = "Birthday of the Sultan of Terengganu" def my_islamic_to_gre(self, year: int, month: int, day: int): """ Malaysia seems to have a slightly different Hijri calendar. This function returns the adjusted date. Only knows years 2000 to 2030. :param year: The Gregorian year. :param Hmonth: The Hijri (Islamic) month. :param Hday: The Hijri (Islamic) day. :return: List of Gregorian dates within the year matching the hijri day month, adjusted for Malaysia. """ hol_dates = islamic_to_gre(year, month, day) if year in ( 2003, 2004, 2010, 2011, 2013, 2017, 2019, 2021, 2024, 2025, 2027, ): hol_dates = [ hol_date + timedelta(days=1) for hol_date in hol_dates ] return hol_dates
def __init__(self, **kwargs): HolidayBase.__init__(self, **kwargs) self.cnls = ChineseLuniSolar()