关于PHP转换超过2038年日期出错的问题解决

前言

最近在写一个项目接口。测试中发现服务器上测试正常的功能,在本地一直有问题。一步步的排查,最终锁定问题是由于函数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日

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • PHP获取当前日期及本周一是几月几号的方法

    本文实例讲述了PHP获取当前日期及本周一是几月几号的方法.分享给大家供大家参考,具体如下: <?php header("content-type:text/html;charset=utf-8"); date_default_timezone_set('PRC'); function getWeek($unixTime=''){ $unixTime=is_numeric($unixTime)?$unixTime:time(); $weekarray=array('日','一','

  • PHP 实现公历日期与农历日期的互转换

    PHP 实现公历日期与农历日期的互转换 前言: 今天根据客户的需求对时间进行了转换,就是客户要求增加农历日期的显示,在网上抄袭了一段,稍微修改了一下运行成功了,不难的,改动的很少的. 示例代码: <?php /* * * 陈海波 新二级页面 农历转换成公历 * * */ // lunar.php 新建这个php文件,所有的代码无需改,需要改的是下面teacher.php 的几行 class Lunar { private $_SMDay = array(1 => 31, 28, 31, 30,

  • PHP 实现浏览记录并按日期分组

    现有测试数据如下,要求实现如下图中的效果: array(4) { [0] => array(6) { ["visit_id"] => int(127) ["goods_id"] => int(16) ["visittime"] => int(1494399935) ["goods_name"] => string(53) "OPPO R9s 全网通4G+64G 双卡双待手机 玫瑰金&qu

  • php根据年月获取当月天数及日期数组的方法

    本文实例讲述了php根据年月获取当月天数及日期数组的方法.分享给大家供大家参考,具体如下: function get_day( $date ) { $tem = explode('-' , $date); //切割日期 得到年份和月份 $year = $tem['0']; $month = $tem['1']; if( in_array($month , array( 1 , 3 , 5 , 7 , 8 , 01 , 03 , 05 , 07 , 08 , 10 , 12))) { // $te

  • PHP正则匹配日期和时间(时间戳转换)的实例代码

    先来一个比较简单实用的代码 日期YYYY-MM-DD $str = ''; $isMatched = preg_match('/^\d{4}(\-|\/|.)\d{1,2}\1\d{1,2}$/', $str, $matches); var_dump($isMatched, $matches); php需要一定的时间格式才能转换成时间戳(表示从格林威治时间1970年01月01日00时00分00秒起至现在的总秒数),这就要用到php正则判断,以下是代码: <?php //匹配时间格式为2016-0

  • PHP判断两个给定日期是否在同一周的方法

    本文实例讲述了PHP判断两个给定日期是否在同一周的方法.分享给大家供大家参考,具体如下: /** * 判断两日期是不是同一周 * 星期是按周日到周六 */ function getSameWeek($pretime,$aftertime){ $flag = false;//默认不是同一周 $afweek = date('w',$aftertime);//当前是星期几 $mintime = $aftertime - $afweek * 3600*24;//一周开始时间 $maxtime = $af

  • PHP中获取文件创建日期、修改日期、访问时间的方法

    php获取文件创建时间.修改时间常用代码 filemtime ( string filename ) 返回文件上次被修改的时间,出错时返回 FALSE.时间以 Unix 时间戳的方式返回,可用于 date(). 例如:$a=filemtime("log.txt"); echo "修改时间:".date("Y-m-d H:i:s",$a); filectime ( string filename ) 返回文件上次 inode 被修改的时间,如果出错

  • 关于PHP转换超过2038年日期出错的问题解决

    前言 最近在写一个项目接口.测试中发现服务器上测试正常的功能,在本地一直有问题.一步步的排查,最终锁定问题是由于函数strtotime返回了一个false值,导致数据插入数据库失败. 相同代码运行结果不一样,原因那就是环境不一致导致.要么是PHP版本不同,要么是位数不同. 我电脑是64位的.这里是PHP位数不一致,服务器使用64位,而我本地是32位.而strtotime被传入了一个字符串2050-1-1 23:59:59,该参数大于了2038-1-19 03:14:07所以在32位PHP下直接返

  • 转换json格式的日期为Javascript对象的函数

    复制代码 代码如下: //转换json格式的日期(如:{ServerDatetime:"\/Date(1278930470649)\/"})为Javascript的日期对象 function ConvertJSONDateToJSDateObject(JSONDateString) { var date = new Date(parseInt(JSONDateString.replace("/Date(", "").replace(")

  • SpringBoot日期格式转换之配置全局日期格式转换器的实例详解

    1. SpringBoot设置后台向前台传递Date日期格式 在springboot应用中,@RestController注解的json默认序列化中,日期格式默认为:2020-12-03T15:12:26.000+00:00类型的显示. 在实际显示中,我们需要对其转换成我们需要的显示格式. 1.1 方式1:配置文件修改 配置文件配置application.yml: spring: # 配置日期格式化 jackson: date-format: yyyy-MM-dd HH:mm:ss #时间戳统一

  • Python pip安装lxml出错的问题解决办法

    Python  pip安装lxml出错的问题解决办法 1.  在使用pip安装lxml过程中出现了一下错误: >>> pip install lxml C:\Users\Chen>pip install lxml Collecting lxml Using cached lxml-3.5.0.tar.gz Installing collected packages: lxml Running setup.py install for lxml ... error Complete

  • Python  pip安装lxml出错的问题解决办法

    Python  pip安装lxml出错的问题解决办法 1.  在使用pip安装lxml过程中出现了一下错误: >>> pip install lxml C:\Users\Chen>pip install lxml Collecting lxml Using cached lxml-3.5.0.tar.gz Installing collected packages: lxml Running setup.py install for lxml ... error Complete

  • 解决java字符串转换成时间Unparseable date出错的问题

    今天在写代码的时候,在将字符串转换成时间的时候,出现了这样的问题. java.text.ParseException: Unparseable date: "2017-1-1 00:00:00" DateFormat df = new SimpleDateFormat("yyyy-MM-dd"); Date start = df.parse(startTime); Date stop = df.parse(stopTime); long timeSpan = sto

  • 在JS中如何把毫秒转换成规定的日期时间格式实例

    最近做的一个项目,从后台查询到日期数据传到前台JS中遍历之后显示的是以"14"开头的毫秒数,刚开始想用"simpleDateFormat"类处理,结果显示都不显示了.后来查了一下资料,感觉其实很简单,下面 把自己的方法分享给大家以供参考. 1.显示的毫秒数 2.处理之前的样式 3.处理之后的样式 Date.prototype.toLocaleString = function() { return this.getFullYear() + "-"

  • ASP.NET中TextBox使用Ajax控件显示日期不全的问题解决方法

    正常的引用 复制代码 代码如下: <%@ Register assembly="AjaxControlToolkit" namespace="AjaxControlToolkit" tagprefix="AjaxToolKit" %><asp:TextBox ID="txtRecordTime" runat="server" cssclass="style" width

  • 解析SQL Server中SQL日期转换出错的原因

    开发人员有时候使用类似下面SQL将字符串转换为日期时间类型,乍一看,这样的SQL的写法是没有什么问题的.但是这样的SQL其实有时候就是一个定时炸弹,随时可能出现问题(),下面简单对这种情况进行一个简单概括. SELECT CONVERT(DATETIME, '2020-01-13 6:46:42'); 如果你将连接数据库的登录名的默认语言修改为Aribc,然后去执行上面SQL语句,就会遇到错误,为什么呢? 为什么上面SQL的日期转换出错了呢?其实是因为登录名修改默认语言后,会话对应的date_f

  • Ruby日期时间的比较,日期转换等时间日期处理方法大全

    Ruby中Date.Time. DateTime这3个类提供 了和日期时间相关的操作. Date只能处理日期Time能处理日期和时间DateTime也能处理日期和时间 其中,DateTime 是Date的一个子类,是对时间部分数据的补充.要使用Date和DateTime类,只需导入date库就可以,要使用Time类,导入time库就行. require 'date' # 提供Date和DateTime类 require 'time' # 提供Time类(可直接使用,但导入后有更多方法) 一般来说

随机推荐