3

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

ここで何が問題なのですか?

4

1 に答える 1

7

このパッケージは、秒を表すために 32 ビット整数を使用していると思います。これはいわゆる 2038 年問題 (1970 年 1 月 1 日からの秒数が 2038 年 1 月 19 日に 2 31に達し、整数オーバーフローが発生する) につながるため、バグです。

実際には、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
于 2014-07-29T10:16:38.533 に答える