小蒋同学 - 时间戳
type: channel
link: https://www.eybk.cn/tag/%E6%97%B6%E9%97%B4%E6%88%B3/
items: 关于 PHP 时间戳最大支持到 2038 年问题解决办法

关于 PHP 时间戳最大支持到 2038 年问题解决办法
type: item
date: 2019-11-12T20:31:00+08:00
description: 原因分析这个问题在 64 位的 PHP 版本中并不存在，因为是在 32 位版本中，以秒计算 PHP 只支持到 2147483648，即：2^31，到 2038-01-19 03:14:08。有效的时间戳通常从 Fri, 13 Dec 1901 20:45:54 GMT 到 Tue, 19 Jan 2038 03:14:07 GMT（对应于 32 位有符号整数的最小值和最大值）。不是所有的平台都支持负的时间戳，那么日记范围就被限制为不能早于 Unix 纪元。这意味着在 1970 年 1 月 1 日之前的日期将不能用在 Windows，一些 Linux 版本，以及几个其它的操作系统中。不过 PHP 5.1.0 及更新的版本克服了此限制。 —— [ PHP手册 ]解决办法如果在32系统PHP 5.1.0之后的版本，可以使用new DateTime解决。代码如下：将时间戳转为年月日：$d = new DateTime("@21474836490"); $d->setTimezone(new DateTimeZone("PRC")); echo $d->format("Y-m-d H:i:s");将年月日转为时间戳：$d = new DateTime('2650-07-06 16:21:30'); echo $d->format('U');如果运行时，遇到如下报错：WARNING: It is not safe to rely on the system’s timezone settings建议在 php.ini 里加上找到 date.timezone 项，设置 date.timezone = "Asia/Shanghai"，再重启环境。利用 DateTime 的替代函数传统 date 替代函数：function newDate($curformat, $utc_value){ while(1){ if($utc_value > 2147483647){ if(date('Y', $utc_value) < 2038){ $mydate2 = new DateTime('@'.$utcValue); $string = $mydate2->format($curformat); break; } } $string = date($curformat, $utc_value); break; } return $string; } // 调用方法 $utc_value = 2247484647 $curformat = 'Y-m-d'; newDate($curformat, $utc_value);传统 strtotime 替代函数：function newStrToTime($str_time){ $result = strtotime($str_time); if(empty($result)){ $date = new DateTime($str_time); $result = $date->format('U'); } return $result; } // 调用方法 $str_time = '2100-10-02'; newStrToTime($str_time);具体 DateTime 类使用方法请详查 - [ PHP手册-DateTime类 ]利用 DateTimeZone 的替代函数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'); }