プログラムは難しい
プログラミングに不自由を感じることはなくなったと思っていたが、やはり難しいものだ。
プログラムで日付を扱うことが非常に多いことは論を待たない。したがって、標準ライブラリは日付を扱うための処理を提供することが普通である。.NETにおいては、たとえば DateTime.Parse メソッドなどがある。
しかしながら、そんなありふれた処理でさえ、バグが埋め込んでしまう。
"2011/9/10"
この文字列を普通に解析すると、3999年9月10日となってしまう”正常な”環境が存在する。
その環境とは、システムの暦を変更した環境である。Windowsの日時形式を「和暦」にしていると yyyy/MM/dd のyyyyは和暦の年だと解釈されるようになる。そのため、2011/1/1は平成2011年だと解釈され、平成2011年は西暦3999年ということになる。
これは、運に恵まれれば、障害として顕在化しないこともある。実際、和暦の環境でも次のコードは期待通りに動く。
var time = DateTime.Parse(“2011/1/1”);
Assert( time.ToString(“yyyy”) == 2011 );
内部では西暦3999年である値を処理していながら、入出力が和暦であることを無視しているために、たまたま数値が一致する。もちろん、閏年の影響などで、日付演算の結果は狂うだろうが。
思えば、日付の処理を書くたび「大丈夫かな?」とは感じていた。いつしか「大丈夫だろう」になり、そのうち「大丈夫だ」になった。
慣れとは恐ろしい。そしてまた、優れたプログラムを書くことの難しさを思い知らされる。
P.S.
形式手法を用いれば、こういう不具合を検出できるのだろうか…。
彼らは、限界を定めるべきだと常々思っている。