2009-10-29 26 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

相關問題