Как элегантно распечатать формат% z (часовой пояс) в Perl в Windows? - PullRequest
6 голосов
/ 13 апреля 2010

Ответвление Как элегантно напечатать дату в формате RFC822 на Perl? , но для Windows.

На окнах:

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

Урожайность:

    Central Daylight Time

Я ожидал:

    -0500

Как и любой другой в системе Linux. Как я могу получить «-0500» в Windows?

UPDATE:

Это действительно ужасно делать на своем месте? (Предполагается, что мне не разрешено устанавливать 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?

UPDATE:

Выяснилось, что 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);
}

Таким образом, независимо от того, являетесь ли вы DST или нет, он всегда вернет -0500, то есть то, что вы хотите от %z.

1 Ответ

5 голосов
/ 13 апреля 2010

Я думаю, что причина, по которой вы получаете первое, в том, что

  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 , я думаю, он может поддерживать %z на основе POD. У меня не установлено, поэтому не могу проверить

Также DateTime может поддерживать его без DateTime :: Format.

...