关于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 相关文章推荐
在Zeus Web Server中安装PHP语言支持
Oct 09 PHP
基于PHP+MySQL的聊天室设计
Oct 09 PHP
PHP新手上路(十)
Oct 09 PHP
解决了Ajax、MySQL 和 Zend Framework 的乱码问题
Mar 03 PHP
实用PHP会员权限控制实现原理分析
May 29 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(四)
Jun 23 PHP
php使用指定字符列表生成随机字符串的方法
Apr 18 PHP
PHP实现linux命令tail -f
Feb 22 PHP
PHP常见数组函数用法小结
Mar 21 PHP
php 输入输出流详解及示例代码
Aug 25 PHP
Zend Framework分发器用法示例
Dec 11 PHP
php 反斜杠处理函数addslashes()和stripslashes()实例详解
Dec 25 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 中的面向对象编程:通向大型 PHP 工程的办法
2006/12/03 PHP
discuz 首页四格:最新话题+最新回复+热门话题+精华文章插件
2007/08/19 PHP
PHP函数preg_match_all正则表达式的基本使用详细解析
2013/08/31 PHP
Javascript控制div属性动态变化实例分析
2015/10/08 Javascript
12个非常实用的JavaScript小技巧【推荐】
2016/05/18 Javascript
JavaScript简单下拉菜单特效
2016/09/13 Javascript
Angularjs实现带查找筛选功能的select下拉框示例代码
2016/10/04 Javascript
微信小程序 地图(map)实例详解
2016/11/16 Javascript
vue给input file绑定函数获取当前上传的对象完美实现方法
2017/12/15 Javascript
express默认日志组件morgan的方法
2018/04/05 Javascript
实例讲解Vue.js中router传参
2018/04/22 Javascript
LayerClose弹窗关闭刷新方法
2018/08/17 Javascript
总结4个方面优化Vue项目
2019/02/11 Javascript
Vue实现滑动拼图验证码功能
2019/09/15 Javascript
JavaScript中的Proxy对象
2020/11/27 Javascript
[02:42]2014DOTA2国际邀请赛 三冰专访:我会打到Ti20
2014/07/13 DOTA
[04:26]DOTA2上海特锦赛小组赛第二日 TOP10精彩集锦
2016/02/27 DOTA
Python进阶之尾递归的用法实例
2018/01/31 Python
利用pandas读取中文数据集的方法
2018/07/25 Python
基于numpy中数组元素的切片复制方法
2018/11/15 Python
python面向对象 反射原理解析
2019/08/12 Python
Python OpenCV图像指定区域裁剪的实现
2019/10/30 Python
使用pytorch完成kaggle猫狗图像识别方式
2020/01/10 Python
Django实现图片上传功能步骤解析
2020/04/22 Python
实现ECharts双Y轴左右刻度线一致的例子
2020/05/16 Python
html5 input属性使用示例
2013/06/28 HTML / CSS
canvas实现手机的手势解锁的步骤详细
2020/03/16 HTML / CSS
世界著名的顶级牛排:Omaha Steak(奥马哈牛排)
2016/09/20 全球购物
全球最大化妆品零售网站:SkinStore
2020/10/24 全球购物
应届生船舶驾驶求职信
2013/10/19 职场文书
八项规定自查自纠报告及整改措施
2014/10/26 职场文书
2015年信息化建设工作总结
2015/07/23 职场文书
八年级作文之我的母亲
2019/12/10 职场文书
python基础入门之字典和集合
2021/06/13 Python
使用 Apache Superset 可视化 ClickHouse 数据的两种方法
2021/07/07 Servers
python+opencv实现目标跟踪过程
2022/06/21 Python