关于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 相关文章推荐
海河写的 Discuz论坛帖子调用js的php代码
Aug 23 PHP
php5编程中的异常处理详细方法介绍
Jul 29 PHP
php 生成饼图 三维饼图
Sep 28 PHP
深入探讨:PHP使用数据库永久连接方式操作MySQL的是与非
Jun 05 PHP
自己写的兼容低于PHP 5.5版本的array_column()函数
Oct 24 PHP
php_imagick实现图片剪切、旋转、锐化、减色或增加特效的方法
Dec 15 PHP
php使用wordwrap格式化文本段落的方法
Mar 17 PHP
PHP ajax 异步执行不等待执行结果的处理方法
May 27 PHP
Yii2配置Nginx伪静态的方法
May 05 PHP
PHP实现webshell扫描文件木马的方法
Jul 31 PHP
PHP常见字符串操作函数与用法总结
Mar 04 PHP
yii2.0框架使用 beforeAction 防非法登陆的方法分析
Sep 11 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
不用GD库生成当前时间的PNG格式图象的程序
2006/10/09 PHP
Zend Framework自定义Helper类相关注意事项总结
2016/03/14 PHP
php rsa 加密,解密,签名,验签详解
2016/12/06 PHP
Yii Framework框架开发微信公众平台示例
2020/04/26 PHP
Javascript Global对象
2009/08/13 Javascript
教您去掉ie网页加载进度条的方法
2010/12/09 Javascript
基于jquery的回到页面顶部按钮
2011/06/27 Javascript
js+JQuery返回顶部功能如何实现
2012/12/03 Javascript
JavaScript地图拖动功能SpryMap的简单实现
2013/07/17 Javascript
js函数setTimeout延迟执行的简单介绍
2013/07/17 Javascript
页面按钮禁用与解除禁用的方法
2014/02/19 Javascript
JavaScript弹出窗口方法汇总
2014/08/12 Javascript
JavaScript实现的双向跨域插件分享
2015/01/31 Javascript
jQuery DOM插入节点操作指南
2015/03/03 Javascript
浅析JavaScript中作用域和作用域链
2016/12/06 Javascript
详解jQuery事件
2017/01/13 Javascript
js上传图片预览的实现方法
2017/05/09 Javascript
使用vuex的state状态对象的5种方式
2018/04/19 Javascript
Vue.js单向绑定和双向绑定实例分析
2018/08/14 Javascript
微信小程序用户拒绝授权的处理方法详解
2019/09/20 Javascript
JavaScript进阶(三)闭包原理与用法详解
2020/05/09 Javascript
python搭建简易服务器分析与实现
2012/12/15 Python
利用python实现对web服务器的目录探测的方法
2019/02/26 Python
python中的数据结构比较
2019/05/13 Python
浅谈numpy中np.array()与np.asarray的区别以及.tolist
2020/06/03 Python
使用CSS变量实现炫酷惊人的悬浮效果
2019/04/26 HTML / CSS
钉钉企业内部H5微应用开发详解
2020/05/12 HTML / CSS
微软香港官网及网上商店:Microsoft HK
2016/09/01 全球购物
7 For All Mankind官网:美国加州洛杉矶的高级牛仔服装品牌
2018/12/20 全球购物
捷科时代的软件测试笔试题
2015/11/09 面试题
搞笑创意广告语
2014/03/17 职场文书
员工考核评语大全
2014/04/26 职场文书
十佳青年事迹材料
2014/08/21 职场文书
办公室班子四风问题对照检查材料
2014/10/04 职场文书
2014年涉外离婚协议书范本
2014/11/20 职场文书
新农村建设指导员工作总结
2015/08/13 职场文书