MySQLで timestamp型 を使うのはNG!2038年問題の対処法

2038年問題

これはMySQLなどのデータベースにも影響を与えます。

特に問題なのが TIMESTAMP 型が2038年問題に対応してないこと

もし TIMESTAMP 型を使い続けると、将来大変なことになるかもしれません。

ということで、MySQLで2038年問題を回避する方法をまとめました。

そもそも2038年問題ってどういう問題?

まず知ってる人も多いけど、2038年問題 について解説

これは 2038年1月19日3時14分7秒 を過ぎると、プログラムが誤作動する問題のことです。

伝統的な実装ではtime_tをintとし、そのintは符号つき32ビットであった。このため最大値は (231 − 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秒、閏秒は考慮していない)を過ぎると、この値がオーバーフローし、と扱われる[3]ため、時刻を正しく扱えていることを前提としたコードがあれば、誤作動する。

引用元 : 2038年問題 - Wikipedia

上の説明は Wikipedia から引用したもの

従来だと日時はなぜか 32ビット型 で扱ってたので、それが問題の温床です。

32ビットだと 68年分 しか扱えないので、そのツケがあと数十年後にやってくるということ

 

もちろん MySQL でも日時を扱うことは当然あります。

なので何も対策してないと、次の例みたいにデータベースがかなり深刻な影響を受けます。

実際にMySQLで2038年問題を疑似再現してみた

MySQLだと TIMESTAMP型 が2038年問題の影響をモロにうけます。

そこで実際に適当なテーブルを作って、2038年を疑似再現をしてみました。

 

まず 2038年01月19日 03時14分07秒以前 なら TIMESTAMP 型は正常に機能します。

例えば次みたいなテーブルを作ってレコード挿入したとしましょう。

この SQL 実行の結果は次の通り

ここまではOKです、特に問題ありません。

 

でも問題になるのが 2038年01月19日 03時14分07秒以降の日時 だったとき

例えば次みたいなSQLを発行してみました。

この結果がどうなるかというと次の通り

こういう風にエラーが出て、レコード自体が挿入できなくなる訳です。

既に動いてるシステムでこんなことが起こったら・・・想像するだけでも恐ろしいですね。

でもこの2038年問題の対処法、MySQLならそんなに難しくありません。

MySQLで2038年問題を超簡単に解決する方法

その解決方法とは、

 TIMESTAMP型 を使うのをやめて DATETIME型 に切り替えること

たったこれだけで 2038年問題は簡単に解決できます。

 

なぜこう言い切れるかというと、リファレンスにこう書いてあるから

DATETIME 型は、日付と時間の両方の部分を含む値に使用されます。MySQL では、DATETIME 値の取得と表示は 'YYYY-MM-DD HH:MM:SS' 形式で行われます。サポートしている範囲は '1000-01-01 00:00:00' から '9999-12-31 23:59:59' です。
>TIMESTAMP データ型は、日付と時間の両方の部分を含む値に使用されます。TIMESTAMP には、'1970-01-01 00:00:01' UTC から '2038-01-19 03:14:07' UTC の範囲があります。

引用元 : DATE、DATETIME、およびTIMESTAMP型

赤字で強調したところに注目してください。

この説明の通り、 DATETIME を使えば9999年まで日時を問題なく扱えるんです

つまり次に日時が問題になるのは 西暦10000年 ってことですね。

その頃になったら 「10000年問題がヤバい!」 とか言って騒がれてるかも・・・

まあ今開発してるシステムを10000年まで動かす予定がないなら大丈夫です。

 

これを使えば、2038年以降の日付も問題なく扱えます。

例えば次が先ほどのSQLを DATETIME型 で書き換えたもの

この実行結果は次の通り

はい、ちゃんと問題なく動いてくれてます。

以上が MySQL で2038年問題を回避する方法

今動いているシステムだと難しいですが、これから作るシステムなら簡単に対策できます。

補足 : PHPでも2038年問題には注意しよう!

ここまでが MySQL での2038年問題の回避策

もちろんMySQL以外に、PHP などでも問題が起こります。

その PHPでの2038年問題回避策 は次記事でまとめたので、良ければご覧ください。

PHPにはTIMESTAMP型はないです。

でもdate関数が 2038年問題 の温床になるので要注意ですね。

ここまでのまとめ

ということで簡単なまとめ

  • TIMESTAMP型は使ったらダメ
    なぜなら内部的に日時を32ビットで扱っているため。2038年01月19日 03時14分07秒 より大きな日時を代入すると誤作動の原因に。絶対使っちゃダメ!
  • 代わりにDATETIME型を使えばOK
    リファレンスによると DATETIME型 は 9999年 まで対応している。日時を扱うならこちらを使う方が安全だし2038年問題も解決できる

MySQLでは絶対に TIMESTAMP型 を使わないように要注意!

以上、MySQLでの2038年問題の回避方法についてでした。ではでは(^_^)/~

Commentsこの記事についたコメント

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA


このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください