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

6

这是如何在Perl中优雅地打印RFC822格式的日期?的一个分支,但是针对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而不是我期望的-0500,但我猜这是由于DST计算或其他原因?我主要是想得到一个合理的近似值,但我无法弄清楚为什么mktime()会与DST有关?
更新:
发现tzoffset()如果手动强制关闭DST,则在DST方面可能更加“稳定”。
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);
}

无论您是否处于夏令时,这种方法都将始终返回-0500,这是您从%z中想要的内容。
1个回答

5

我认为你得到前者的原因是:

  1. %z 是Linux特有的。
  2. 在Windows上,它会忽略大小写并选择大写字母Z。

来自manpage:

%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的情况下支持它。

我认为你是对的,但我只是希望得到一些像样的东西... 我确实注意到了%Z与%z之间的区别,我觉得这有点讽刺,因为Windows在任何地方都是大小写敏感的,为什么不是strftime()格式字符串呢?</sarcasm> - dlamotte

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接