perl - 为什么对于英国夏令时间之外的欧洲/伦敦日期,DateTime::Format::W3CDTF 返回 0?

标签 perl datetime timezone

自从上周英国夏令时结束以来,我的应用程序就发现了一个非常有趣的错误。这是一个单独的 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 库中的错误吗?

最佳答案

看看 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 codepath 被命中,我猜在 Perl 中这意味着隐式返回 nil。我认为这个场景就是我的示例脚本所遇到的情况 - “欧洲/伦敦”在技术上不是 UTC,但它的偏移量仍然为 0。

更新

经过更多研究后,我发现同样的错误 has already been reported (2年前!)。该错误报告包含一个似乎可以解决该问题的补丁(尽管我还没有亲自测试过)。

更新2

修复此问题 has been released

关于perl - 为什么对于英国夏令时间之外的欧洲/伦敦日期,DateTime::Format::W3CDTF 返回 0?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1647209/

相关文章:

perl - 在 Raku 中使用 Perl 5 模块 Data::Printer 的 `show_tied` 选项时,如何关闭它?

c# - 如何检查特定时间是否已过

python - 在python中将山区标准时间转换为东部标准时间

timezone - 是否有信誉良好的来源提供 UN/LOCODE 到奥尔森时区的映射?

perl - 如何在调试时恢复全局变量 $1、$2、$3?

regex - Perl 和 Regex - 从 .csv 解析值

perl - Perl CPAN 模块的依赖问题

python - 如何将 Pandas DateTime Quarter 对象转换为字符串

powershell - 如何基于另一个格式化的时间戳生成时间戳

php - Symfony 2.7 : default timezone not set, 导致 fatal error