Почему DateTime :: Format :: W3CDTF возвращает 0 для дат Европы / Лондона за пределами Британского летнего времени? - PullRequest
2 голосов
/ 30 октября 2009

Со времени окончания британского летнего времени в Великобритании на прошлой неделе мое приложение обнаружило очень интересную ошибку. Вот отдельный 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'.

Это проблема для меня, потому что сторонняя библиотека, которую мы используем, использует DateTime :: Format :: W3CDTF для форматирования параметров во время вызова SOAP. Поскольку форматирование не выполняется, вызовы не выполняются.

У кого-нибудь есть какие-нибудь подсказки? Я не гуру Perl, поэтому любая помощь будет очень признательна. Может ли это быть ошибкой в ​​библиотеке DateTime :: Format :: W3CDTF?

1 Ответ

3 голосов
/ 30 октября 2009

Глядя на реализацию 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 означает, что nil неявно возвращается. Я думаю, что сценарий - это то, что происходит в моем примере сценария - «Европа / Лондон» технически не является UTC, но он все еще имеет смещение 0.

UPDATE

После нескольких дополнительных исследований я обнаружил, что об этой же ошибке уже сообщалось (2 года назад!). Отчет об ошибке содержит исправление, которое, по-видимому, решает проблему (хотя я лично не проверял это).

ОБНОВЛЕНИЕ 2

Исправление для этого выпущено

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...