关于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 相关文章推荐
Win2003服务器安全加固设置--进一步提高服务器安全性
May 23 PHP
php设计模式小结
Feb 15 PHP
php中文乱码怎么办如何让浏览器自动识别utf-8
Jan 15 PHP
PHP动态页生成静态页的3种常用方法
Nov 13 PHP
php实现session自定义会话处理器的方法
Jan 27 PHP
php获取图片信息的方法详解
Dec 10 PHP
ThinkPHP模板Volist标签嵌套循环输出多维数组的方法
Mar 23 PHP
PHP微信公众号自动发送红包API
Jun 01 PHP
PHP list() 将数组中的值赋给变量的简单实例
Jun 13 PHP
微信支付开发维权通知实例
Jul 12 PHP
PHP实现批量清空删除指定文件夹所有内容的方法
May 30 PHP
PHP+fiddler抓包采集微信文章阅读数点赞数的思路详解
Dec 20 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
用ODBC的分页显示
2006/10/09 PHP
Twig模板引擎用法入门教程
2016/01/20 PHP
Laravel5中防止XSS跨站攻击的方法
2016/10/10 PHP
laravel框架创建授权策略实例分析
2019/11/22 PHP
js 数组克隆方法 小结
2010/03/20 Javascript
jquery 笔记 事件
2011/11/02 Javascript
jQuery文本框(input textare)事件绑定方法教程
2013/04/24 Javascript
js用闭包遍历树状数组的方法
2014/03/19 Javascript
js点击选择文本的方法
2015/02/09 Javascript
浅析Javascript匿名函数与自执行函数
2016/02/06 Javascript
AngularJS学习第二篇 AngularJS依赖注入
2017/02/13 Javascript
vue项目常用组件和框架结构介绍
2017/12/24 Javascript
node实现登录图片验证码的示例代码
2018/04/20 Javascript
jQuery 实现批量提交表格多行数据的方法
2018/08/09 jQuery
VUE 配置vue-devtools调试工具及安装方法
2018/09/30 Javascript
详解vue项目打包步骤
2019/03/29 Javascript
vue2.0 实现富文本编辑器功能
2019/05/26 Javascript
vue相关配置文件详解及多环境配置详细步骤
2020/05/19 Javascript
浅谈vue.watch的触发条件是什么
2020/11/07 Javascript
Python使用Scrapy爬取妹子图
2015/05/28 Python
Python获取命令实时输出-原样彩色输出并返回输出结果的示例
2019/07/11 Python
Django rest framework jwt的使用方法详解
2019/08/08 Python
Python学习笔记之装饰器
2020/08/06 Python
基于Python中Remove函数的用法讨论
2020/12/11 Python
CSS3实现多背景模拟动态边框的效果
2016/11/08 HTML / CSS
加拿大消费电子和手机购物网站:The Source
2017/01/28 全球购物
英国度假别墅预订:Sykes Cottages
2017/06/12 全球购物
意大利网上购书网站:Libraccio.it
2021/02/03 全球购物
婚前协议书
2014/04/15 职场文书
见习报告的格式
2014/11/04 职场文书
2014年精神文明建设工作总结
2014/11/19 职场文书
政协工作总结2015
2015/05/20 职场文书
在人间读书笔记
2015/06/30 职场文书
金榜题名主持词
2015/07/02 职场文书
学困生帮扶工作总结
2015/08/13 职场文书
简单聊聊Vue中的计算属性和属性侦听
2021/10/05 Vue.js