先说明。 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 # 没顺延的行也带规则

缩到一个客户,规则照样跟着。
