<menuitem id="npfdd"><video id="npfdd"><listing id="npfdd"></listing></video></menuitem>
<menuitem id="npfdd"><strike id="npfdd"><thead id="npfdd"></thead></strike></menuitem>
<cite id="npfdd"></cite>
<cite id="npfdd"><video id="npfdd"><menuitem id="npfdd"></menuitem></video></cite>
<cite id="npfdd"><span id="npfdd"><menuitem id="npfdd"></menuitem></span></cite>
<thead id="npfdd"></thead>
太仓人才网 [登录] 2019年05月19日 星期天 您是第 942057173 位访者(今天第 299492 位访问者) ¡¡目前在线 1558版本更新 设为首页 | 加入收藏
太仓人才网
阳光回来了£¬2019太仓春季招聘会; 太仓十大网站; 阳光迎来1万家企业会员; 太仓人才网最新招聘信息; 太仓找工作; 太仓人才网手机版
企业£º14188 职位£º103062 简历£º262246 | 实时动态: 今天 18:57:39:求职者[50001*] 应聘了 太仓人才网 的职位 外企仓管员£¨工作地点:南郊£©[655165] 更多
当前位置: 全站信息>> 专题栏目>> 网络技术>>正文

当前系统在2038年之后datetime类也无法获取当前时间的解决

发布£º太仓人才网   发布日期£º2018-04-18  阅读次数£º  

由于php 32位使用 int 类型保存时间戳£¬也就是从1970 00:00:00 到当前时间的秒数¡£
而32位int 数字的取值范围是 -2147483648 到 2147483647¡£
 
所以当 时间戳为最大值 2147483647 时£¬表示的时间是 2038-01-19 03:14:07 或?#26412;?#26102;间 2038-01-19 11:14:07 £¨为了表述方便£¬下文中£¬将这个临界点时间称之为 T0£©¡£
而当时间大于这个时间时£¬php很多内置函数都会出错¡£
比如
 
当日期和时间大于 ?#26412;?#26102;间 2038-01-19 11:14:07 时
time()函数£¬原本应该返回时间戳£¬现在会始终返回-1¡£
date("Y-m-d H:i:s")函数£¬会返回 1970-01-01 07:59:59£¨?#26412;?#26102;间£©£¬其实也是因为 time()=-1导致的£¬date默?#31995;?#31532;二个参数就是time()¡£
同样£¬mktime() 等函数也会异常¡£
 
上网查了解决办法£¬
1¡¢换用64位系统¡£这里说的64位系统£¬需要操作系统¡¢web服务系统£¬以及PHP?#23478;?4位的¡£
2¡¢使用php5.2之后推出的 DateTime 类¡£
 
首?#20154;?#31532;一种方法£¬因为我的服务器建设在Windows系统上£¬然后又有几个自制插件£¬这些插件在php 64位下面可能不能使用£¬因此这个方法不能用¡£
再说DateTime类£¬网上?#36127;?#20960;十篇文章都说使用DateTime类就能解决2038年问题¡£
 
我在自己的服务器上测试了一下£¬使用DateTime类似乎确实可以让日期超过2038上限£¬各种转换£¬都没问题£¬这里?#20063;?#20855;体说明£¬大家网上搜"php datetime"£¬?#21152;?#35828;明¡£
但是£¬我在把服务器的时间设置为2040年4月18日的时候£¬发现£¬datetime 类依然无法获取当前时间¡£代码如下£º
$date = new DateTime();
echo $date->format('Y-m-d H:i:s');
 
输出的还是 1970-01-01 07:59:59
 
但是£¬如果使用 $date->setDate(2040,4,18) 之后£¬再显示£¬再输出时间戳等£¬都是正常的代码如下£º
$date = new DateTime();
$date->setDate(2040,4,18);
$date->setTime(10,24,11);
echo $date->format('Y-m-d H:i:s')."
\r\n";
echo $date->format('U')."
\r\n";
 
这时 输出时间 2040-04-18 10:24:11 £¬以及时间戳 2218328651 都是正常的¡£
 
问题在于£¬datetime 类可以解决 2038年之后的时间的各种运算和转换£¬但是当系统日期在2038年那个T0时间之后£¬php系统根本无法获取当前时间¡£
我还试了  new DateTime("today");new DateTime('+2 days');new DateTime('tomorrow'); 等等£¬都无法获取今天£¬明天£¬后天等日期¡£
这时£¬整个php 系统无法获取当前的年月日和时间¡£
 
然后我开始在php的系统数组 $_SERVER 中寻找£¬看看哪里能?#19994;?#21644;时间相关的内容£¬终于被我?#19994;?#19968;个 $_SERVER["REQUEST_TIME"]£¬这个实际上是一个记录用户刷新页面时php相应时刻的时间¡£它的值£¬在T0之前£¬和time()是一致的£¬但是£¬当T0之后£¬它就变成负数了¡£那么£¬怎么通过 $_SERVER["REQUEST_TIME"] 来获取真实的 时间戳呢£¿
 
很简单£¬32位int 数字的取值范围是 -2147483648 到 2147483647£¬转成2进制就会发现£¬其实是最高位用作符号位£¬最高位0表示正数£¬最高位1表示负数£¬当数字达到 2147483647后£¬二进制 就是 01111111 11111111 11111111 11111111£¨31个1£©£¬这时就是T0时刻的时间戳£¬继续+1 以后£¬变成了 10000000000000000000000000000000 £¨31个0£©£¬如果是无符号32位整数£¬就是 2147483648£¨正数£© 但是在有符号的整数里£¬最高位1表示负数£¬就是 -2147483648£¨负数£©£¬而 $_SERVER["REQUEST_TIME"] 的特性是根据时间的推移进行累加¡£所以£¬它的时间线如下£º
T0 之前£º它等于 1970 00:00:00 到当前时间的秒数£¬和time()相同
T0 时£º 它等于 2147483647
T0 后1秒£º 它等于 2147483647+1=2147483648  被表示为 -2147483648  我?#21069;?-2147483648 记作 T1£¬T1=T0+1秒的时刻
T0 后N秒£º-2147483648-1+N 
 
所以£¬当 $_SERVER["REQUEST_TIME"]<0 时£¬真正的时间戳为  $_SERVER["REQUEST_TIME"]-£¨-2147483648£©+ 2147483647¡£
其中 $_SERVER["REQUEST_TIME"]-£¨-2147483648£©表示 T1£¨变成负数£¬即T0+1秒£© 时刻到当前时间 过了多少秒¡£
 
据此£¬写出一个新的取代time()的函数£¬该函数在系统时间超过T0 时£¬也能返回正确的时间戳£¬但是它的范围是无符号32位上限 4294967295£¬?#26412;?#26102;间 2106-02-07 06:28:15¡£在这个时间之前£¬应该都可以正常使用¡£
 
function sunTime(){
  if($_SERVER["REQUEST_TIME"]>0){
    $t=$_SERVER["REQUEST_TIME"];
  }else{
    $t0=PHP_INT_MAX; // 第 2147483647 秒 再过一秒为 2147483648秒£¬但最高位变成1£¬系统中为 -2147483648
    $t1=0-$t0-1;   // t0后面1秒£¬瞬间变成负数£¬值为 -2147483648
    $t2=($_SERVER["REQUEST_TIME"]);//虽然$_SERVER["REQUEST_TIME"]变成了负数£¬但是 系统依然通过 +1秒 来计时
    $t=$t2-$t1+$t0."";  //t2-t1 就是变成负数后过了多少秒£¬t0就是变成负数前的秒数¡£
  }
  $date=new datetime("@".$t);
  $timemark=$date->format("U");
  return $timemark;
}
 
所以£¬目前网上很多人?#23478;?#20026;使用 DateTime类可以解决问题£¬殊不知等时间真正到了2038那个时间之后£¬php系统获得当前时间都会出错¡£而我这方法也是目前网上唯一存在的方法¡£
 
阳光浪子
2018-04-18


以上信息或来自于互联网£¬若?#26143;?#26435;£¬请及时联?#24403;?#31449;管理人员£¡ 阳光客服 1987127758

太仓人才网 太仓人才网WAP 苏州市人力资源服务业知名品牌 关于我们 网页制作/数据库£º阳光技术小组 QQ阳光客服
版权所有£º太仓市瑞福尔人力资源服务有限公司£»ICP许可证£º苏B2-20120448£»苏ICP备10224897号-1£»软著登字第0395877号£»人力资源中介许可320585000030号
本页更新时间:2019-05-19 19:01:00 []

苏公网安备 32058502010045号



3d¿ª½±½á¹û
<menuitem id="npfdd"><video id="npfdd"><listing id="npfdd"></listing></video></menuitem>
<menuitem id="npfdd"><strike id="npfdd"><thead id="npfdd"></thead></strike></menuitem>
<cite id="npfdd"></cite>
<cite id="npfdd"><video id="npfdd"><menuitem id="npfdd"></menuitem></video></cite>
<cite id="npfdd"><span id="npfdd"><menuitem id="npfdd"></menuitem></span></cite>
<thead id="npfdd"></thead>
<menuitem id="npfdd"><video id="npfdd"><listing id="npfdd"></listing></video></menuitem>
<menuitem id="npfdd"><strike id="npfdd"><thead id="npfdd"></thead></strike></menuitem>
<cite id="npfdd"></cite>
<cite id="npfdd"><video id="npfdd"><menuitem id="npfdd"></menuitem></video></cite>
<cite id="npfdd"><span id="npfdd"><menuitem id="npfdd"></menuitem></span></cite>
<thead id="npfdd"></thead>