シリアル値の1900年問題

Unix Timeをベースにすると、Unix Epochである1970年1月1日(実際には1901年12月14日)以前の日付は、変数の範囲の関係により扱いが煩雑である。

  • 日付表現⇒Unix Time ⇒シリアル値 ×

そこで、『ユリウス積算日』
http://php.net/manual/ja/function.gregoriantojd.php
を導入すれば、“紀元前4713年1月1日12時”からの積算なので安心。
‥と思ったら、1日ずれた。
理由は、Excelの有名なバグ(存在しない閏日1900年2月29日が扱われていること)のようだ。
http://pc.nikkeibp.co.jp/article/NPC/20070529/272873/?P=1&rt=nocnt
http://d.hatena.ne.jp/hebikuzure/20100423/1272037288
ちなみに、この日はcheckdate()関数では正しく弾かれます。
ここで、表設計の問題として、シリアル値『60』をどう扱うか。

  • 主キー60を欠番にするか⇒美しくない
  • 日付の方を欠番にする⇒すごく面倒
  • 60の前と後で換算関数中にif文をつけて‥⇒しんどい
  • 知らん振りして、表は1970年以降しか扱わない⇒言い訳の雪雪崩‥
  • 実はVBAでは1899年12月31日がシリアル値『1』となってるらしい⇒これだ!

ということで、一歩進めて、『1899年12月30日のシリアル値が0』という換算でこの問題は収束させようと思います。VBA互換ということで‥

$dateSerialVBA = (gregoriantojd($monthTextInput,$dayTextInput,$yearTextInput) - gregoriantojd('12','30','1899'));

http://www.scollabo.com/banban/php/php_12.html
http://labs.unoh.net/2010/11/unix_time.html
http://www.excel.studio-kazu.jp/kw/20030916180306.html
http://www.h3.dion.ne.jp/~sakatsu/Excel_Tips02.htm