2015年04月04日

C++ Builder の TDateTime が、1989年12月30日から経過日数なのは?

最近、様々な時刻表現を表示するプログラムを作って遊んでいました。
その中で、C++Builder の TDateTime と、Excel の(時刻)シリアル値が、実は同じ数値になるのを発見して、喜んでいたりということをしていました。

でも、「本当にそう?」とドキュメントを調べてみると、

TDateTime : 1989年12月30日からの経過日数
Excelのシリアル値 : 1900年1月1日を「1」とした日数

ということで、本来違うはずです。
普通に解釈すると、TDateTime の内部表現と、Excelのシリアル値は、1日ずれるはず。
でも、実際に表示している数字は同じ。

で、まずは、実験してみました。
0 を入力すると 1989/12/30 vs 1900/1/0 (おい?)で、確かに違う。
1 : 1989/12/31 vs 1900/1/1
2 : 1900/1/1 vs 1900/1/2
100 : 1900/4/9 で、「同じ」

実は、ここで、見当がつきました。
1900年は閏年じゃないけど、Excleは閏年で処理をしている。

そのあたりをついてみると、

59 : 1900/2/27 vs 1900/2/28 相違
60 : 1900/2/28 vs 1900/2/29 相違……というか、1900/2/29 は存在しない日付。
61 : 1900/3/1 で「同じ」

ということで、Excel まさかのバグ? と思ったら、この話(Excel が 1900年を閏年にしていること)は、結構有名な話のようでした。
「Excel 1900年」などで検索すると、関連する情報がいろいろ出てきます。

ということで、C++Builder の、一見中途半端な、1899年12月30日 という起点は、Excel のシリアル値と同じになるように設定して、なおかつ、「正しく」仕様を記述した結果ということかもしれません。
posted by 麻野なぎ at 18:49| Comment(0) | TrackBack(0) | 雑感