关于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 相关文章推荐
CakePHP去除默认显示的标题及图标的方法
Oct 22 PHP
PHPWind 发帖回帖Api PHP版打包下载
Feb 08 PHP
phpmyadmin里面导入sql语句格式的大量数据的方法
Jun 05 PHP
CI(CodeIgniter)框架中的增删改查操作
Jun 10 PHP
php中socket通信机制实例详解
Jan 03 PHP
PHP设计模式之观察者模式实例
Feb 22 PHP
php格式化json函数示例代码
May 12 PHP
浅谈mysql_query()函数的返回值问题
Sep 05 PHP
详解PHP中foreach的用法和实例
Oct 25 PHP
PHP生成唯一ID之SnowFlake算法
Dec 17 PHP
PHP会话控制实例分析
Dec 24 PHP
php 7新特性之类型申明详解
Jun 06 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水印技术
2007/02/14 PHP
PHP 长文章分页函数 带使用方法,不会分割段落,翻页在底部
2009/10/22 PHP
php去掉字符串的最后一个字符附substr()的用法
2011/03/23 PHP
PHP实现生成模糊图片的方法示例
2017/12/21 PHP
PHP获取链表中倒数第K个节点的方法
2018/01/18 PHP
php中目录操作opendir()、readdir()及scandir()用法示例
2019/06/08 PHP
javascript 自动填写表单的实现方法
2010/04/09 Javascript
functional继承模式 摘自javascript:the good parts
2011/06/20 Javascript
js语法学习之判断一个对象是否为数组
2014/05/13 Javascript
javascript实现的元素拖动函数宿主为浏览器
2014/07/21 Javascript
JS是按值传递还是按引用传递
2015/01/30 Javascript
JavaScript中将数组进行合并的基本方法讲解
2016/03/07 Javascript
js+html5实现canvas绘制椭圆形图案的方法
2016/05/21 Javascript
AngularJS表格添加序号的方法
2017/03/03 Javascript
JS+HTML5实现图片在线预览功能
2017/07/22 Javascript
JavaScript 高性能数组去重的方法
2018/09/20 Javascript
React 使用Hooks简化受控组件的状态绑定
2019/03/18 Javascript
python如何查看系统网络流量的信息
2016/09/12 Python
完美解决Python2操作中文名文件乱码的问题
2017/01/04 Python
Python实现获取照片拍摄日期并重命名的方法
2017/09/30 Python
python3.6.3安装图文教程 TensorFlow安装配置方法
2020/06/24 Python
pycharm中成功运行图片的配置教程
2018/10/28 Python
pandas对dataFrame中某一个列的数据进行处理的方法
2019/07/08 Python
Python使用import导入本地脚本及导入模块的技巧总结
2019/08/07 Python
python GUI编程(Tkinter) 创建子窗口及在窗口上用图片绘图实例
2020/03/04 Python
Python grpc超时机制代码示例
2020/09/14 Python
python通用数据库操作工具 pydbclib的使用简介
2020/12/21 Python
LN-CC日本:高端男装和女装的奢侈时尚目的地
2019/09/01 全球购物
如何用JQuery进行表单验证
2013/05/29 面试题
电大会计学自我鉴定
2014/02/06 职场文书
婚前协议书怎么写
2014/04/15 职场文书
2014年科室工作总结
2014/11/20 职场文书
个人事迹材料范文
2014/12/29 职场文书
使用PDF.js渲染canvas实现预览pdf的效果示例
2021/04/17 Javascript
python脚本框架webpy的url映射详解
2021/11/20 Python
Python实现将多张图片合成MP4视频并加入背景音乐
2022/04/28 Python