【Python】日本の祝日リスト生成【2022年以降対応】

  • 2021年12月12日
  • 2022年8月4日
  • Python
  • 291View
  • 1件

はじめに

Python のプログラムレシピ紹介です。
日本の祝日をリストアップします。

2022年時点の制度に基づいた祝日を生成します。
2020~2021 年のオリンピック休日には対応していません。

日本の祝日リスト生成

サンプルコードです。

休日の一覧は、Wikipedia を参考にしました。

Wikipedia 国民の祝日
Wikipedia Public holidays in Japan

import datetime


def nth_monday(y, m, n):
    """N番目の月曜日"""
    base_date = datetime.date(y, m, 1)
    offset = 7 * (n - 1) + (7 - base_date.weekday()) % 7
    return base_date + datetime.timedelta(days=offset)


def substitute_holidays(holidays):
    """振替休日"""
    dates = []
    for date in holidays:
        if date.weekday() != 6:
            continue
        offset = 1
        while True:
            test_date = date + datetime.timedelta(days=offset)
            if test_date not in holidays:
                dates.append(test_date)
                break
            offset += 1
    return dates


def citizens_holidays(holidays):
    """国民の祝日"""
    dates = []
    for curr, next in zip(holidays, holidays[1:]):
        if (next - curr).days == 2:
            dates.append(curr + datetime.timedelta(days=1))
    return dates


def japanese_holidays(y):
    """日本の祝日リスト"""
    holidays = []
    # 元日 (New Year's Day)
    holidays.append(datetime.date(y, 1, 1))
    # 成人の日 (Coming of Age Day)
    holidays.append(nth_monday(y, 1, 2))
    # 建国記念の日 (National Foundation Day)
    holidays.append(datetime.date(y, 2, 11))
    # 天皇誕生日 (The Emperor's Birthday)
    holidays.append(datetime.date(y, 2, 23))
    # 春分の日 (Vernal Equinox Day)
    holidays.append(
        datetime.date(y, 3, int(20.8431 + 0.242194 * (y - 1980)) - int((y - 1980) / 4))
    )
    # 昭和の日 (Showa Day)
    holidays.append(datetime.date(y, 4, 29))
    # 憲法記念日 (Constitution Memorial Day)
    holidays.append(datetime.date(y, 5, 3))
    # みどりの日 (Greenery Day)
    holidays.append(datetime.date(y, 5, 4))
    # こどもの日 (Children's Day)
    holidays.append(datetime.date(y, 5, 5))
    # 海の日 (Marine Day)
    holidays.append(nth_monday(y, 7, 3))
    # 山の日 (Mountain Day)
    holidays.append(datetime.date(y, 8, 11))
    # 敬老の日 (Respect for the Aged Day)
    holidays.append(nth_monday(y, 9, 3))
    # 秋分の日 (Autumnal_Equinox Day)
    holidays.append(
        datetime.date(y, 9, int(23.2488 + 0.242194 * (y - 1980)) - int((y - 1980) / 4))
    )
    # スポーツの日 (Sports Day)
    holidays.append(nth_monday(y, 10, 2))
    # 文化の日 (Culture Day)
    holidays.append(datetime.date(y, 11, 3))
    # 勤労感謝の日 (Labour Thanksgiving Day)
    holidays.append(datetime.date(y, 11, 23))
    all_holidays = (
        holidays + substitute_holidays(holidays) + citizens_holidays(holidays)
    )
    all_holidays.sort()
    return all_holidays


if __name__ == "__main__":
    import sys
    y = int(sys.argv[1])
    for holiday in japanese_holidays(y):
        print(holiday.strftime("%Y-%m-%d %a"))

以下は出力例です。
2022年は、振替休日も国民の休日もありませんでした。

❯ python3 japanese_calendar.py 2022
2022-01-01 Sat
2022-01-10 Mon
2022-02-11 Fri
2022-02-23 Wed
2022-03-21 Mon
2022-04-29 Fri
2022-05-03 Tue
2022-05-04 Wed
2022-05-05 Thu
2022-07-18 Mon
2022-08-11 Thu
2022-09-19 Mon
2022-09-23 Fri
2022-10-10 Mon
2022-11-03 Thu
2022-11-23 Wed

以下は2026年の出力例です。
2026-05-06 が振替休日、2026-09-22 が国民の休日です。

❯ python3 japanese_calendar.py 2026
2026-01-01 Thu
2026-01-12 Mon
2026-02-11 Wed
2026-02-23 Mon
2026-03-20 Fri
2026-04-29 Wed
2026-05-03 Sun
2026-05-04 Mon
2026-05-05 Tue
2026-05-06 Wed
2026-07-20 Mon
2026-08-11 Tue
2026-09-21 Mon
2026-09-22 Tue
2026-09-23 Wed
2026-10-12 Mon
2026-11-03 Tue
2026-11-23 Mon