今天遇到一個bug,strtotime('2099-12-12 00:00:00')的時候返回false。排查之後發現,是32位的unix時間戳漏洞,稱為Y2K38 漏洞。(64位PHP的不受此影響)
Y2K38 漏洞
Y2K38,又稱 Unix Millennium Bug,此漏洞將會影響到所有 32 位系統下用 UNIX 時間戳整數來記錄時間的 PHP,及其它程式語言。
一個整型的變數所能儲存的最大時間為 2038 年01月19 日 03:14:07。超過這個時間後,整型數值將會溢位。
從 1970 年 01 月 01 日開始,到世界標準時 2038 年 01 月 19 日星期二凌晨 03:14:07 超過 2^31 – 1。2^31 – 1 就是0x7FFFFFFF,相信很多程式設計員都看過,在 32 位系統裡,這表示最大的有符號整數。如果用它來表示秒數,大概相當於 68.1 年,從 1970 年到 2038 年剛好是這個數。
所有,當時間大於2038 年 01 月 19 日星期二凌晨 03:14:07時,整型數值將會溢位。
(可以透過使用DateTime解決這個問題)
- 輸出當前時間
$datetime = new /DateTime();
print_r($datetime->format('Y-m-d H:i:s')); - 輸出Unix時間戳格式
//(php版本大於5.2):
$datetime = new /DateTime('2099-12-12 00:00:00');
var_dump($datetime->format('U')); - 根據給定的時間戳格式化為給定的時間
$datetime = new /DateTime();
$datetime->setTimestamp(4100688000);
echo $datetime->format('Y-m-d H:i:s');
本作品採用《CC 協議》,轉載必須註明作者和本文連結