perl - How to make Time::Piece respect DST when converting localtime to UTC? -
i want convert timestamp localtime gmt. have legacy code "manually" time::local::timelocal()
, gmtime
. works, don't , wanted use time::piece
instead. used this answer (albeit converting other way round, able replace +
-
:-)).
this code:
#!/usr/bin/env perl use strict; use warnings; use time::local; use time::piece; use posix qw(strftime); sub local_to_utc_timelocal { $local_ts = shift; ( $year, $mon, $mday, $hour, $min, $sec ) = ( $local_ts =~ /(\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)/ ); $local_secs = time::local::timelocal( $sec, $min, $hour, $mday, $mon - 1, $year ); return posix::strftime( '%y-%m-%d %h:%m:%s', gmtime($local_secs) ); } sub local_to_utc_timepiece { $local_ts = shift; $local_tp = time::piece->strptime( $local_ts, '%y-%m-%d %h:%m:%s' ); $utc_tp = $local_tp - localtime->tzoffset(); # *** return $utc_tp->strftime('%y-%m-%d %h:%m:%s'); } $local; # dst in effect (april 19 2016): $local = '16-04-19 14:30:00'; print "dst in effect:\n"; printf("utc(%s) = %s (using timelocal)\n", $local, local_to_utc_timelocal($local)); printf("utc(%s) = %s (using timepiece)\n\n", $local, local_to_utc_timepiece($local)); # dst not in effect (feb 19 2016): $local = '16-02-19 14:30:00'; print "dst not in effect:\n"; printf("utc(%s) = %s (using timelocal)\n", $local, local_to_utc_timelocal($local)); printf("utc(%s) = %s (using timepiece)\n", $local, local_to_utc_timepiece($local));
unfortunately time::piece code doesn't seem work wrt dst. i'm living in germany, (spring/summer, dst in effect) utc+2. "april 19 2016" above code gives:
dst in effect: utc(16-04-19 14:30:00) = 16-04-19 12:30:00 (using timelocal) utc(16-04-19 14:30:00) = 16-04-19 12:30:00 (using timepiece)
which correct. "feb 19 2016" (when utc+1) same code gives:
dst not in effect: utc(16-02-19 14:30:00) = 16-02-19 13:30:00 (using timelocal) utc(16-02-19 14:30:00) = 16-02-19 12:30:00 (using timepiece)
that is: gmtime(time::local::timelocal($timestamp))
gives correct 1 hour offset while time::piece
still gives 2 hours offset.
is bug in time::piece
or use wrongly?
i know there plenty of ways convert localtime utc i'd use time::piece
because of simplicity. plus cannot use datetime
because involve deploying on dozen of production machines.
problem 1
localtime
returns now, localtime->tzoffset()
returns offset now. change
my $utc_tp = $local_tp - localtime->tzoffset();
to
my $utc_tp = $local_tp - $local_tp->tzoffset();
however, leaves $utc_tp
flagged localtime, want:
my $utc_tp = gmtime( $local_tp->epoch );
problem 2
despite name, $local_tp
not local time, $local_tp->tzoffset()
zero. change
time::piece->strptime( $local_ts, '%y-%m-%d %h:%m:%s' )
to
localtime->strptime( $local_ts, '%y-%m-%d %h:%m:%s' );
Comments
Post a Comment