PHPで2038年問題を回避するには?すぐできる対策とコード例

あちこちで話題になってる2038年問題

コンピューター内部(というか言語内部)で扱うデータ型が問題で起こるみたいです。

もちろんPHPの場合も、対策しないとかなりヤバい影響を受けてしまいます。

ということで、 PHPでの2038年問題の回避策とコード例 をまとめてみました。

そもそも2038年問題とは?何が問題なの?

まず 2038年問題 について簡単に解説

これはその名の通り、2038年を超えるとコンピューターが誤作動するという問題です。

以下 Wikipedia からの説明引用

伝統的な実装では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

古いOSだと時間を 32ビット で扱うことが多かったです。

でも32ビットで扱えるのは 2,147,483,647秒(≒ 68年)まで

標準時から数えて約68年が 2038年1月19日3時14分7秒 という訳です。

 

つまりこういうこと

  • 32bitでは68年分の日時しか扱えない
  • 2038年問題は日時を32bitで扱うと起こる

今までだと 68年分 しか扱えなかったとは・・・

もちろんPHPにも日時型は存在するんで、次みたいに深刻な問題が出てきます。

2038年問題がPHPに与える悪影響&コード例

PHPで問題が起きるのは date関数 を使って日付をフォーマットする時

この関数は内部的に32bitで扱ってるので、2038年を超えると変な動作をします。

実際どういう誤作動をするかは次コードの通りです。

 

まず初めに 2038年問題 でギリセーフな、  2038/01//19 03:14:07  をdate関数でフォーマット

表示されるフォーマット日時は次の通りです。

まあ当たり前と言えば当たり前、当然の動作です。

 

で・す・が、
この日時を1秒でも超えると問題が出てきてしまいます

例えば2038年を過ぎた 2039-01-01  をフォーマットしてみました。

このコードがどういう結果を返すのか・・・

その答えは次の通り

なんと 1970-01-01  と表示されてしまいました。

これはさっき書いたみたいに date 関数では32bitで日時を扱うため

1秒でも32bitを過ぎると、こういう風にオーバーフローしてしまうみたいです。

PHPでの2038年問題の簡単な回避法

じゃあPHPでのこの2038年問題はどう回避すればいいのか・・・

その答えは単純で、 DateTime型 で日時を扱えばいいだけです。

なぜならDateTime型は 年、月、日、etc‥ を全て個別に扱っているため。

なので2038年を超えようが全く問題ないということです。

 

例えば DateTime型を使って、
次みたいに 2038-06-09 08:40:01  をフォーマットするコードを書いてみました。

もし date関数を使ってるならアウトです。

でも DateTime  を使ってるので、次みたいに正常に表示されます。

これが PHP での2038年問題の回避法

 

あとそれから、DateTime型で使う関数には色々エイリアスもあります

例えばその一例を上げるなら次の通り

  • date_add 関数
  • date_create 関数
  • date_format 関数
  • date_modify 関数
  • date_sub 関数

こういうのも DateTime で日時を扱えるので、問題ありません。

PHPリファレンスなどで「返り値がDateTime型」と書いてあれば大丈夫です。

MySQLでも2038年問題の対策は必須!

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

もちろん MySQL でも日付を扱うことは多いので、対策が必要になります。

その MySQLでの2038年問題への回避策 は次記事でまとめた通り

MySQLの場合、TIMESTAMP型 は使わないようにすべきです。

詳しい対策方法が知りたい人はご覧ください。対策自体は簡単なので

ここまでのまとめ

ということでPHPでの2038年問題のまとめ

  • date関数は使っちゃダメ
    この関数は内部的に日時を32ビットで扱う。そのため 2038年01月19日19日3時14分7秒 を超えた時点で誤作動してしまう。絶対使ってはダメ!
  • 代わりに DateTime を使おう
    このクラスは 年・月・日、時・分・秒 それぞれで個別にデータを扱う。なので2038年を超える日時を扱うことが可能(9999年まで取り扱える)

以上、PHPでの2038年問題の回避策についてでした。

絶対にWeb開発では date関数 は使ってはいけません、要注意です!

PHP

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

コメントを残す

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

CAPTCHA


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