TimeとDateTimeと2038年問題
現在の Unix システムでの最大時刻は、協定世界時の2038年1月19日午前3時14分7秒です。
http://www.ruby-lang.org/ja/man/?cmd=view;name=Time
Timeは2038/1/19以降がエラーになる。
>> Time.gm(2038,1,19).strftime("%Y-%m-%d %a") => "2038-01-19 Tue" >> Time.gm(2038,1,20).strftime("%Y-%m-%d %a") ArgumentError: time out of range from (irb):7:in `gm' from (irb):7 from :0
DateTimeはもっとずっと先まで大丈夫。
>> require 'date' => true >> DateTime.civil(2038,1,19).strftime("%Y-%m-%d %a") => "2038-01-19 Tue" >> DateTime.civil(2038,1,20).strftime("%Y-%m-%d %a") => "2038-01-20 Wed" >> DateTime.civil(99999999999999,1,20).strftime("%Y-%m-%d %a") => "99999999999999-01-20 Sun" >> DateTime.civil(999999999999999,1,20).strftime("%Y-%m-%d %a") => "999999999999999-01-20 Sun" >> DateTime.civil(9999999999999999,1,20).strftime("%Y-%m-%d %a") ArgumentError: invalid date from /usr/lib/ruby/1.8/date.rb:1173:in `civil' from (irb):14 from :0
ActionWebserviceが:timeのデータをDateTimeで受け取ってしまうのは何でだろうと思っていましたが、ここらへんが一番の原因なのかなー。
Timeの下限は1901年12月13日20時45分52秒。
>> Time.gm(1901,12,13,20,45,52).strftime("%Y-%m-%d %a") => "1901-12-13 Fri" >> Time.gm(1901,12,13,20,45,51).strftime("%Y-%m-%d %a") ArgumentError: time out of range from (irb):45:in `gm' from (irb):45 >> Time.gm(1901,12,13,20,45,52).to_i => -2147483648
これはOSに依存するみたい。
Time [compat] 負の time_t を扱えるようになりました(OSがサポートしている場合に限る)
http://www.ruby-lang.org/ja/man/index.cgi?cmd=view;name=1.6.8%A4%AB%A4%E91.8.0%A4%D8%A4%CE%CA%D1%B9%B9%C5%C0(%A4%DE%A4%C8%A4%E1)
手元の環境(MySQL)だと、ActiveRecordがTIMESTAMPの範囲外の日付をnilにしてくれる。DBの値がNULLの場合と区別がつかない。すごく危険な感じ。Timeの代わりにDateTimeを使う方法はあるのかな?