現場

日付の横に根拠が付いてくる — 締切ボードが保存しないもの

2026-06に税務の締切ボードの話を載せた。あの記事には日付がどこから来たのかがなかった。今回は自分で作った — このボードは締切日をひとつも保存しない。規則だけを持って毎回計算し、週末で後ろにずれた日はずれたと言う。

著者: makemind · 2026年8月17日

先に明かしておく。 2026年6月にこの雑誌はある会計事務所の締切ボードの話を載せた。この現場は特定の事務所ではない。 実際にそう回っている形をそのまま構成し、どこかは明かさない。以下はその形どおりに自分で作ったものであり、取引先と締切項目は作り物だ。

このドメインの難しさは算数ではない。規則と日付は別物なのに、事務所はいつも規則の側を失うということだ。

表計算のセルに 2026-04-27 と書かれているとしよう。それを読む人は、それが法定期限なのか、週末でずれた日なのか、去年のものをコピーして生まれた誤字なのか、知る術がない。

だからこのボードは締切日をひとつも保存しない。

保存するのは規則だ

/// A filing obligation, as a rule rather than a date.
class Duty {
  const Duty(this.client, this.name, this.dayOfMonth, this.monthOf, this.note);

  /// Statutory day of the month.
  final int dayOfMonth;

  /// Which month it lands in, relative to the period being filed.
  final int monthOf;
}

日付がない。何月何日という規則だけがある。画面に出る日付は毎回その規則から計算される。

そして検証がそれを確認する。画面に出た締切日がソースに文字列として存在すれば失敗させる。

for D in $(grep -o "20[0-9][0-9]-[0-9][0-9]-[0-9][0-9] D-\?[0-9]*" captures/run.log | awk '{print $1}' | sort -u); do
  if grep -RIn --exclude-dir=captures -F "$D" deadline_server/bin deadlines.mbd bundle_host/lib; then
    echo "   due date $D is a literal in the sources — it must be computed"
    exit 1
  fi
done

この検査が実際に何かを捕まえた。 最初に回したとき失敗し、原因は私がドキュメントコメントに例として書いておいた 2026-04-27 だった。誤検知だ — コメントであって保存された日付ではないからだ。

ところが直しながら本物がひとつ一緒に出てきた。状態応答に 'today': '2026-04-20' と文字列が埋め込まれていて、その値はコード上方の _today一致しなければならない二か所だった。

// Derived, not typed twice. Two places that must agree eventually
// disagree.
'today': _fmt(_today),

検査が捕まえたのはコメントだったが、それを見に行ったついでに本物を直した。検査が誤検知を出すことと役に立たないことは違う。

週末でずれたならずれたと言う

このドメインの代表的な罠だ。誰もが知っている規則なのに、表計算はいつも忘れる。

/// Shift a statutory date off a weekend, and say that you did.
///
/// This is the rule everyone knows and every spreadsheet forgets. Returning
/// the shift as text rather than silently moving the date is the whole point:
/// "25th, moved to Monday" is checkable, "27th" is not.

実行ログだ。

2026-03-31 D-20  Dodam   Corporate tax        [day 31 of month 3]
2026-04-10 D-10  Hanbit  Withholding — March  [day 10 of month 4]
2026-04-10 D-10  Seum    Withholding — March  [day 10 of month 4]
2026-04-27 D7    Hanbit  VAT — Q1   [day 25 of month 4 · statutory 25th fell on Saturday]
2026-04-27 D7    Dodam   VAT — Q1   [day 25 of month 4 · statutory 25th fell on Saturday]
2026-04-30 D10   Seum    Local income tax     [day 30 of month 4]

04-25が実際に土曜日だったので04-27にずれ、その事由が角括弧の中に付いている。 ずれていない行にも規則が付いていることも見てほしい — ずれたものだけ説明して残りを日付だけにすれば、規則のある行とない行が画面で区別できなくなる。

検証が両方を見る。

grep -q "statutory 25th fell on Saturday" captures/run.log || exit 1
grep -q "\[day 10 of month 4\]" captures/run.log || exit 1   # ずれていない行にも規則が
期限ボード · 2026-04-20 — 延滞 3・一週間以内 2。行ごとにその日付を作った規則が付き、週末でずれた二件はそのことまで書いてある
期限ボード · 2026-04-20 — 延滞 3・一週間以内 2。行ごとにその日付を作った規則が付き、週末でずれた二件はそのことまで書いてある

取引先ひとつに絞っても規則はそのまま付いてくる。

一社だけ — 規則はそのまま、行が減っただけ
一社だけ — 規則はそのまま、行が減っただけ

このコンテンツは開発者以上が必要です

サインインしてプランをアップグレードすると続きを読めます。

プランを見る
Twitter