I want to convert the timestamp from localtime to GMT. I have legacy code that does this “manually” using Time::Local::timelocal() and gmtime . It works, but I don’t like it and instead use Time::Piece . I used this answer to do this (although they convert in the other direction, but I was able to replace + with - : -)).
This is my code:
#!/usr/bin/env perl use strict; use warnings; use Time::Local; use Time::Piece; use POSIX qw(strftime); sub local_to_utc_timelocal { my $local_ts = shift; my ( $year, $mon, $mday, $hour, $min, $sec ) = ( $local_ts =~ /(\d\d)-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)/ ); my $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 { my $local_ts = shift; my $local_tp = Time::Piece->strptime( $local_ts, '%y-%m-%d %H:%M:%S' ); my $utc_tp = $local_tp - localtime->tzoffset();
Unfortunately, the Time :: Piece code does not seem to work properly compared to DST. I live in Germany, so at present (spring / summer, summer time) we are UTC + 2. For "April 19, 2016" the 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)
what is right. But for “February 19, 2016” (when we are UTC + 1) the 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 the correct offset at 1 hour, and Time::Piece still gives the offset at 2 hours.
Is this a mistake in Time::Piece or am I using it incorrectly?
I know that there are many ways to convert localtime to UTC, but I would like to use Time::Piece because of its simplicity. Plus, I can’t use DateTime because it involves deploying it to a dozen production machines.