原因分析
这个问题在 64 位的 PHP 版本中并不存在,因为是在 32 位版本中,以秒计算 PHP 只支持到 2147483648,即:2^31,到 2038-01-19 03:14:08。
Note:
有效的时间戳通常从 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');
}
网友评论