使用DateTime :: Format :: Strptime移动时区

时间:2015-12-07 14:29:24

标签: perl timezone

请先查看Perl代码。

use DateTime::Format::Strptime;

my $strp = DateTime::Format::Strptime->new(
    pattern => '%Y-%m-%d%H:%M:%S',
);
my $dt = $strp->parse_datetime('2015-07-0611:21:33');

print $dt->epoch, "\n";
print $dt->ymd . ' ' . $dt->hms, "\n";
$dt->set_time_zone( 'local' );
print $dt->epoch,"\n";
print $dt->ymd . ' ' . $dt->hms, "\n";

输出:

1436181693
2015-07-06 11:21:33
1436149293
2015-07-06 11:21:33

我想更改时区。

$dt->epoch更改,但$dt->ymd$dt->hms未更改。

我不知道为什么。

请帮帮我。

1 个答案:

答案 0 :(得分:7)

您正在处理浮动时区。

my $dt = $strp->parse_datetime('2015-07-0611:21:33');
say $dt->time_zone;

在我的机器上,它位于 Europe / Berlin 时区,这给出了:

DateTime::TimeZone::Floating=HASH(0x1dd1f68)

DateTime docs有这样说:

  

如果旧时区是浮动时区,则除了考虑闰秒之外,不会对当地时间进行调整。如果新时区是浮动的,则调整UTC时间以保持当地时间不受影响。

我机器上其余程序的输出是:

1436181693
2015-07-06 11:21:33
1436174493
2015-07-06 11:21:33

两个纪元值之间的差异是7200。那是两个小时。

$dt->set_time_zone( 'local' );
say $dt->time_zone;
# DateTime::TimeZone::Europe::Berlin=HASH(0x27dc1d8)

让我们来看看时区的事情。当DateTime对象中没有给出时区时,使用DateTime::TimeZone::Floating。将时区设置为local会更新对象。

它假设浮动时区是UTC时间,因此它将UTC增加一小时到柏林,另一个因为那时柏林有夏令时。

这有点理论上的。关键是,将time_zone设置为a  DateTime对象不会立即转换它。如果您以浮动时区开头,则会更改附加到日期和时间的时区。这是一个区别。只有当你再次打电话时,它才会转换。

use strict;
use warnings;
use feature 'say';
use DateTime::Format::Strptime;

my $strp = DateTime::Format::Strptime->new(
                    pattern => '%Y-%m-%d%H:%M:%S',
                );

my $dt = $strp->parse_datetime('2015-07-0611:21:33');
say $dt->time_zone;
say $dt->epoch;
say $dt;

say "changing to UTC...";
$dt->set_time_zone( 'UTC' );
say $dt->time_zone;
say $dt->epoch;
say $dt;

say "changing to local...";
$dt->set_time_zone( 'local' );
say $dt->time_zone;
say $dt->epoch;
say $dt;

这是我机器上的输出:

DateTime::TimeZone::Floating=HASH(0x1887f98)
1436181693
2015-07-06T11:21:33
changing to UTC...
DateTime::TimeZone::UTC=HASH(0x177dfd8)
1436181693
2015-07-06T11:21:33
changing to local
DateTime::TimeZone::Europe::Berlin=HASH(0x19a84c0)
1436181693
2015-07-06T13:21:33

如您所见,第一个set_time_zone使得DateTime对象不再处于浮动时区。第二个调用从一个实际时区转换为另一个,时间会发生变化。