[2019/12/8 追記]
ブログ内で「calender」と表記していますが、正式には「calendar」でした(^^; 変更して齟齬が出るのも嫌なので、記事内ではそのままにしています。
2019年は、天皇陛下の退位と皇太子様の即位、それに伴う元号の変更などカレンダーに影響を与えるイベントがたくさんあります。また来年は東京オリンピックが開催により、一部の祝日が移動されることが決まっています。祝日という観点からは非常にややこしいこの2年間ですが、今回はこの2年のイレギュラーな祝日にも対応するカレンダーを制作するプログラムを作ったので、それをまとめようと思います。
1. 環境設定
今回の実験環境は以下になります。
- Python: 3.7
- requests: 2.21.0
また使用するAPIは以下になります。
- カレンダーAPI
- URL: http://calendar-service.net/api.php
- 備考: データ形式や区間はサイトで設定できる
- 内閣府の祝祭日情報を提供するAPI
- URL: https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv
- 備考: 祝日の概要についてはこちらに記載
googleカレンダーのAPIを使っても良さそうでしたが、諸手続きが面倒くさそうだったので使うのをやめました。
2. コード
以下がカレンダーのコードになります。特に関数を作ったりせず、力技で処理しています。
#カレンダー情報の取得から整理 -> MySQlのcalenderに挿入
import requests
#カレンダーAPIから基本的なカレンダー情報の取得
api = "http://calendar-service.net/cal?start_year={year}&start_mon=1&end_year={year}&end_mon=12&year_style=normal&month_style=numeric&wday_style=ja&format=csv"
s = []
for i in [2019,2020]: #ここでカレンダーにしたい年を設定
res = requests.get(api.format(year=i))
m = res.text.split('\n')
s += m[1:-1]
calender = []
for i in s:
m = i.split(',')
date = '/'.join((m[0],m[1],m[2]))
calender.append([date,m[5],m[7]])
#内閣府からの祝日情報の取得し、2019年度のデータだけを抽出
import requests
holidays_api = requests.get('https://www8.cao.go.jp/chosei/shukujitsu/syukujitsu.csv')
holidays_api.encoding = 'Shift_JIS'
f = holidays_api.text.split('\r\n')
holidays = []
s = []
for i in f:
m = i.split(',')
try:
year = int(m[0].split('/')[0])
except Exception:
continue
if year == 2018:
continue
holidays.append(m)
# calenderへの祝日APIの反映(主に即位の礼のため)
for holiday in holidays:
for day in calender:
if day[0] == holiday[0]:
day[2] = holiday[1]
# スポーツの日への名称変更(2020年から)
for i in calender:
if i[2] == '体育の日':
if (i[0].split('/')[0]) != '2019':
i[2] = 'スポーツの日'
# 天皇誕生日の変更
for i in calender:
if i[0].split('/')[1] == '12' and i[0].split('/')[2] == '23':
i[2] = ''
# 東京オリンピックによる祝日の改正への影響
for i in calender:
if i[0] == '2019/12/23':
i[2] = ''
elif i[0] == '2020/7/20':
i[2] = ''
elif i[0] == '2020/7/23':
i[2] = '海の日'
elif i[0] == '2020/7/24':
i[2] = 'スポーツの日'
elif i[0] == '2020/8/10':
i[2] = '山の日'
elif i[0] == '2020/8/11':
i[2] = ''
elif i[0] == '2020/10/12':
i[2] = ''
continue
calender
戻り値
[['2019/1/1', '火', '元日'], ['2019/1/2', '水', ''], ['2019/1/3', '木', ''], (省略) ['2019/4/20', '土', ''], ['2019/4/21', '日', ''], ['2019/4/22', '月', ''], ['2019/4/23', '火', ''], ['2019/4/24', '水', ''], ['2019/4/25', '木', ''], ['2019/4/26', '金', ''], ['2019/4/27', '土', ''], ['2019/4/28', '日', ''], ['2019/4/29', '月', '昭和の日'], ['2019/4/30', '火', '休日'], ['2019/5/1', '水', '休日(祝日扱い)'], ['2019/5/2', '木', '休日'], ['2019/5/3', '金', '憲法記念日'], ['2019/5/4', '土', 'みどりの日'], ['2019/5/5', '日', 'こどもの日'], ['2019/5/6', '月', '休日'], ['2019/5/7', '火', ''], ['2019/5/8', '水', ''], ['2019/5/9', '木', ''], ['2019/5/10', '金', ''], (省略) ['2019/10/10', '木', ''], ['2019/10/11', '金', ''], ['2019/10/12', '土', ''], ['2019/10/13', '日', ''], ['2019/10/14', '月', '体育の日(スポーツの日)'], ['2019/10/15', '火', ''], ['2019/10/16', '水', ''], ['2019/10/17', '木', ''], ['2019/10/18', '金', ''], ['2019/10/19', '土', ''], ['2019/10/20', '日', ''], ['2019/10/21', '月', ''], ['2019/10/22', '火', '休日(祝日扱い)'], ['2019/10/23', '水', ''], ['2019/10/24', '木', ''], (省略) ['2019/12/19', '木', ''], ['2019/12/20', '金', ''], ['2019/12/21', '土', ''], ['2019/12/22', '日', ''], ['2019/12/23', '月', ''], ['2019/12/24', '火', ''], ['2019/12/25', '水', ''], ['2019/12/26', '木', ''], (省略) ['2020/7/19', '日', ''], ['2020/7/20', '月', ''], ['2020/7/21', '火', ''], ['2020/7/22', '水', ''], ['2020/7/23', '木', '海の日'], ['2020/7/24', '金', 'スポーツの日'], ['2020/7/25', '土', ''], ['2020/7/26', '日', ''], ['2020/7/27', '月', ''], ['2020/7/28', '火', ''], ['2020/7/29', '水', ''], ['2020/7/30', '木', ''], ['2020/7/31', '金', ''], ['2020/8/1', '土', ''], ['2020/8/2', '日', ''], ['2020/8/3', '月', ''], ['2020/8/4', '火', ''], ['2020/8/5', '水', ''], ['2020/8/6', '木', ''], ['2020/8/7', '金', ''], ['2020/8/8', '土', ''], ['2020/8/9', '日', ''], ['2020/8/10', '月', '山の日'], ['2020/8/11', '火', ''], ['2020/8/12', '水', ''], ['2020/8/13', '木', ''], (省略)
現時点で法令が変更された祝日が反映されたカレンダーが完成しました。
3. まとめ
以上が、直近2年間のややこしい祝祭日を反映させたカレンダーを作るプログラムです。カレンダーAPIから取得するデータの加工の仕方次第でより柔軟にカレンダーを作成することができます。もっと簡単にできそうな気がしたのですが、祝祭日の状況が変わりやすく、思った以上に手間取ったというのが本音です。日本では有給休暇の取得率の低さが問題になっていますが、個人的には祝日を半分程度に減らした上で、有給休暇の全日取得義務化、それができない場合は企業による1.5倍での未消化有給休暇日の買取義務化、のような施策を実施した方が良いと考えています(但し有休付与日でちょろまかす企業が出てくると思うので、そこも「雇用契約締結より1年を過ぎた職員には最低12日以上の有休付与義務を課す」といったルールを合わせて定める必要があるとは思います。)なお、上記のような考えを持ってはいますが、左派や労組よりというわけではなく、解雇規制の緩和、ホワイトカラーエグセプションや裁量労働制の拡大には賛成です。最後はかなり記事の主題からそれてしまいましたが、今回のカレンダーの作成プログラムがどなたかのお役に立てれば幸いです。