Question

using an old release of EPrints software, i've this function EPrints::Time::datestring_to_timet to return an integer number of seconds since 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;                                                                   
  }

if using with a year far in the future, i got a negative number:

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

result:

-26895412800

what is wrong here?

Was it helpful?

Solution

I think this package is using 32-bit integer to represent seconds. This is a bug because it leads to so called year 2038 problem - on Jan 19, 2038 number of seconds since Jan 1st, 1970 reaches 231 and integer overflow happens.

Actually, since you are trying to use year 3017, this overflow happens many times over (after every 68 years).

Typical fix for this issue is to use 64-bit numbers for seconds.

Another possibility is that you are using old 32-bit Perl. Upgrading to 64-bit Perl (together with your package) might fix it by itself.

Alternatively, you could use package DateTime. It supports timestamps that are large enough even on 32-bit Perl by using floating point numbers (53 bits).

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

$ perl -MDateTime::Format::RFC3339 -E'
   say DateTime::Format::RFC3339
      ->parse_datetime("3017-09-20T12:00:00Z")
          ->epoch'
33062817600
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top