Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
171 changes: 171 additions & 0 deletions holidays.py
Original file line number Diff line number Diff line change
Expand Up @@ -2224,3 +2224,174 @@ def _populate(self, year):

class NO(Norway):
pass


class Japan(HolidayBase):
# https://en.wikipedia.org/wiki/Public_holidays_in_Japan

def __init__(self, **kwargs):
self.country = 'JP'
HolidayBase.__init__(self, **kwargs)

def _populate(self, year):
if year < 1949 or year > 2050:
raise NotImplementedError

# New Year's Day
self[date(year, 1, 1)] = "元日"

# Coming of Age Day
if year <= 1999:
self[date(year, 1, 15)] = "成人の日"
else:
self[date(year, 1, 1) + rd(weekday=MO(+2))] = "成人の日"

# Foundation Day
self[date(year, 2, 11)] = "建国記念の日"

# Vernal Equinox Day
self[self._vernal_equinox_day(year)] = "春分の日"

# The former Emperor's Birthday, Greenery Day or Showa Day
if year <= 1988:
self[date(year, 4, 29)] = "天皇誕生日"
elif year <= 2006:
self[date(year, 4, 29)] = "みどりの日"
else:
self[date(year, 4, 29)] = "昭和の日"

# Constitution Memorial Day
self[date(year, 5, 3)] = "憲法記念日"

# Greenery Day
if year >= 2007:
self[date(year, 5, 4)] = "みどりの日"

# Children's Day
self[date(year, 5, 5)] = "こどもの日"

# Marine Day
if year >= 1996 and year <= 2002:
self[date(year, 7, 20)] = "海の日"
elif year >= 2003:
self[date(year, 7, 1) + rd(weekday=MO(+3))] = "海の日"

# Mountain Day
if year >= 2016:
self[date(year, 8, 11)] = "山の日"

# Respect for the Aged Day
if year >= 1966 and year <= 2002:
self[date(year, 9, 15)] = "敬老の日"
elif year >= 2003:
self[date(year, 9, 1) + rd(weekday=MO(+3))] = "敬老の日"

# Autumnal Equinox Day
self[self._autumnal_equinox_day(year)] = "秋分の日"

# Health and Sports Day
if year >= 1966 and year <= 1999:
self[date(year, 10, 10)] = "体育の日"
elif year >= 2000:
self[date(year, 10, 1) + rd(weekday=MO(+2))] = "体育の日"

# Culture Day
self[date(year, 11, 3)] = "文化の日"

# Labour Thanksgiving Day
self[date(year, 11, 23)] = "勤労感謝の日"

# The Emperor's Birthday
if year >= 1989:
self[date(year, 12, 23)] = "天皇誕生日"

# A weekday between national holidays becomes a holiday too (国民の休日)
self._add_national_holidays(year)

# Substitute holidays
self._add_substitute_holidays(year)

def _vernal_equinox_day(self, year):
day = 20
if year % 4 == 0:
if year <= 1956:
day = 21
elif year >= 2092:
day = 19
elif year % 4 == 1:
if year <= 1989:
day = 21
elif year % 4 == 2:
if year <= 2022:
day = 21
elif year % 4 == 3:
if year <= 2055:
day = 21
return date(year, 3, day)

def _autumnal_equinox_day(self, year):
day = 22
if year % 4 == 0:
if year <= 2008:
day = 23
elif year % 4 == 1:
if year <= 2041:
day = 23
elif year % 4 == 2:
if year <= 2074:
day = 23
elif year % 4 == 3:
if year <= 1979:
day = 24
else:
day = 23
return date(year, 9, day)

def _add_national_holidays(self, year):
if year in (1993, 1999, 2004, 1988, 1994, 2005, 1989, 1995, 2000, 2006,
1990, 2001, 1991, 1996, 2002):
self[date(year, 5, 4)] = "国民の休日"

if year in (2032, 2049, 2060, 2077, 2088, 2094):
self[date(year, 9, 21)] = "国民の休日"

if year in (2009, 2015, 2026, 2037, 2043, 2054, 2065, 2071, 2099):
self[date(year, 9, 22)] = "国民の休日"

def _add_substitute_holidays(self, year):
table = (
(1, 2, (1978, 1984, 1989, 1995, 2006, 2012, 2017, 2023, 2034, 2040,
2045)),
(1, 16, (1978, 1984, 1989, 1995)),
(2, 12, (1979, 1990, 1996, 2001, 2007, 2018, 2024, 2029, 2035,
2046)),
(3, 21, (1988, 2005, 2016, 2033, 2044, 2050)),
(3, 22, (1982, 1999, 2010, 2027)),
(4, 30, (1973, 1979, 1984, 1990, 2001, 2007, 2012, 2018, 2029,
2035, 2040, 2046)),
(5, 4, (1981, 1987, 1992, 1998)),
(5, 6, (1985, 1991, 1996, 2002, 2013, 2019, 2024, 2030, 2041, 2047,
2008, 2014, 2025, 2031, 2036, 2042, 2009, 2015, 2020, 2026,
2037, 2043, 2048)),
(7, 21, (1997,)),
(8, 12, (2019, 2024, 2030, 2041, 2047)),
(9, 16, (1974, 1985, 1991, 1996, 2002)),
(9, 23, (2024,)),
(9, 24, (1973, 1984, 1990, 2001, 2007, 2018, 2029, 2035, 2046)),
(10, 11, (1976, 1982, 1993, 1999)),
(11, 4, (1974, 1985, 1991, 1996, 2002, 2013, 2019, 2024, 2030,
2041, 2047)),
(11, 24, (1975, 1980, 1986, 1997, 2003, 2008, 2014, 2025, 2031,
2036, 2042)),
(12, 24, (1990, 2001, 2007, 2012, 2018)),
)
for holiday in table:
month = holiday[0]
day = holiday[1]
years = holiday[2]
if year in years:
self[date(year, month, day)] = "振替休日"


class JP(Japan):
pass
119 changes: 119 additions & 0 deletions tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -3000,5 +3000,124 @@ def test_not_holiday(self):
self.assertFalse('2016-12-28' in self.holidays_with_sundays)


class TestJapan(unittest.TestCase):
def setUp(self):
self.holidays = holidays.Japan(observed=False)

def test_new_years_day(self):
self.assertTrue(date(1949, 1, 1) in self.holidays)
self.assertTrue(date(2017, 1, 1) in self.holidays)
self.assertTrue(date(2050, 1, 1) in self.holidays)

def test_coming_of_age(self):
self.assertTrue(date(1999, 1, 15)in self.holidays)
self.assertTrue(date(2000, 1, 10)in self.holidays)
self.assertTrue(date(2017, 1, 9)in self.holidays)
self.assertTrue(date(2030, 1, 14)in self.holidays)
self.assertTrue(date(2050, 1, 10)in self.holidays)

self.assertFalse(date(2000, 1, 15)in self.holidays)
self.assertFalse(date(2017, 1, 15)in self.holidays)
self.assertFalse(date(2030, 1, 15)in self.holidays)

def test_foundation_day(self):
self.assertTrue(date(1949, 2, 11) in self.holidays)
self.assertTrue(date(2017, 2, 11) in self.holidays)
self.assertTrue(date(2050, 2, 11) in self.holidays)

def test_vernal_equinox_day(self):
self.assertTrue(date(1960, 3, 20) in self.holidays)
self.assertTrue(date(1970, 3, 21) in self.holidays)
self.assertTrue(date(1980, 3, 20) in self.holidays)
self.assertTrue(date(1990, 3, 21) in self.holidays)
self.assertTrue(date(2000, 3, 20) in self.holidays)
self.assertTrue(date(2010, 3, 21) in self.holidays)
self.assertTrue(date(2017, 3, 20) in self.holidays)
self.assertTrue(date(2020, 3, 20) in self.holidays)
self.assertTrue(date(2030, 3, 20) in self.holidays)
self.assertTrue(date(2040, 3, 20) in self.holidays)

def test_showa_day(self):
self.assertTrue(date(1950, 4, 29) in self.holidays)
self.assertTrue(date(1990, 4, 29) in self.holidays)
self.assertTrue(date(2010, 4, 29) in self.holidays)

def test_constitution_memorial_day(self):
self.assertTrue(date(1950, 5, 3) in self.holidays)
self.assertTrue(date(2000, 5, 3) in self.holidays)
self.assertTrue(date(2050, 5, 3) in self.holidays)

def test_greenery_day(self):
self.assertFalse(date(1950, 5, 4) in self.holidays)
self.assertTrue(date(2007, 5, 4) in self.holidays)
self.assertTrue(date(2050, 5, 4) in self.holidays)

def test_childrens_day(self):
self.assertTrue(date(1950, 5, 5) in self.holidays)
self.assertTrue(date(2000, 5, 5) in self.holidays)
self.assertTrue(date(2050, 5, 5) in self.holidays)

def test_marine_day(self):
self.assertFalse(date(1950, 7, 20) in self.holidays)
self.assertTrue(date(2000, 7, 20) in self.holidays)
self.assertTrue(date(2003, 7, 21) in self.holidays)
self.assertTrue(date(2017, 7, 17) in self.holidays)
self.assertTrue(date(2050, 7, 18) in self.holidays)

def test_mountain_day(self):
self.assertFalse(date(1950, 8, 11) in self.holidays)
self.assertFalse(date(2015, 8, 11) in self.holidays)
self.assertTrue(date(2016, 8, 11) in self.holidays)
self.assertTrue(date(2017, 8, 11) in self.holidays)
self.assertTrue(date(2050, 8, 11) in self.holidays)

def test_respect_for_the_aged_day(self):
self.assertFalse(date(1965, 9, 15) in self.holidays)
self.assertTrue(date(1966, 9, 15) in self.holidays)
self.assertTrue(date(2002, 9, 15) in self.holidays)
self.assertTrue(date(2003, 9, 15) in self.holidays)
self.assertFalse(date(2004, 9, 15) in self.holidays)
self.assertTrue(date(2004, 9, 20) in self.holidays)
self.assertTrue(date(2017, 9, 18) in self.holidays)
self.assertTrue(date(2050, 9, 19) in self.holidays)

def test_autumnal_equinox_day(self):
self.assertTrue(date(2000, 9, 23) in self.holidays)
self.assertTrue(date(2010, 9, 23) in self.holidays)
self.assertTrue(date(2017, 9, 23) in self.holidays)
self.assertTrue(date(2020, 9, 22) in self.holidays)
self.assertTrue(date(2030, 9, 23) in self.holidays)

def test_health_and_sports_day(self):
self.assertFalse(date(1965, 10, 10) in self.holidays)
self.assertTrue(date(1966, 10, 10) in self.holidays)
self.assertTrue(date(1999, 10, 10) in self.holidays)
self.assertFalse(date(2000, 10, 10) in self.holidays)
self.assertTrue(date(2000, 10, 9) in self.holidays)
self.assertTrue(date(2017, 10, 9) in self.holidays)
self.assertTrue(date(2050, 10, 10) in self.holidays)

def test_culture_day(self):
self.assertTrue(date(1950, 11, 3) in self.holidays)
self.assertTrue(date(2000, 11, 3) in self.holidays)
self.assertTrue(date(2050, 11, 3) in self.holidays)

def test_labour_thanks_giving_day(self):
self.assertTrue(date(1950, 11, 23) in self.holidays)
self.assertTrue(date(2000, 11, 23) in self.holidays)
self.assertTrue(date(2050, 11, 23) in self.holidays)

def test_emperors_birthday(self):
self.assertTrue(date(1989, 12, 23) in self.holidays)
self.assertTrue(date(2017, 12, 23) in self.holidays)
self.assertTrue(date(2050, 12, 23) in self.holidays)

def test_invalid_years(self):
self.assertRaises(NotImplementedError,
lambda: date(1948, 1, 1) in self.holidays)
self.assertRaises(NotImplementedError,
lambda: date(2051, 1, 1) in self.holidays)


if __name__ == "__main__":
unittest.main()