2009-10-29 90 views
2

自英国夏令时上周在英国结束以来,我的应用程序一直在看到一个非常有趣的bug。下面是一个孤立的Perl脚本,这表明该问题:为什么DateTime :: Format :: W3CDTF在英国夏令时之外的欧洲/伦敦日期返回0?

#!/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库中的一个错误吗?

回答

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是假的,但$dt->offset()为0,则既不存在return代码路径正在热播,我猜想在Perl中意味着一个零隐含返回。我认为这情景是我的示例脚本打 - “欧洲/伦敦”在技术上并不UTC,但它仍然有0.1

UPDATE

偏移一点更多的研究,我发现后这同样的错误has already been reported(2年前!)。该错误报告包括一个看起来可以解决问题的补丁(尽管我没有亲自测试过)。

UPDATE 2

一种用于此has been released

+3

一个perl子的返回值修复程序是最后一个表达式的计算的值,在这种情况下是'$ offset'(从'如果(我的$ offset = $ dt-> offset())')或者'0'。 – Ether 2009-10-30 02:33:35

相关问题