何が起きていたか
請求日・締め日・支払サイトから支払日を出すツールで、2007〜2019年の祝日が、内閣府の「国民の祝日」の一覧と合っていませんでした。支払日を営業日に寄せるとき、休日を営業日として扱うことがありました。
- 2019年4月10日・月末締め・当月末払い・次の営業日へ寄せる: 支払日の 4月30日は、即位に伴う10連休の中の休日です。次の営業日は 5月7日 が正解です。ツールは 4月30日を営業日とみなし、4月30日 と表示していました
- 前の営業日へ寄せる場合も、正解の 4月26日ではなく 4月30日でした
どのくらいの入力で起きていたか
祝日の数: 内閣府の一覧(syukujitsu.csv)では、2007〜2019年の休日(振替休日・国民の休日を含む)は229日です。直す前の祝日の計算と比べると、次のずれがありました。
| ずれ | 日数 | 内訳 |
|---|---|---|
| 休日なのに、休日にしていない | 19日 | 天皇誕生日(12月23日)2007〜2018年の12日、その振替休日(12月24日)3日、2019年の即位に伴う休日4日(4月30日・5月1日・5月2日・10月22日) |
| 休日ではないのに、休日にしている | 10日 | 山の日(8月11日)2007〜2015年の9日、その振替休日(2013年8月12日)1日 |
2020年1月1日〜2027年11月23日(一覧の最終日)の143日は、直す前から一致していました。
支払日への影響: 請求日 2007年1月1日〜2019年12月31日の毎日(4,748日)× 締め日6種類 × 支払サイト4種類 × 寄せ方2種類(前の営業日・次の営業日)の 227,904通り で、直す前の計算と、内閣府の一覧で営業日を判定した場合を比べました。
| 寄せ方 | 支払日が違う件数 |
|---|---|
| 前の営業日へ | 113,952通り中663通り |
| 次の営業日へ | 113,952通り中660通り |
営業日に寄せない設定では、祝日を使わないので結果は変わりません。
どうやって見つかったか
CODE Polyglot の仕様 締め日・支払日の計算 を作るとき、休日の定義を内閣府の一覧と突き合わせました(2026-10-15)。仕様が扱う範囲は請求日 2020〜2030年で、この範囲の休日は一覧と一致しています。元のツールは2007年以降の祝日を計算していたので、一覧と2007年から比べたところ、2007〜2019年に上のずれが見つかりました。
正解表のケースは2020〜2030年の範囲なので、このずれは正解表には現れません。
原因
- ツールの祝日の計算が、古い規則のままでした。シルギアの修正コミットの記録では「祝日(baseHolidays)が古いコピーのままで、2007〜2019年に取りこぼしがあった」とされています
- 古い規則は、天皇誕生日を2020年以降の2月23日だけにしていて、2018年までの12月23日がありませんでした。2016年に始まった山の日を、それより前の年にも付けていました。2019年だけの即位に伴う休日もありませんでした
どう直したか
祝日の規則を3か所直しました。あわせて、計算の部分を calc.js に分けました。4月30日と5月2日は、前後が祝日になるので、もともとある「国民の休日」の処理で休日になります。
if (year >= 2020) add(2, 23); + else if (year <= 2018) add(12, 23); + if (year === 2019) { + add(5, 1); + add(10, 22); + } - add(8, 11); + if (year >= 2016) add(8, 11); // 山の日は2016年施行
確かめたこと
- 本番が配信している
calc.jsがコミット e5ba1ed1 と同じ内容であることを確認(2026-10-15) - 祝日は、2007年1月1日〜2027年11月23日の内閣府の一覧372日と、差が0日
- 請求日 2020〜2030年の5,016通りで、支払日が仕様の正解とすべて一致(日本時間とロサンゼルス時間の両方)
- シルギア側の記録では、2020〜2030年の全289,296通りで直す前と結果が同じ(2020年以降は変わっていない)ことを確認。回帰テスト(内閣府の一覧との一致、上の 2019年4月10日の例など)を追加