关于PHP转换超过2038年日期出错的问题解决


Posted in PHP onJune 28, 2017

前言

最近在写一个项目接口。测试中发现服务器上测试正常的功能,在本地一直有问题。一步步的排查,最终锁定问题是由于函数strtotime返回了一个false值,导致数据插入数据库失败。

相同代码运行结果不一样,原因那就是环境不一致导致。要么是PHP版本不同,要么是位数不同。

我电脑是64位的。这里是PHP位数不一致,服务器使用64位,而我本地是32位。而strtotime被传入了一个字符串2050-1-1 23:59:59,该参数大于了2038-1-19 03:14:07所以在32位PHP下直接返回false,而64位PHP不受影响。

Y2K38漏洞

导致上述问题的根本原因就是Y2K38漏洞,也被称为Unix Millennium Bug

32位系统或PHP

此漏洞将会影响到所有 32 位系统下用UNIX 时间戳整数来记录时间的 PHP,及其它编程语言。一个整型的变量所能保存的最大时间为 2038 年01月19 日 03:14:07。超过这个时间后,整型数值将会溢出。

64位系统或PHP

64位系统下可以保存的日期最远日期是现在宇宙年龄的21倍——292亿年。所以不会受到该漏洞影响。

如何检测

如何知道你的系统是否收到该漏洞的影响。很简单,直接使用strtotime去转换一个大于2038年1月19日03:14:07日期。或者使用date函数将一个大于2147454847时间戳转换为日期。

下面具体演示一下

方法一

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

上面结果如果返回2050-12-31 23:59:59那么就没有问题。如果返回1914-11-25 09:31:43那么就受收到影响。

方法二

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

上面结果如果返回2556115199那么就正常。如果返回false那么也会受到影响。

解决方案

方案一

更换系统和PHP均为64位。这个代价比较大,但是可以永久解决问题。

方案二

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中使用Oracle数据库(6)
Oct 09 PHP
PHP iconv 解决utf-8和gb2312编码转换问题
Apr 12 PHP
php5 apache 2.2 webservice 创建与配置(java)
Jan 27 PHP
php中比较简单的导入phpmyadmin生成的sql文件的方法
Jun 28 PHP
PHP If Else(elsefi) 语句
Apr 07 PHP
php中动态修改ini配置
Oct 14 PHP
PHP实现采集抓取淘宝网单个商品信息
Jan 08 PHP
深入解析PHP的Laravel框架中的event事件操作
Mar 21 PHP
php简单实现数组分页的方法
Apr 30 PHP
PHP动态地创建属性和方法, 对象的复制, 对象的比较,加载指定的文件,自动加载类文件,命名空间
May 06 PHP
PHP获取本周所有日期或者最近七天所有日期的方法
Jun 20 PHP
laravel框架 laravel-admin上传图片到oss的方法
Oct 13 PHP
YII2自动登录Cookie总是失效的解决方法
Jun 28 #PHP
php的常量和变量实例详解
Jun 27 #PHP
Zend Framework框架中实现Ajax的方法示例
Jun 27 #PHP
PHP用continue跳过本次循环中剩余代码的注意点
Jun 27 #PHP
PHP API接口必备之输出json格式数据示例代码
Jun 27 #PHP
利用PHP获取访客IP、地区位置、浏览器及来源页面等信息
Jun 27 #PHP
简单谈谈PHP面向对象之标识对象
Jun 27 #PHP
You might like
php利用curl抓取新浪微博内容示例
2014/04/27 PHP
PHP中echo,print_r与var_dump区别分析
2014/09/29 PHP
php简单获取文件扩展名的方法
2015/03/24 PHP
php生成圆角图片的方法
2015/04/07 PHP
编写PHP程序检查字符串中的中文字符个数的实例分享
2016/03/17 PHP
XHProf报告字段含义的解析
2016/05/17 PHP
JS Array对象入门分析
2008/10/30 Javascript
JavaScript框架(iframe)操作总结
2014/04/16 Javascript
jQuery源码解读之removeClass()方法分析
2015/02/20 Javascript
跟我学习javascript的函数调用和构造函数调用
2015/11/16 Javascript
javascript自定义滚动条实现代码
2020/04/20 Javascript
js插件dropload上拉下滑加载数据实例解析
2016/07/27 Javascript
Bootstrap 网站实例之单页营销网站
2016/10/20 Javascript
Jquery与Bootstrap实现后台管理页面增删改查功能示例
2017/01/22 Javascript
JavaScript 数据类型详解
2017/03/13 Javascript
jquery.uploadifive插件怎么解决上传限制图片或文件大小问题
2017/05/08 jQuery
JavaScript 数组的进化与性能分析
2017/09/18 Javascript
详解vue-cli3多环境打包配置
2019/03/28 Javascript
python常规方法实现数组的全排列
2015/03/17 Python
Sanic框架应用部署方法详解
2018/07/18 Python
在Python中os.fork()产生子进程的例子
2019/08/08 Python
python3 图片 4通道转成3通道 1通道转成3通道 图片压缩实例
2019/12/03 Python
如何基于Python实现自动扫雷
2020/01/06 Python
python基于event实现线程间通信控制
2020/01/13 Python
python 基于opencv 实现一个鼠标绘图小程序
2020/12/11 Python
css3实现input输入框颜色渐变发光效果代码
2014/04/02 HTML / CSS
荷兰优雅女装网上商店:Heine
2016/11/14 全球购物
编程输出如下图形
2013/11/24 面试题
农民致富事迹材料
2014/01/23 职场文书
个人求职信范例
2014/01/29 职场文书
节能标语大全
2014/06/21 职场文书
行政专员岗位职责范本
2014/08/26 职场文书
我是特种兵观后感
2015/06/11 职场文书
爱国教育主题班会
2015/08/14 职场文书
员工旷工检讨书
2015/08/15 职场文书
医务人员医德医风心得体会
2016/01/25 职场文书