自上周英国夏令时在英国结束以来,我的应用程序一直在看到一个非常有趣的错误。这是一个孤立的Perl脚本,它演示了这个问题:
#!/usr/bin/perl
use strict; use warnings;
use DateTime::Format::W3CDTF;
use DateTime::Format::ISO8601;
my $tz = 'Europe/London';
sub print_formatted_date {
my $date = shift;
my $tz_date = DateTime::Format::ISO8601->new->parse_datetime( $date );
$tz_date->set_time_zone( $tz );
print "tz_date: $tz_date\n";
$tz_date->set_formatter( DateTime::Format::W3CDTF->new );
print "tz_date with W3C formatter: $tz_date\n";
}
print_formatted_date( '2009-10-25' );
print "\n";
print_formatted_date( '2009-10-26' );
这个输出是:
tz_date: 2009-10-25T00:00:00
tz_date with W3C formatter: 2009-10-25T00:00:00+01:00
tz_date: 2009-10-26T00:00:00
tz_date with W3C formatter: 0
请注意,对于超出BST的日期,W3C格式化程序将它们渲染为“0”。
这对我来说是个问题,因为我们使用的第三方库在SOAP调用期间使用DateTime :: Format :: W3CDTF来格式化参数。由于格式化失败,因此调用失败。
任何人都有线索吗?我不是Perl大师所以任何帮助都会非常感激。这可能是DateTime :: Format :: W3CDTF库中的错误吗?
答案 0 :(得分:3)
看看W3CDTF的实现,我认为这实际上可能是库中的一个错误:
sub format_datetime
{
my ( $self, $dt ) = @_;
my $base = sprintf( '%04d-%02d-%02dT%02d:%02d:%02d',
$dt->year, $dt->month, $dt->day,
$dt->hour, $dt->minute, $dt->second );
my $tz = $dt->time_zone;
return $base if $tz->is_floating;
return $base . 'Z' if $tz->is_utc;
if (my $offset = $dt->offset()) {
return $base . offset_as_string($offset );
}
}
请注意,如果$tz->is_utc
为false,但$dt->offset()
为0,那么没有return
代码路径被命中,我猜在Perl中意味着隐式返回了一个nil。我认为这种情况是我的示例脚本所针对的 - “欧洲/伦敦”在技术上不是UTC,但它的偏移量仍为0。
<强>更新强>
经过一番研究后,我发现了同样的错误has already been reported(2年前!)。错误报告包含一个似乎可以解决问题的补丁(虽然我没有亲自测试过。)
更新2
的修复程序