关于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和jquery实现地图区域数据统计展示数据示例
Feb 12 PHP
php开启openssl的方法
May 15 PHP
MacOS 安装 PHP的图片裁剪扩展Tclip
Mar 25 PHP
php实现用已经过去多长时间的方式显示时间
Jun 05 PHP
php实现Mysql简易操作类
Oct 11 PHP
Laravel中使用FormRequest进行表单验证方法及问题汇总
Jun 19 PHP
PHP中new static()与new self()的比较
Aug 19 PHP
PHP自带方法验证邮箱、URL、IP是否合法的函数
Dec 08 PHP
PHP中检查isset()和!empty()函数的必要性
Feb 13 PHP
php字符串截取函数mb_substr用法实例分析
Jun 25 PHP
laravel框架模型中非静态方法也能静态调用的原理分析
Nov 23 PHP
PHP+ajax实现上传、删除、修改单张图片及后台处理逻辑操作详解
Feb 12 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
windows7下安装php的imagick和imagemagick扩展教程
2014/07/04 PHP
php时间戳格式化显示友好的时间函数分享
2014/10/21 PHP
php技术实现加载字体并保存成图片
2015/07/27 PHP
彪哥1.1(智能表格)提供下载
2006/09/07 Javascript
js对象关系图 方便dom操作
2012/03/18 Javascript
jquery多选项卡效果实例代码(附效果图)
2013/03/23 Javascript
js中一个函数获取另一个函数返回值问题探讨
2013/11/21 Javascript
js二维数组定义和初始化的三种方法总结
2014/03/03 Javascript
一个简单的动态加载js和css的jquery代码
2014/09/01 Javascript
浅谈Javascript中的Function与Object
2015/01/26 Javascript
Jquery左右滑动插件之实现超级炫酷动画效果附源码下载
2015/12/02 Javascript
jquery表单验证插件formValidator使用方法
2016/04/01 Javascript
使用jquery提交form表单并自定义action的方法
2016/05/25 Javascript
js动态获取子复选项并设计全选及提交的实现方法
2016/06/24 Javascript
canvas实现图像截取功能
2017/02/06 Javascript
js 博客内容进度插件详解
2017/02/19 Javascript
jQuery实现单击按钮遮罩弹出对话框效果(2)
2017/02/20 Javascript
Angular开发者指南之入门介绍
2017/03/05 Javascript
jquery实现企业定位式导航效果
2018/01/01 jQuery
实例详解vue中的$root和$parent
2019/04/29 Javascript
layer弹出层自适应高度,垂直水平居中的实现
2019/09/16 Javascript
element-ui tooltip修改背景颜色和箭头颜色的实现
2019/12/16 Javascript
深入理解 ES6中的 Reflect用法
2020/07/18 Javascript
vue 函数调用加括号与不加括号的区别
2020/10/29 Javascript
Python获取服务器信息的最简单实现方法
2015/03/05 Python
实例讲解Python中函数的调用与定义
2016/03/14 Python
django 常用orm操作详解
2017/09/13 Python
Pyqt QImage 与 np array 转换方法
2019/06/27 Python
使用Pyhton集合set()实现成果查漏的例子
2019/11/24 Python
python try...finally...的实现方法
2020/11/25 Python
美国在线打印网站:Overnight Prints
2018/10/11 全球购物
2013年入党人员的自我鉴定
2013/10/25 职场文书
会计实训报告范文
2014/11/04 职场文书
【超详细】八大排序算法的各项比较以及各自特点
2021/03/31 Python
python 离散点图画法的实现
2022/04/01 Python
win10此电脑打不开怎么办 win10双击此电脑无响应的解决办法
2022/07/23 数码科技