如何在Windows上优雅地在Perl中打印%z(时区)格式?

时间:2010-04-13 18:26:48

标签: windows perl timezone rfc822

How do I elegantly print the date in RFC822 format in Perl?的分支,但特定于Windows。

在Windows上:

    C:\> perl -MPOSIX
    print strftime('%z', localtime()),"\n";

收率:

    Central Daylight Time

我在期待:

    -0500

任何人都会在Linux系统上。如何在Windows上获得“-0500”?

更新:

这样做真的很糟糕吗? (假设我不允许安装DateTime或以任何方式打包它)

C:\> perl -MPOSIX
sub tzoffset {
    my $t = time();
    my $utc = mktime(gmtime($t));
    my $local = mktime(localtime($t));

    return ($local - $utc);
}

sub zformat {
    my ($tzoffset) = @_;
    my $z = '';
    if ($tzoffset < 0) { 
        $z .= '-';
        $tzoffset *= -1;
    } 
    my $hours = floor($tzoffset / 60 / 60);
    my $minutes = $tzoffset - $hours * 60 * 60;
    $z .= sprintf('%02d%02d', $hours, $minutes);
    return $z;
}

print zformat(tzoffset()),"\n";

我注意到的问题是,这会返回-0600 vs -0500(我期望的),但我的猜测是由于DST计算或其他原因?我主要是寻找合适的近似值,但我无法弄清楚为什么mktime()正在使用DST?

更新:

如果只是手动强制关闭DST,{D}表示tzoffset()可以更加“稳定”。

sub tzoffset {
    my $t = time();
    my $utc = mktime(gmtime($t));
    my @tmlocal = localtime($t);
    $tmlocal[8] = 0; # force dst off, timezone specific
    my $local = mktime(@tmlocal);

    return ($local - $utc);
}

这样一来,无论你是不是DST,它总会返回-0500,这是你想要的%z

1 个答案:

答案 0 :(得分:5)

我认为你获得前者的原因是因为

  1. %z是特定于Linux的
  2. 在Windows上,它会以某种方式对您不区分大小写并取代大写字母Z.
  3. 从联系手册:

    %Z    Time zone name or abbreviation, or no bytes if no time
           zone information exists.
    

    此外,“%z”似乎是特定于Linux的 - 在Solaris上也不起作用:

    $ perl -MPOSIX -e 'print strftime("%z", localtime()),"\n"' 
    %z
    $ perl -MPOSIX -e 'print strftime("%Z", localtime()),"\n"' 
    EDT
    

    而在Linux上我得到:

    $ perl -MPOSIX -e 'print strftime("%z", localtime()),"\n"' 
    -0400
    

    如果您安装了DateTime::Format,我认为它可能会基于POD支持%z。我没有安装它所以无法测试

    DateTime可以在没有DateTime :: Format的情况下支持它。