关于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 相关文章推荐
把从SQL中取出的数据转化成XMl格式
Oct 09 PHP
手把手教你使用DedeCms V3的在线采集图文教程
Apr 03 PHP
php中用文本文件做数据库的实现方法
Mar 27 PHP
php md5下16位和32位的实现代码
Apr 09 PHP
php处理json时中文问题的解决方法
Apr 12 PHP
采集邮箱的php代码(抓取网页中的邮箱地址)
Jul 17 PHP
PHP JS Ip地址及域名格式检测代码
Sep 27 PHP
微信公众平台开发实现2048游戏的方法
Apr 15 PHP
php将文件夹打包成zip文件的简单实现方法
Oct 04 PHP
PHP微信支付结果通知与回调策略分析
Jan 10 PHP
php面向对象基础详解【星际争霸游戏案例】
Jan 23 PHP
php实现的简单多进程服务器类完整示例
Feb 01 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
Apache+php+mysql在windows下的安装与配置图解(最新版)
2008/11/30 PHP
php 生成唯一id的几种解决方法
2013/03/08 PHP
CentOS下与Apache连接的PHP多版本共存方案实现详解
2015/12/19 PHP
Javascript 类型转换方法
2010/10/24 Javascript
javascript跨域刷新实现代码
2011/01/01 Javascript
JS实现拖动示例代码
2013/11/01 Javascript
jquery中的查找parents与closest方法之间的区别
2013/12/02 Javascript
百度判断手机终端并自动跳转js代码及使用实例
2014/06/11 Javascript
JS实现很酷的EMAIL地址添加功能实例
2015/02/28 Javascript
浅谈DOCTYPE对$(window).height()取值的影响
2016/07/21 Javascript
详解jQuery中ajax.load()方法
2017/01/25 Javascript
基于Vue SEO的四种方案(小结)
2019/07/01 Javascript
[00:58]他们到底在电话里听到了什么?
2017/11/21 DOTA
一些常用的Python爬虫技巧汇总
2016/09/28 Python
通过Python实现自动填写调查问卷
2017/09/06 Python
Python 实现数据结构-堆栈和队列的操作方法
2019/07/17 Python
python3.7 openpyxl 删除指定一列或者一行的代码
2019/10/08 Python
Django框架反向解析操作详解
2019/11/28 Python
Python读写操作csv和excle文件代码实例
2020/03/16 Python
tensorflow中tf.reduce_mean函数的使用
2020/04/19 Python
Pycharm plot独立窗口显示的操作
2020/12/11 Python
python 将html转换为pdf的几种方法
2020/12/29 Python
CSS3 clip-path 用法介绍详解
2018/03/01 HTML / CSS
使用javascript和HTML5 Canvas画的四渐变色播放按钮效果
2014/04/10 HTML / CSS
HTML5中form如何关闭自动完成功能的方法
2018/07/02 HTML / CSS
事业单位公务员的职业生涯规划
2014/01/15 职场文书
草船借箭教学反思
2014/02/03 职场文书
带薪年假请假条
2014/02/04 职场文书
小学教师师德感言
2014/02/10 职场文书
如何写一份好的英文求职信
2014/03/19 职场文书
节水倡议书范文
2014/04/15 职场文书
文明班集体申报材料
2014/05/23 职场文书
市场调研项目授权委托书范本
2014/10/04 职场文书
2014年路政工作总结
2014/12/10 职场文书
成品仓库管理员岗位职责
2015/04/09 职场文书
通知的写法
2015/04/23 职场文书