不要在 `DateTime::Format::MySQL->parse_datetime` 中使用时区
在做任何与时区相关的事情时,你不应该使用它是有充分理由的。为什么?因为它绝对不支持任何时区。请参阅文档:
所有的解析方法都将返回的 DateTime 对象的时区设置为浮动时区,因为 MySQL不提供时区信息。(来源:MetaCPAN:DateTime::Format::MySQL。)
如果您确实使用它,它将假定您的系统时区为默认值。这可能不是您要转换的时区!(虽然这对很多人都有效,但它只在您的服务器不更改其默认时区时才有效——在那之后,一切都会中断。)
使用 `DateTime->new()`,因为它确实支持时区
使用DateTime
直接提供的构造函数(来源:MetaCPAN:DateTime。):
my $dt = DateTime->new(
year => 1966,
month => 10,
day => 25,
hour => 7,
minute => 15,
second => 47,
nanosecond => 500000000,
time_zone => 'America/Chicago',
);
使用 DateTime 转换时区
您的起始时区是您输入构造函数的任何内容(即,America/Chicago
在上面的示例中)。要将时间转换为结束时区,请使用set_time_zone()
.
工作代码
在下面的代码中,时间从一个时区转换为另一个时区,并且每次都完美地完成此操作,即使您使用 Linux 操作系统为新加坡时间的服务器将纽约时间转换为旧金山时间。
use strict;
use DateTime;
sub convertTimeZonesForTime {
my ($args) = @_;
my $time = $args->{time};
my $date = $args->{date};
my $totimezone = $args->{totimezone};
my $fromtimezone = $args->{fromtimezone};
my $format = $args->{format} || '%H:%M:%S';
my ($year, $month, $day) = map {int $_} split('-', $date);
my ($hour, $minute, $second) = map {int $_} split(':', $time);
$year ||= 1999 if !defined $year;
$month ||= 1 if !defined $month;
$day ||= 1 if !defined $day;
$hour ||= 12 if !defined $hour;
$minute ||= 30 if !defined $minute;
$second ||= 0 if !defined $second;
my $dt = DateTime->new(
year=>$year,
month=>$month,
day=>$day,
hour=>$hour,
minute=>$minute,
second=>$second,
time_zone => $fromtimezone,
);
my $formatter = new DateTime::Format::Strptime(pattern => $format);
$dt->set_formatter($formatter);
$dt->set_time_zone($totimezone);
return "$dt";
}
print(convertTimeZonesForTime({
'totimezone'=>'America/Denver',
'fromtimezone'=>'US/Eastern',
'time'=>'12:30:00',
}));
输出:
10:30:00