ホームページ  >  記事  >  バックエンド開発  >  PHP で 2038 年を超える日付を変換するときのエラーを解決する方法

PHP で 2038 年を超える日付を変換するときのエラーを解決する方法

小云云
小云云オリジナル
2018-02-10 13:23:501899ブラウズ

私は現在プロジェクトのインターフェースを書いています。テスト中に、通常の機能はサーバー上でテストされましたが、ローカルでは常に問題が発生することがわかりました。段階的に調査した結果、最終的なロックの問題は、関数 strtotime が false 値を返し、データベースへのデータ挿入が失敗することが原因であることが判明しました。

同じコードでも実行結果が異なるのは、環境が一貫していないためです。 PHPのバージョンが違うかビット数が違うかのどちらかです。

この記事では、PHP が 2038 年以降の日付を変換する問題の解決策を主に紹介します。この記事では、詳細な解決策が示されており、サンプルコードを通じて誰でも理解しやすくなっています。必要な方は以下をご覧ください。 , 皆さんのお役に立てれば幸いです。

私のコンピューターは 64 ビットです。 PHP のビット数に不一致があります。サーバーは 64 ビットを使用していますが、ローカルのサーバーは 32 ビットです。また、strtotime は文字列 2050-1-1 23:59:59 で渡されます。このパラメータは 2038-1-19 03:14:07 より大きいため、32 ビット PHP では直接 false を返しますが、64 ビット PHP では false が返されます。インフルエンスの影響を受けません。

Y2K38 脆弱性

上記の問題の根本原因は、Unix Millennium Bug としても知られる Y2K38 脆弱性です。

32 ビット システムまたは PHP

この脆弱性は、32 ビット システムで時刻を記録するために UNIX タイムスタンプ整数を使用するすべての PHP およびその他のプログラミング言語に影響します。整数変数を保存できる最大時間は、2038 年 1 月 19 日 03:14:07 です。この時間を超えると、整数値はオーバーフローします。

64 ビット システムまたは PHP

64 ビット システムで保存できる最も遠い日付は、現在の宇宙年齢の 21 倍、つまり 292 億年です。したがって、この脆弱性による影響は受けません。

検出方法

システムがこの脆弱性の影響を受けるかどうかを確認する方法。これは非常に簡単で、strtotime を使用して 2038 年 1 月 19 日 03:14:07 より後の日付を変換するだけです。または、date 関数を使用して、2147454847 より大きいタイムスタンプを日付に変換します。

以下は詳細なデモです

方法 1

echo date("Y-m-d H:i:s",2556115199);

上記の結果が 2050-12-31 23:59:59 を返す場合、問題はありません。 1914-11-25 09:31:43 を返すと影響を受けます。

方法2

var_dump(strtotime("2050-12-31 23:59:59"));

上記の結果が2556115199を返した場合は正常です。 false が返された場合も影響を受けます。

解決策

オプション1

システムとPHPを64ビットに変更します。このコストは比較的高くなりますが、問題を永久に解決できます。

オプション 2

バージョン PHP5.2 以降では、問題を一時的に解決する関数 DateTime が提供されています。

// 1、日期字符串转换为时间戳
$obj = new DateTime("2050-12-31 23:59:59");
echo $obj->format("U"); // 2556115199

// 2、时间戳转换为日期字符串
$obj = new DateTime("@2556115199"); // 这里时间戳前要写一个@符号
$timezone = timezone_open('Asia/HONG_KONG'); // 设置时区
$obj->setTimezone($timezone); 
echo $obj->format("Y-m-d H:i:s"); // 2050-12-31 23:59:59

// 而且DateTime还可以有其他玩法
$obj = new DateTime("2050-12-31 23:59:59");
echo $obj->format("Y/m/d H:i:s"); // 换种方式输入时间字符串2050/12/31 23:59:59

DateTime クラスを使用した日付の操作は、Y2K38 脆弱性の影響を受けず、9999 年 12 月 31 日まではサポートされます

関連推奨事項:

php の日付と休日の変換のインスタンス分析

php についてdate 配列の使い方のまとめ

php 日付からタイムスタンプ、指定された日付からタイムスタンプ

以上がPHP で 2038 年を超える日付を変換するときのエラーを解決する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。