Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Re: Time::Piece reversibility

by cguevara (Vicar)
on Jun 18, 2017 at 00:54 UTC ( [id://1193029]=note: print w/replies, xml ) Need Help??


in reply to Time::Piece reversibility

#!/usr/bin/env perl use strict; use warnings; use Test::More ('no_plan'); use Time::Piece; $ENV{'TZ'} = 'America/Los_Angeles'; my $datestr = '2017-06-19 10:07:42-0700'; my $t = Time::Piece->strptime($datestr, '%Y-%m-%d %H:%M:%S%z'); my $u = localtime($t->epoch); is($Time::Piece::VERSION, 1.31); is($t->epoch, 1497892062); is($u->epoch, 1497892062); is($t->tzoffset, 0); is($u->tzoffset, -25200); is($t->strftime, 'Mon, 19 Jun 2017 17:07:42 UTC'); is($u->strftime, 'Mon, 19 Jun 2017 10:07:42 PDT'); is($u->strftime('%Y-%m-%d %H:%M:%S%z'), $datestr);

Replies are listed 'Best First'.
Re^2: Time::Piece reversibility
by choroba (Cardinal) on Jun 18, 2017 at 08:14 UTC
    Interesting. The last question now is how to get "America/Los_Angeles" from "-0700".

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re^2: Time::Piece reversibility
by mla12 (Acolyte) on Jun 18, 2017 at 18:22 UTC

    That's very helpful, @cguevara, thank you.

    So to summarize that result, Time::Piece->strptime always returns a gmtime instance (tzoffset = 0). If you want it in localtime, you need to convert that to a localtime instance. Correct?

    My follow-up question, then, is how to achieve that same result if the time zone is not part of the date string? IOW, I want to parse "2017-06-19 10:07:42" into a localtime Time::Piece instance with epoch seconds of 1497892062 and a tzoffset of -25200.

    I can use Time::Local and do this:

    $ENV{'TZ'} = 'America/Los_Angeles'; my $epoch = timelocal(42,07,10,19,05,2017); print "timelocal epoch: $epoch\n"; print "timelocal date: ", scalar localtime($epoch), "\n";

    Produces:

    timelocal epoch: 1497892062 timelocal date: Mon Jun 19 10:07:42 2017

    But since strptime() always returns gmtime, is there a way to do that with Time::Piece currently? It will be treated as UTC and converting it to a localtime() will offset it by 7 hours (in this case).

    #!/usr/bin/env perl use strict; use warnings; use Time::Local; use Time::Piece; $ENV{'TZ'} = 'America/Los_Angeles'; my $datestr = '2017-06-19 10:07:42'; my $gmt = Time::Piece->strptime($datestr, '%Y-%m-%d %H:%M:%S'); my $local = localtime($gmt->epoch); print "gmt epoch: ", $gmt->epoch, "\n", "local epoch: ", $local->epoch, "\n", "datestr: $datestr\n", "T::P gmt strftime: ", $gmt->strftime, "\n", "T::P local strftime: ", $local->strftime, "\n" ;

    Produces

    gmt epoch: 1497866862 local epoch: 1497866862 datestr: 2017-06-19 10:07:42 T::P gmt strftime: Mon, 19 Jun 2017 10:07:42 UTC T::P local strftime: Mon, 19 Jun 2017 03:07:42 PDT

    Of course you could always append the zone that you want to the date string, but that's cheating ;)

      #!/usr/bin/env perl use strict; use warnings; use Test::More ('no_plan'); use Time::Piece; $ENV{'TZ'} = 'America/Los_Angeles'; my $datestr = '2017-06-19 10:07:42'; my $t = localtime->strptime($datestr, '%Y-%m-%d %H:%M:%S'); is($Time::Piece::VERSION, 1.31); is($t->epoch, 1497892062); is($t->tzoffset, -25200); is($t->strftime, 'Mon, 19 Jun 2017 10:07:42 PDT'); is($t->strftime('%Y-%m-%d %H:%M:%S'), $datestr);

        Thanks again. So localtime()->strptime does behave differently.

        So localtime()->strptime's handling of time zones is the underlying issue. Certainly these two should be equivalent, no?

        #!/usr/bin/env perl use strict; use warnings; use Test::More ('no_plan'); use Time::Piece; $ENV{'TZ'} = 'America/Los_Angeles'; my @tests = ( ['2017-06-19 10:07:42', '%Y-%m-%d %H:%M:%S'], ['2017-06-19 10:07:42-0700', '%Y-%m-%d %H:%M:%S%z'], ); is($Time::Piece::VERSION, 1.31); foreach my $test (@tests) { my ($datestr, $fmt) = @$test; my $t = localtime->strptime($datestr, $fmt); is($t->epoch, 1497892062); is($t->tzoffset, -25200); is($t->strftime, 'Mon, 19 Jun 2017 10:07:42 PDT'); is($t->strftime('%Y-%m-%d %H:%M:%S'), $datestr); }

        Result

        ok 1 ok 2 ok 3 ok 4 ok 5 not ok 6 # Failed test at ./try7 line 22. # got: '1497917262' # expected: '1497892062' ok 7 not ok 8 # Failed test at ./try7 line 24. # got: 'Mon, 19 Jun 2017 17:07:42 PDT' # expected: 'Mon, 19 Jun 2017 10:07:42 PDT' not ok 9 # Failed test at ./try7 line 25. # got: '2017-06-19 17:07:42' # expected: '2017-06-19 10:07:42-0700' 1..9 # Looks like you failed 3 tests of 9.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1193029]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (2)
As of 2024-04-25 23:04 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found