Как изменить часовой пояс значения datetime в Perl?

С помощью этой функции:

perl -e 'use Time::Local; print timelocal("00","00","00","01","01","2000"),"n";'

он вернет эпох-но только в GMT-если я хочу получить результат в GMT+1(который является локальным временем систем (TZ)), что мне нужно изменить?

заранее спасибо,

Андерс

6 ответов


существует только одно стандартное определение для epochtime, основанное на UTC, а не разные эпохи для разных часовых поясов.

Если вы хотите найти смещение между gmtime и localtime используйте

use Time::Local;
@t = localtime(time);
$gmt_offset_in_seconds = timegm(@t) - timelocal(@t);

use DateTime;
my $dt   = DateTime->now;
$dt->set_time_zone( 'Europe/Madrid' );

вам просто нужно установить часовой пояс. Попробуйте:

env TZ=UTC+1 perl -e 'use Time::Local; print timelocal("00","00","00","01","01","2000"),"\n";'

Time::Local::timelocal обратное localtime. Результат будет в местное время вашего хоста:

$ perl -MTime::Local -le \
    'print scalar localtime timelocal "00","00","00","01","01","2000"'
Tue Feb  1 00:00:00 2000

вы хотите gmtime, что соответствует localtime?

$ perl -MTime::Local' -le \
    'print scalar gmtime timelocal "00","00","00","01","01","2000"'
Mon Jan 31 23:00:00 2000

вы хотите, чтобы это было наоборот,localtime, что соответствует gmtime?

$ perl -MTime::Local -le \
    'print scalar localtime timegm "00","00","00","01","01","2000"'
Tue Feb  1 01:00:00 2000

хотя Time:: Local является разумным решением, Вам может быть лучше использовать более современный объектно-ориентированный модуль DateTime. Вот пример:

use strict;
use DateTime;
my $dt = DateTime->now;
print $dt->epoch, "\n";

для часовых поясов можно использовать модуль DateTime::TimeZone.

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:

DateTime


другой пример, основанный на 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