Holiday counter~休みたい私による祝日未来予想図

## はじめに
はじめまして、物理工学専攻修士1年のあるみと申します。
早速ですが質問です。皆さんは祝日は好きですか？
<font color="Red">私は大好きです。</font> 
午前様しても良し。
昼まで寝まくって、睡眠負債を全力返納しても良し。
早起きして朝活に邁進してもよし。
そう休日とはフリーダム！！
でも毎日休日・祝日を望んでいるのかと言われてみると
ちょっと違う。
後半になってくるとダレてくる小学時代の夏休みや、
最初は勢いありながらも次第に飽きてくる食べ放題のように。

休日・祝日とはなかなかやって来ないからこそ思いが募り、
特別感のある存在となるものなのです。
休日・祝日のために平日を頑張る、まさにモチベーションのような存在である休日。
しかし祝日を抹消しにかかる存在が、そう。
<font color="Red">土曜日。</font> 
土曜日と重なった祝日は振り替えられず、
消される運命にあるのです。
例えば来年2024年のゴールデンウィークはみどりの日が
土曜日と重なったために、4連休となっています。
この辛い現実に対しては、X(Twitter)でも悲しみの声が散見されています。

https://x.com/The_kid_steak/status/1730927048896717003?s=20

完全週休2日に従う民にとっては相当の痛手！
そこで気になったのです。
祝日が一番生き残っている年はいつだろうかと。
そこで私はPythonのライブラリを用いて、
各年の祝日をカウントするプログラムを作成し計算してみました。
~~え、研究は週7でやるものって？~~


![calender_shock_man.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574056/6f394214-ba04-9e4c-dd8d-028bacb1374a.png)


## 　計算のルール説明

- ここで祝日は「国民の祝日に関する法律」で定められた国民の祝日をカウントします。
- 春分の日、秋分の日は太陽が「春分点」「秋分点」を通過する日と定められています。そのため地球の運行状態によって日付が変動します。国立天文台のホームページでは2050年までの春分の日、秋分の日の予測日が公開されているので、それに則りました。

https://www.nao.ac.jp/faq/a0301.html

- そこで計算する範囲は2024年から2050年までとします。
- 祝日の増減、日にちの移動は無いものとする。つまり2023年12月現在のルールが、2050年まで適用されるものと仮定して計算を行います。

## カウントの方法

- 平日と国民の祝日が重なった場合は1日とカウントします。
- 土曜日と国民の祝日が重なった場合は祝日のカウントはしません。
- 日曜日と国民の祝日が重なった場合は振替休日があるため1日とカウントします。
    - 会社や組織によっては年末休業・お盆休みもあるかと思いますが、~~「仕事納めが日曜日に重なった場合はどうするんだ」とか場合わけが面倒臭い~~計算が煩雑になりそうだったので割愛させていただきました、すみません。。。

## ソースコード

コードを書くにあたってこちらのライブラリを拝借しました、ありがとうございます。

https://qiita.com/flarebrow/items/c2e54db73130630d2c01

このライブラリを用いると、
- 特定の日付が祝日に当たるのかを判断すること
- 指定した年月日内にある祝日の日数のカウント
ができます。
例えばコードと出力はこんな感じです。

```python
# まずライブラリをインポートします
pip install flaretool
from flaretool.holiday import JapaneseHolidays
import datetime
# 日本の祝日のインスタンスを定義します
holidays = JapaneseHolidays()

# 以下、特定の期間内の祝日一覧を取得するコード。
# カウントの開始日を指定します
start_date = datetime.date(2030, 1, 1)
# カウントの終了日を指定します
end_date = datetime.date(2030, 12, 31)
# 指定した年月日内の祝日をリストに格納します
holiday_list = holidays.get_holidays_in_range(start_date, end_date)
for holiday in holiday_list:
    #リスト型で格納されます
    print(holiday)
```


>('元日', datetime.date(2030, 1, 1))
('成人の日', datetime.date(2030, 1, 14))
('建国記念の日', datetime.date(2030, 2, 11))
('天皇誕生日', datetime.date(2030, 2, 23))
('春分の日', datetime.date(2030, 3, 20))
('昭和の日', datetime.date(2030, 4, 29))
('憲法記念日', datetime.date(2030, 5, 3))
('みどりの日', datetime.date(2030, 5, 4))
('こどもの日', datetime.date(2030, 5, 5))
('こどもの日（振替休日）', datetime.date(2030, 5, 6))
('海の日', datetime.date(2030, 7, 15))
('山の日', datetime.date(2030, 8, 11))
('山の日（振替休日）', datetime.date(2030, 8, 12))
('敬老の日', datetime.date(2030, 9, 16))
('秋分の日', datetime.date(2030, 9, 23))
('スポーツの日', datetime.date(2030, 10, 14))
('文化の日', datetime.date(2030, 11, 3))
('文化の日（振替休日）', datetime.date(2030, 11, 4))
('勤労感謝の日', datetime.date(2030, 11, 23))

こんな感じの結果が返されます。
次はいよいよ祝日の日数をカウントするプログラムを作ります。
forループを回せるようちょっといじるだけです。
コードはこんな感じ。
```python
# まずライブラリをインポートします
pip install flaretool
from flaretool.holiday import JapaneseHolidays
import datetime
# 日本の祝日のインスタンスを定義します
holidays = JapaneseHolidays()

# 以下各年の祝日の日数をカウントするコード
# 対象となる年（始め）を入力
start_year = 2024
# 対象となる年（終わり）を入力
end_year = 2051

for i in range (start_year,end_year):
    # holiday_listに入力するために年を文字型に直します
    str_year = str(i)
    # holidaysの関数でstr_yearの年の祝日をリストで求めます。
    holiday_list = holidays.get_holidays(str_year)
    # 祝日数を格納する変数num_holidaysを初期化します
    num_holiday = 0
    for holiday in holiday_list:
        # holiday_list中の祝日の曜日を取得します。
        weekday = holiday[1].weekday()
        # 土曜日に当たる祝日を除外し、平日に当たる祝日のみをカウントします。
        # 日曜日に当たる祝日と振替休日がダブルカウントになっているので、日曜日に当たる祝日も除外します。
        if weekday < 5:
            num_holiday +=1
    # 各年の祝日の日数をプリントします。
    print(str_year+"の祝日数: "+str(num_holiday))
```

## 結果と考察
コードを実行し、祝日の日数を年ごとに求めました。
それをグラフ化したものがこちらです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574056/5f40d978-52fe-5c9d-3497-2007229668bc.png)

大体どの年も13~16日で祝日の日数が推移していることがわかります。
その中でも例外的に祝日が少ないのが2040年。
祝日の日数は最大の年で16日となっていますが、
2040年はなんと<font color="Red">11日</font>しかありません！

各祝日の曜日を出力するコードを使って、原因を探っていきましょう。

```python
# 特定の期間内の祝日と曜日一覧を取得するコード
x = 2040
# カウントの開始日を指定
start_date = datetime.date(x, 1, 1)
# カウントの終了日を指定
end_date = datetime.date(x, 12, 31)
# 祝日一覧をholiday_listのリストに格納します。
# tuple型になっており、1つ目の要素が祝日名、2つ目の要素が年月日となっています。
holiday_list = holidays.get_holidays_in_range(start_date, end_date)
for holiday in holiday_list:
    # 祝日の年月日をdtに格納します
    dt = holiday[1]
    # 祝日名と祝日の年月日、曜日を出力します。
    print(holiday,dt.strftime('%a'))
```
>('元日', datetime.date(2040, 1, 1)) Sun
('元日（振替休日）', datetime.date(2040, 1, 2)) Mon
('成人の日', datetime.date(2040, 1, 9)) Mon
('建国記念の日', datetime.date(2040, 2, 11)) Sat
('天皇誕生日', datetime.date(2040, 2, 23)) Thu
('春分の日', datetime.date(2040, 3, 20)) Tue
('昭和の日', datetime.date(2040, 4, 29)) Sun
('昭和の日（振替休日）', datetime.date(2040, 4, 30)) Mon
('憲法記念日', datetime.date(2040, 5, 3)) Thu
('みどりの日', datetime.date(2040, 5, 4)) Fri
('こどもの日', datetime.date(2040, 5, 5)) Sat
('海の日', datetime.date(2040, 7, 16)) Mon
('山の日', datetime.date(2040, 8, 11)) Sat
('敬老の日', datetime.date(2040, 9, 17)) Mon
('秋分の日', datetime.date(2040, 9, 22)) Sat
('スポーツの日', datetime.date(2040, 10, 8)) Mon
('文化の日', datetime.date(2040, 11, 3)) Sat
('勤労感謝の日', datetime.date(2040, 11, 23)) Fri

出力はこんなかんじ。
やはり5つもの祝日が土曜日に重なって消滅しているではありませんか！
2040年は祝日が少なく、心のオアシスが枯渇する年となる予感。
でも祝日が少ないことを予め知っておけば、無駄にがっかりすることもないでしょう。
この記事を読んだ方はラッキーですね(笑)。

## 終わりに
今回の記事ではPythonのライブラリを使ってコードを
軽くいじって遊んでみました。
祝日は年によって大きく変動し、
最多で16日、最少で11日あることが判明しました。
今回の計算では2023年の祝日制度が
そのまま継続することを仮定して計算しましたが、未来はまだわかりません。
祝日が増える可能性も十分にあります！
（特に6月に祝日が欲しいですよね……）
多くの祝日が土曜日にバッティングするXイヤー・2040年までに
祝日が増えることを祈って、今回の記事を締め括らせていただきます。
それではみなさん、良い年末年始をお過ごしください！

![party.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574056/71ab1d37-7ccd-9d65-7cc9-68adfbcaec4f.png)