Go 製祝日ライブラリ shukujitsu の取得元を Google Calendar API から内閣府 CSV に変更しました
自作の日本の祝日判定 Go ライブラリ shukujitsu の祝日データ取得元を、Google Calendar API から内閣府公表の「国民の祝日」CSV(一次ソース)に変更しました。
除外リストの手動保守と API キー管理から解放され、依存パッケージも大幅に減ったので、その顛末を書きます。
shukujitsu とは
日付→祝日名のマップ(shukujitsu.yml)を go:embed で埋め込み、IsHoliday(t) / HolidayName(t) を提供するライブラリです。データは GitHub Actions の週次 cron で自動更新しています。
Google Calendar API の何が困っていたか
変更前は Google Calendar の日本の祝日カレンダー(ja.japanese#holiday@group.v.calendar.google.com)から取得していましたが、以下の問題がありました。
- 祝日でない行事が混入する。七夕・母の日・節分・クリスマスなどがカレンダーに含まれるため、除外リストを手で保守していた
1 | var excludedSummaries = map[string]bool{ |
GOOGLE_CALENDAR_API_KEYを GitHub Secrets で管理する必要があるgoogle.golang.org/api系の依存が重い- データ範囲が Google 側の応答に依存する
内閣府が公表している 国民の祝日 CSV は一次ソースそのものなので、行事の混入がなく除外リスト自体が不要になります。
実装
Shift_JIS のデコード
内閣府 CSV は Shift_JIS です。golang.org/x/text の transform.NewReader でストリームデコードしてから encoding/csv でパースします。
1 | // fetchHolidays : 内閣府 CSV (Shift_JIS) を取得し、ヘッダー行を除いたレコードを返す |
日付フォーマットの罠
CSV の日付は 2021/7/22 のようなゼロ埋めなしのスラッシュ区切りです。Go の time レイアウトは "2006/1/2" を使います("2006/01/02" だとパースに失敗します)。
1 | for _, row := range rows { |
CI から Secrets を削除
GitHub Actions からは API キーの env が消え、go run するだけになりました。
1 | - - name: auto update shukujitsu.yml by google calendar api |
依存も google.golang.org/api v0.97.0 + indirect 15個 → golang.org/x/text のみになり、go.sum が 675 行減りました。
変更に伴う挙動の違い(注意点)
- 祝日名の表記が変わりました。振替休日・国民の休日は政府 CSV の表記に合わせて「休日」に統一されます(従来は「海の日 振替休日」のような Google カレンダー由来の詳細名)。
HolidayNameの返却文字列に依存している場合は破壊的変更に近い点です - データ範囲が変わりました。過去方向は 1955年〜に大幅拡充、未来方向は政府が確定発表した年まで(従来 2030年 → 現時点で 2027年)になります
まとめ
- 祝日データの取得元を一次ソース(内閣府 CSV)に変更し、除外リストの保守・API キー管理・重い依存から解放されました
- Shift_JIS デコードは
japanese.ShiftJIS.NewDecoder()、日付パースはレイアウト"2006/1/2"がポイントです - 祝日名の表記とデータ範囲が変わる点には注意が必要です
以上です。ご利用いただけますと幸いです。
- リポジトリ: kenzo0107/shukujitsu
