请先查看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
未更改。
我不知道为什么。
请帮帮我。
答案 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对象不再处于浮动时区。第二个调用从一个实际时区转换为另一个,时间会发生变化。