关于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的库,结果发现很多东西
Dec 31 PHP
PHP操作文件类的函数代码(文件和文件夹创建,复制,移动和删除)
Nov 10 PHP
遍历指定目录下的所有目录和文件的php代码
Nov 27 PHP
PHP查询数据库中满足条件的记录条数(两种实现方法)
Jan 29 PHP
PHP 实现判断用户是否手机访问
Jan 21 PHP
PHP常用处理静态操作类
Apr 03 PHP
PHP getallheaders无法获取自定义头(headers)的问题
Mar 23 PHP
php生成带logo二维码方法小结
Apr 08 PHP
Yii2中SqlDataProvider用法示例
Sep 22 PHP
php禁用cookie后session设置方法分析
Oct 19 PHP
php原生导出excel文件的两种方法(推荐)
Nov 19 PHP
php使用ftp实现文件上传与下载功能
Jul 21 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设计模式之迭代器模式的深入解析
2013/06/13 PHP
PHP array_multisort() 函数的深入解析
2013/06/20 PHP
PHP 使用pcntl和libevent 实现Timer功能
2013/10/27 PHP
thinkphp实现发送邮件密码找回功能实例
2014/12/01 PHP
PHP实现的sqlite数据库连接类
2014/12/12 PHP
浅谈Coreseek、Sphinx-for-chinaese、Sphinx+Scws的区别
2016/12/15 PHP
jQuery :first选择器使用介绍
2013/08/09 Javascript
javascript Array.prototype.slice的使用示例
2013/11/14 Javascript
jquery实现ajax提交form表单的方法总结
2014/03/03 Javascript
javascript学习笔记(一)基础知识
2014/09/30 Javascript
Javascript window对象详解
2014/11/12 Javascript
JavaScript中的逻辑判断符&&、||与!介绍
2014/12/31 Javascript
功能强大的Bootstrap效果展示(二)
2016/08/03 Javascript
关于Vue背景图打包之后访问路径错误问题的解决
2017/11/03 Javascript
Vue-cli-webpack搭建斗鱼直播步骤详解
2017/11/17 Javascript
jQuery控制input只能输入数字和两位小数的方法
2019/05/16 jQuery
ssm+vue前后端分离框架整合实现(附源码)
2020/07/08 Javascript
vue 页面回退mounted函数不执行的解决方案
2020/07/26 Javascript
python中的字典详细介绍
2014/09/18 Python
python使用nntp读取新闻组内容的方法
2015/05/08 Python
python 时间戳与格式化时间的转化实现代码
2016/03/23 Python
python3使用scrapy生成csv文件代码示例
2017/12/28 Python
python求最大连续子数组的和
2018/07/07 Python
利用Python实现微信找房机器人实例教程
2019/03/10 Python
pytorch 更改预训练模型网络结构的方法
2019/08/19 Python
Python Print实现在输出中插入变量的例子
2019/12/25 Python
python GUI库图形界面开发之PyQt5打开保存对话框QFileDialog详细使用方法与实例
2020/02/27 Python
HTML5拖拽文件到浏览器并实现文件上传下载功能代码
2013/06/06 HTML / CSS
Sunglasses Shop荷兰站:英国最大的太阳镜独立在线零售商和供应商
2017/01/08 全球购物
神话般的珠宝:Ross-Simons
2020/07/13 全球购物
寒假思想汇报
2014/01/10 职场文书
党政领导班子四风问题对照检查材料思想汇报
2014/10/02 职场文书
龙潭大峡谷导游词
2015/02/10 职场文书
幼师求职自荐信
2015/03/26 职场文书
刑事起诉书范文
2015/05/19 职场文书
如何使用Python实现一个简易的ORM模型
2021/05/12 Python