TIMESTAMP型の最大値を知った
とあるDBの日時カラムに対して、試しに「2500年」と遠い未来の日時を設定しようとすると、MySQLのエラーが出て反映されない、という問題がありました。
原因を調査したところ、MySQLの日時の型のひとつであるTIMESTAMPでは、最大値が**2038-01-09 03:14:07(UTC)**であることがわかりました。
9999-99-99...が最大ではなく、まさか上限があったとは……!
この仕様により、2038年を過ぎるとさまざまなシステムが動作不良になるのではないかと言われているのが、2038年問題だそうです。
https://ja.wikipedia.org/wiki/2038年問題
なぜ【2038年】なのか
なぜこの最大値がキリの良い時間ではないのかというと、その理由もWikipediaに書かれていました。
伝統的な実装ではtime_tをintとし、そのintは符号つき32ビットであった。このため最大値は (2^31 − 1) = 2,147,483,647 となり、取り扱えるのは2,147,483,647秒(≒ 68年)までに限られていた。これを前提として作成されたプログラムは、協定世界時における1970年1月1日0時0分0秒(日本標準時では1970年1月1日9時0分0秒)から2,147,483,647秒を経過した、2038年1月19日3時14分7秒(日本標準時では2038年1月19日12時14分7秒、閏秒は考慮していない)を過ぎると、この値がオーバーフローし、負と扱われる[2]ため、時刻を正しく扱えていることを前提としたコードがあれば、誤作動する。
符号付き32ビットだったため、このような中途半端な期間になっているそうです。
TIMESTAMPは2038年に爆発する時限爆弾 だったんですね…おそろしい…。
ということで、特に問題が無ければTIMESTAMPではなくDATETIMEを使うようにしましょう!
(DATETIMEの範囲は'1000-01-01 00:00:00' から '9999-12-31 23:59:59')
*追記*
コメントでご指摘いただきましたが、DATETIME型はタイムゾーンの影響を受けないという問題があるそうです。
http://qiita.com/yuba/items/7852a29d63d6279c6f6e
TIMESTAMP型を使い続けて、MySQLが対応してくれるの待つか、
もし今すぐにでも2038年以降の設定を使うのであれば、PostgreSQLに乗り換えるのが良さそうです!
http://qiita.com/jTakasuRyuji/items/5e50e8f298613f99c870#_reference-89d14067d7440fe8eebb