3

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?

mvp
  • 111,019
  • 13
  • 122
  • 148
robert laing
  • 1,331
  • 2
  • 12
  • 19
  • 3
    Perhaps this is year 2038 problem? That is, 32bit seconds overflow that will happen in year 2038? – mvp Jul 29 '14 at 10:09

1 Answers1

7

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
mvp
  • 111,019
  • 13
  • 122
  • 148
  • [Perl 5.12 and up compensate for the 2038 problem even on 32 bit machines](http://perldoc.perl.org/perl5120delta.html#Y2038-compliance) though there may still be libraries that screw it up. It looks like EPrints is using [timegm_local from Time::Local](https://metacpan.org/pod/Time::Local#timelocal_nocheck-and-timegm_nocheck), that should work fine. – Schwern Mar 27 '15 at 17:38