Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Time::Piece epoch parsing

by vsespb (Chaplain)
on Jul 01, 2016 at 13:45 UTC ( [id://1166994]=perlquestion: print w/replies, xml ) Need Help??

vsespb has asked for the wisdom of the Perl Monks concerning the following question:

Why if I parse epoch value (%s), it outputs different epoch time? (I have system timezone Europe/Moscow).
use strict; use warnings; use Time::Piece; my $t = Time::Piece->new(); print Time::Piece->VERSION, "\n"; $t = $t->strptime( $ARGV[0], '%s' ); print "Input $ARGV[0]\n"; print "Output ".$t->epoch(), "\n"; print $t, "\n"; print $t->strftime, "\n";
1.30 Input 1415998800 Output 1415988000 Fri Nov 14 21:00:00 2014 Fri, 14 Nov 2014 21:00:00 MSK
Is this a bug in Time::Piece or I misunderstand how it should work?

also input 1415998800 is "Fri, 14 Nov 2014 21:00:00 GMT", so output "Fri, 14 Nov 2014 21:00:00 MSK" is wrong too.

Replies are listed 'Best First'.
Re: Time::Piece epoch parsing
by Marshall (Canon) on Jul 01, 2016 at 16:04 UTC
    runrig++ idea looks right. in OP's code, strptime() interprets the input value as a local time. It then subtracts 3 hours to get the output GMT epoch value.

    I ran this code myself and in my time zone, I get the following result:

    use strict; use warnings; use Time::Piece; my $x = '1415998800'; my $t = Time::Piece->new(); print Time::Piece->VERSION, "\n"; $t = $t->strptime( $x, '%s' ); print "Input $x\n"; print "Output ".$t->epoch(), "\n"; print $t, "\n"; print $t->strftime, "\n"; print "daylight savings flag is:",$t->daylight_savings, "\n"; __END__ 1.30 Input 1415998800 <- interpreted as a local time Output 1416027600 <- 8 hours ahead of input Fri Nov 14 21:00:00 2014 Fri, 14 Nov 2014 21:00:00 Pacific Standard Time daylight savings flag is:0
    What I don't understand is why Time::Piece doesn't know that currently Daylight Savings time is in effect? Right now, GMT is only 7 hours ahead of us instead of 8. I am on Windows and my clock in taskbar shows the right time (PSDT).

    Update: I found out that if you call strptime() as a Class method, instead of as an object method, GMT is assumed. Otherwise the object's timezone is used, i.e. changing:

    $t = $t->strptime( $x, '%s' ); ## to: $t = Time::Piece->strptime( $x, '%s' );
    produces:
    1.30 Input 1415998800 Output 1415998800 Fri Nov 14 21:00:00 2014 Fri, 14 Nov 2014 21:00:00 UTC daylight savings flag is:0
      strptime() interprets the input value as a local time. It then subtracts 3 hours to get the output GMT epoch value.

      But why in the first place epoch interpreted as "local time"? Epoch is not about timezones. It cannot be local or GMT..

      From man 7 strptime:

      %s The number of seconds since the Epoch, 1970-01-01 00:00:00 +0000 (UTC). Leap seconds are not counted unless leap second support is available.

      and number of seconds since specific moment of time is always same, independent of timezone

      I found out that if you call strptime() as a Class method, instead of as an object method, GMT is assumed
      Ok, behaviour differs. Great finding! thx
        I have no idea why this thing does what it does. But my "reverse engineering" appears to be sound:
        (1415988000-1415998800)/60/60= -3 hrs Moscow time to GMT (1416027600-1415998800)/60/60= +8 hrs California time to GMT
        Almost all my work is done in GMT. I seldom convert to local time. This module appears to be pretty stupid about local time. I think there are much better modules for that task with better knowledge about time zones and daylight savings time. The good modules will even know about places that are 30 minutes instead of an hour off from the adjacent time zone.
Re: Time::Piece epoch parsing
by runrig (Abbot) on Jul 01, 2016 at 15:26 UTC
    My man pages say that %e is the same as %d, i.e., the day of the month.(Update: I need glasses...OP is %s not %e) That said, you don't have to 'parse' an epoch, you just pass it to new():
    use strict; use warnings; use Time::Piece; my $e = time(); my $t = Time::Piece->new($e); print Time::Piece->VERSION, "\n"; print "Input $e\n"; print "Output ".$t->epoch(), "\n"; print $t, "\n"; print $t->strftime, "\n";
      I am not looking for way to parse epoch, I am investigating why strptime with %s works wrong.
        I am not looking for way to parse epoch, I am investigating why strptime with %s works wrong.
        Um, strptime is a function that (I think) is short for string-parse-time, and %s is the field descriptor for epoch, so I think you are trying to parse an epoch, whether you realize it or not.

        I am not looking for way to parse epoch, I am investigating why strptime with %s works wrong.

        Look at the source, IIRC its a call to the underling C Runtimes strptime function, they're not all the same

Re: Time::Piece epoch parsing
by choroba (Cardinal) on Jul 04, 2016 at 06:21 UTC
    As documented in Time::Piece, strptime is a class method. The problem is caused by calling it as an instance method instead.
    #! /usr/bin/perl use warnings; use strict; use Time::Piece; print 'Time::Piece'->VERSION, "\n"; my $t = 'Time::Piece'->strptime($ARGV[0], '%s'); print "Input $ARGV[0]\n"; print "Output ", $t->epoch(), "\n"; print $t, "\n"; print $t->strftime('%a %b %d %T %Y'), "\n";

    Test run:

      Indeed. Thanks!
Re: Time::Piece epoch parsing
by pme (Monsignor) on Jul 01, 2016 at 14:27 UTC
    Hi vsespb,

    strptime() called from language C gives the very same result.

    /* cc -Wall -g strp.c -o strp */ #define _XOPEN_SOURCE #include <time.h> #include <stdio.h> int main(int argc, char *argv[]) { struct tm tm; char *c; c = strptime(argv[1], "%s", &tm); printf("%s", asctime(&tm)); return 0; }
    Run:
    $ TZ=MSK ./strp 1415998800 Fri Nov 14 21:00:00 2014

      Not really:

      $ TZ=Europe/Moscow ./strp 1415998800 Sat Nov 15 00:00:00 2014

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1166994]
Front-paged by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others lurking in the Monastery: (4)
As of 2024-04-16 16:32 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found