【问题标题】:perl, int number of second since 1970perl, int 自 1970 年以来的秒数
【发布时间】:2014-07-29 09:58:09
【问题描述】:

使用旧版本的 EPrints 软件,我有这个函数 EPrints::Time::datestring_to_timet 来返回自 1970 年以来的整数秒数

  ######################################################################               
  =pod                                                                                 

  =item $xhtml = EPrints::Time::datestring_to_timet( $handle, $datevalue )             

  Returns an interger number of seconds since 1970-01-01:00:00                         

  $datevalue - in the format YYYY-MM-DDTHH:MM:SSZ                                      

  =cut                                                                                 
  ######################################################################               

  sub datestring_to_timet                                                              
  {                                                                                    
          my( $session, $datevalue, $short ) = @_;                                     

          my( $year,$mon,$day,$hour,$min,$sec ) = split /[- :TZ]/, $datevalue;         

          my $t = timegm_nocheck $sec||0,$min||0,$hour,$day,$mon-1,$year-1900;         

          return $t;                                                                   
  }

如果在未来一年使用,我得到一个负数:

print EPrints::Time::datestring_to_timet(undef, "3017-9-20T12:00:00Z");

结果:

-26895412800

这里有什么问题?

【问题讨论】:

  • 也许这是 2038 年的问题?也就是2038年会发生32bit秒溢出?

标签: perl year2038


【解决方案1】:

我认为这个包使用 32 位整数来表示秒。这是一个错误,因为它会导致所谓的 2038 年问题 - 自 1970 年 1 月 1 日以来的 2038 年 1 月 19 日秒数达到 231 并发生整数溢出。

实际上,由于您尝试使用 3017 年,因此此溢出会多次发生(每 68 年之后)。

此问题的典型解决方法是使用 64 位数秒。

另一种可能是您使用的是旧的 32 位 Perl。升级到 64 位 Perl(连同您的软件包)可能会自行修复它。

或者,您可以使用包 DateTime。它通过使用浮点数(53 位)支持足够大的时间戳,即使在 32 位 Perl 上也是如此。

$ perl -V:ivsize
ivsize='4';

$ perl -MDateTime::Format::RFC3339 -E'
   say DateTime::Format::RFC3339
      ->parse_datetime("3017-09-20T12:00:00Z")
          ->epoch'
33062817600

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-01-05
  • 2013-01-20
  • 2011-08-06
  • 2012-02-19
  • 1970-01-01
  • 1970-01-01
  • 2012-01-19
相关资源
最近更新 更多