我正在尝试使用 DateTime::Format::Strptime
来解析一些日期/时间,但我似乎无法让它解析闰秒的日期/时间(例如,2012-06-30T23:59:60UTC)。文档称它支持长达 60 秒的闰秒。我做错了什么?
这是我的代码:
use DateTime;
use DateTime::TimeZone;
use DateTime::Format::Strptime;
my $utc = DateTime::TimeZone->new(name => 'Etc/UTC');
my $ymdhms_parser = DateTime::Format::Strptime->new(pattern => '%F %T',
locale => 'en_US',
time_zone => $utc,
strict => 1,
on_error => 'croak');
my $date = '2012-06-30 23:59:60';
print "date: $date\n";
my $dt = $ymdhms_parser->parse_datetime($date);
print "dt: $dt\n";
print "tz: ",$dt->time_zone,"\n";
我得到的输出是:
date: 2012-06-30 23:59:60
Parsed values did not produce a valid date at /path/to/test.pl line 14.
版本:
DateTime 1.52
DateTime::LeapSecond 1.52
DateTime::Format::Strptime 1.77
最佳答案
以下内容按预期工作:
my $dt = DateTime->new(
year => 2012,
month => 6,
day => 30,
hour => 23,
minute => 59,
second => 60,
time_zone => $utc,
);
但是,对 parse_datetime
的调用实际上执行了以下操作:
my $dt = DateTime->new(
year => 2012,
month => 6,
day => 30,
hour => 23,
minute => 59,
second => 60,
time_zone => 'floating',
);
$dt->set_time_zone($utc);
上述结果导致 DateTime->new
抛出异常,从而导致收到错误消息。
但我不能责怪 DateTime::Format::Strptime。
在正在解析的字符串中找到的时区(例如,如果使用 %z
)将传递给 ->new
,并将时区传递给构造函数被传递到->set_time zone
。这允许在两个地方都指定时区时发生时区转换。
例如,假设输入为 2020-03-25T00:00:00-05:00
(注意偏移量)。假设您向构造函数传递了 time_zone => 'UTC'
和适当的模式。生成的 DateTime 对象将是 UTC 凌晨 5 点,而不是午夜 UTC-05:00。这很好。
有趣的是,可以使用 60
秒的 float 时区创建 DateTime 对象。
$ perl -MDateTime -e'
CORE::say
DateTime
->new(
year => 2012,
month => 6,
day => 30,
hour => 23,
minute => 59,
second => 60,
time_zone => "UTC",
)
->set_time_zone("floating");
'
2012-06-30T23:59:60
但是 DateTime 与允许它不一致。
$ perl -MDateTime -e'
CORE::say
DateTime
->new(
year => 2012,
month => 6,
day => 30,
hour => 23,
minute => 59,
second => 60,
time_zone => "floating",
);
'
Invalid second value (60)
at -e line 1.
<小时/>
作为解决方法,请在正在解析的数据中包含时区。
my $ymdhms_parser = DateTime::Format::Strptime->new(
pattern => '%F %T%z',
locale => 'en_US',
strict => 1,
on_error => 'croak',
);
my $dt = $ymdhms_parser->parse_datetime($date.'Z');
关于perl - 如何获取 DateTime::Format::Strptime 来解析闰秒的日期/时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60836745/