关于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部分常见问题总结
Oct 09 PHP
PHP文件上传实例详解!!!
Jan 02 PHP
解决cPanel无法安装php5.2.17
Jun 22 PHP
PHP利用hash冲突漏洞进行DDoS攻击的方法分析
Mar 26 PHP
php自定义分页类完整实例
Dec 25 PHP
详解PHP的Yii框架中的Controller控制器
Mar 29 PHP
php中访问修饰符的知识点总结
Jan 27 PHP
laravel 事件/监听器实例代码
Apr 12 PHP
PHP超低内存遍历目录文件和读取超大文件的方法
May 01 PHP
Yii框架通过请求组件处理get,post请求的方法分析
Sep 03 PHP
laravel excel 上传文件保存到本地服务器功能
Nov 14 PHP
PHP cookie与session会话基本用法实例分析
Nov 18 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
曾在DC漫画界反派角色扮演的演员,谁才是你心目中的小丑之王?
2020/04/09 欧美动漫
一步一步学习PHP(6) 面向对象
2010/02/16 PHP
php中引用符号(&)的使用详解
2013/11/13 PHP
配置eAccelerator和XCache扩展来加速PHP程序的执行
2015/12/22 PHP
PHP日志LOG类定义与用法示例
2018/09/06 PHP
php文件包含的几种方式总结
2019/09/19 PHP
彻底搞懂JS无缝滚动代码
2007/01/03 Javascript
jQuery事件 delegate()使用方法介绍
2012/10/30 Javascript
jQuery动画与特效详解
2015/02/01 Javascript
js实现移动端微信页面禁止字体放大
2017/02/16 Javascript
微信小程序 生命周期函数详解
2017/05/24 Javascript
vue中component组件的props使用详解
2017/09/04 Javascript
JS实现table表格内针对某列内容进行即时搜索筛选功能
2018/05/11 Javascript
JavaScript中关于base64的一些事
2019/05/06 Javascript
Vue 实现前进刷新后退不刷新的效果
2019/06/14 Javascript
js canvas实现五子棋小游戏
2021/01/22 Javascript
Python实现的简单文件传输服务器和客户端
2015/04/08 Python
Python基于scrapy采集数据时使用代理服务器的方法
2015/04/16 Python
python实现二分查找算法
2017/09/21 Python
Django csrf 验证问题的实现
2018/10/09 Python
Python中请不要再用re.compile了
2019/06/30 Python
解决python3插入mysql时内容带有引号的问题
2020/03/02 Python
详解用Pytest+Allure生成漂亮的HTML图形化测试报告
2020/03/31 Python
Python xpath表达式如何实现数据处理
2020/06/13 Python
用opencv给图片换背景色的示例代码
2020/07/08 Python
解决运行出现'dict' object has no attribute 'has_key'问题
2020/07/15 Python
详解python安装matplotlib库三种失败情况
2020/07/28 Python
详解pandas中利用DataFrame对象的.loc[]、.iloc[]方法抽取数据
2020/12/13 Python
利用纯CSS3实现文字向右循环闪过效果实例(可用于移动端)
2017/06/15 HTML / CSS
45个非常奇妙的CSS3 特性应用示例
2012/01/01 HTML / CSS
加拿大最大的书店:Indigo
2017/01/01 全球购物
打架检讨书400字
2014/01/17 职场文书
高一学生期末评语
2014/04/25 职场文书
2015年乡镇工会工作总结
2015/05/19 职场文书
幸福终点站观后感
2015/06/04 职场文书
mongodb数据库迁移变更的解决方案
2021/09/04 MongoDB