How can I change the timezone of a datetime value in Perl?
Question
Using this function:
perl -e 'use Time::Local; print timelocal("00","00","00","01","01","2000"),"\n";'
It will return an epochtime - but only in GMT - if i want the result in GMT+1 (which is the systems localtime(TZ)), what do i need to change?
Thanks in advance,
Anders
Solution
There is only one standard definition for epochtime, based on UTC, and not different epochtimes for different timezones.
If you want to find the offset between gmtime and localtime, use
use Time::Local;
@t = localtime(time);
$gmt_offset_in_seconds = timegm(@t) - timelocal(@t);
OTHER TIPS
use DateTime;
my $dt = DateTime->now;
$dt->set_time_zone( 'Europe/Madrid' );
While Time::Local is a reasonable solution, you may be better off using the more modern DateTime object oriented module. Here's an example:
use strict;
use DateTime;
my $dt = DateTime->now;
print $dt->epoch, "\n";
For the timezones, you can use the DateTime::TimeZone module.
use strict;
use DateTime;
use DateTime::TimeZone;
my $dt = DateTime->now;
my $tz = DateTime::TimeZone->new(name => "local");
$dt->add(seconds => $tz->offset_for_datetime($dt));
print $dt->epoch, "\n";
CPAN Links:
You just need to set the timezone. Try:
env TZ=UTC+1 perl -e 'use Time::Local; print timelocal("00","00","00","01","01","2000"),"\n";'
Time::Local::timelocal
is the inverse of localtime
. The result will be in your host's local time:
$ perl -MTime::Local -le \ 'print scalar localtime timelocal "00","00","00","01","01","2000"' Tue Feb 1 00:00:00 2000
Do you want the gmtime
that corresponds to that localtime
?
$ perl -MTime::Local' -le \ 'print scalar gmtime timelocal "00","00","00","01","01","2000"' Mon Jan 31 23:00:00 2000
Do you want it the other way around, the localtime
that corresponds to that gmtime
?
$ perl -MTime::Local -le \ 'print scalar localtime timegm "00","00","00","01","01","2000"' Tue Feb 1 01:00:00 2000
An other example based on DateTime::Format::Strptime
use strict;
use warnings;
use v5.10;
use DateTime::Format::Strptime;
my $s = "2016-12-22T06:16:29.798Z";
my $p = DateTime::Format::Strptime->new(
pattern => "%Y-%m-%dT%T.%NZ",
time_zone => "UTC"
);
my $dt = $p->parse_datetime($s);
$dt->set_time_zone("Europe/Berlin");
say join ' ', $dt->ymd, $dt->hms; # shows 2016-12-22 07:16:29