PHP的strtotime计算2038年以上日期的时间戳错误(解决1970年前及2038年后问题)

  时间戳加到2038-01-19 就不可以往上加了,原因是32位的unix时间戳漏洞,称为Y2K38 漏洞。64位的系统不受此影响。


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 年刚好是这个数。


==========解决代码================

php 5.2+提供了DateTime类来处理这样的问题,参考方案如下(请注意时区的处理):

//1、Unix时间戳转日期

function unixtime_to_date($unixtime, $timezone = 'PRC') {

    $datetime = new DateTime("@$unixtime"); //DateTime类的bug,加入@可以将Unix时间戳作为参数传入

    $datetime->setTimezone(new DateTimeZone($timezone));

    return $datetime->format("Y-m-d H:i:s");

//2、日期转Unix时间戳

function date_to_unixtime($date, $timezone = 'PRC') {

    $datetime= new DateTime($date, new DateTimeZone($timezone));

    return $datetime->format('U');

echo date_to_unixtime("1900-1-31 00:00:00"); //输出-2206425952

echo '<br>';

echo unixtime_to_date(date_to_unixtime("1900-1-31 00:00:00")); //输出1900-01-31 00:00:00



2020-09-20 10:15:19 通过 网页