Perl era returns different values ​​on two different machines (UTC and CET)

I have 2 Linux devices that need to run a perl script and access the database. For some reason, the date itself is correct, but to return an era from Perl, a 1 hour difference results in the UTC being set on one machine and the desired CET on the other.

date on A:

Tue 11 Dec 13:34:09 CET 2012

date on B:

Tue 11 Dec 13:33:20 CET 2012

To check what is happening, I am building a minimalist example. The script uses Time :: HiRes and collects localtime-> epoch to generate the date. I built a minimalistic following script to output the behavior:

#/usr/bin/perl # use Time::HiRes qw(time); use Time::Piece; # my $date = Time::Piece->strptime(localtime->epoch,"%s"); print "$date->datetime"."\n"; print $date->tzoffset."\n"; print $date->epoch."\n"; 

Output Machine A:

Tue 11 Dec 12:35:43 2012-> datetime 0 1355229343

Output Machine B:

Tue 11 Dec 13:34:25 2012-> datetime 0 1355232865

So, as you can see, something must be wrong with the time zone or so. The difference is an hour. But I don’t know where to look and what to configure, since the date itself displays the correct time.

+2
timezone time perl
source share
2 answers

This seems to be a bug in Time::Piece->strptime(STRING, FORMAT) . Here is the code in question:

 sub strptime { my $time = shift; my $string = shift; my $format = @_ ? shift(@_) : "%a, %d %b %Y %H:%M:%S %Z"; my @vals = _strptime($string, $format); 

Start here. _strptime is the operating system's built-in strptime function . It seems to be returning local time, although this is not documented anywhere.

 # warn(sprintf("got vals: %d-%d-%d %d:%d:%d\n", reverse(@vals))); return scalar $time->_mktime(\@vals, (ref($time) ? $time->[c_islocal] : 0)); 

Ok, so we use our _mktime method to convert the _strptime output to a Time::Piece object. The second parameter is whether _mktime should be interpreted as local time or UTC. When called as Time::Piece->strptime(STRING, FORMAT) , ref($time) will be false, and therefore _mktime will be called using $islocal=0 , i.e. _strptime returns the UTC time. This is wrong, and we found a mistake. (I don't know enough about C time functions to know how this should be done.)

 } 

So you should use localtime->strptime(STRING, FORMAT) . Also, this will still fail in older versions of the module due to another error in _mktime (my distribution comes with version 1.15, where it is still broken, but it is fixed in 1.20).

This is not even a strange problem related to %s . This happens with any call to Time::Piece->strptime :

 $ perl -MTime::Piece -E'say $x=Time::Piece->strptime("11 Dec 2012 10:00","%d %b %Y %H:%M")->epoch;say scalar localtime $x' 1355220000 Tue Dec 11 04:00:00 2012 $ perl -MTime::Piece -E'say $x=localtime->strptime("11 Dec 2012 10:00","%d %b %Y %H:%M")->epoch;say scalar localtime $x' 1355220000 Tue Dec 11 04:00:00 2012 $ export PERL5LIB=Time-Piece-1.20/blib/lib:Time-Piece-1.20/blib/arch $ perl -MTime::Piece -E'say $x=Time::Piece->strptime("11 Dec 2012 10:00","%d %b %Y %H:%M")->epoch;say scalar localtime $x' 1355220000 Tue Dec 11 04:00:00 2012 $ perl -MTime::Piece -E'say $x=localtime->strptime("11 Dec 2012 10:00","%d %b %Y %H:%M")->epoch;say scalar localtime $x' 1355241600 Tue Dec 11 10:00:00 2012 
+3
source share

I suggest you use gmtime instead of localtime .


Does not help:

 >perl -MTime::Piece -E"say Time::Piece->strptime(localtime->epoch,'%s')->epoch;" 1355239881 >perl -MTime::Piece -E"say Time::Piece->strptime(gmtime->epoch,'%s')->epoch;" 1355239881 >perl -E"say time" 1355239881 
-2
source share

All Articles