Какой лучший способ получить смещение UTC в Perl? - PullRequest
9 голосов
/ 27 января 2010

Мне нужно получить смещение UTC текущего часового пояса в Perl кросс-платформенным способом (Windows и различные варианты Unix). Должен соответствовать этот формат:

zzzzzz, что представляет ± чч: мм по отношению к UTC

Похоже, я смогу получить его через strftime(), но это не похоже на согласованность.

Unix:

Input: perl -MPOSIX -e "print strftime(\"%z\", localtime());"
Output: -0700

Windows

Input: perl -MPOSIX -e "print strftime(\"%z\", localtime());"
Output: Mountain Standard Time

Хотя кажется, что Unix дает мне то, что я хочу (или, по крайней мере, что-то близкое), Windows - нет. Я почти уверен, что смогу сделать это с Date::Time или подобным, но мне бы очень хотелось, чтобы у меня не было никаких зависимостей, которые я не могу гарантировать пользователю из-за нашей широкой базы установки.

Я что-то упускаю здесь очевидное? Заранее спасибо.

Ответы [ 4 ]

15 голосов
/ 27 января 2010

Time::Local должен сделать трюк

use Time::Local;
@t = localtime(time);
$gmt_offset_in_seconds = timegm(@t) - timelocal(@t);
0 голосов
/ 21 июня 2011

Вы можете вычислить разницу между localtime($t) и gmtime($t). Вот моя версия, вдохновленная mob s answer :

use strict;
use warnings;    

sub tz_offset
{
    my $t = shift;
    my @l = localtime($t);
    my @g = gmtime($t);

    my $minutes = ($l[2] - $g[2] + ((($l[5]<<9)|$l[7]) <=> (($g[5]<<9)|$g[7])) * 24) * 60 + $l[1] - $g[1];
    return $minutes unless wantarray;
    return (int($minutes / 60), $minutes % 60);
}

push @ARGV, time;
foreach my $t (@ARGV) {
    printf "%s (%d): %+03d%02u\n", scalar localtime($t), $t, tz_offset($t);
}
0 голосов
/ 27 января 2010

" Мне бы очень хотелось, чтобы у меня не было никаких зависимостей, которые я не могу гарантировать пользователю из-за нашей широкой базы установки "

Как насчет включения пользовательской копии Date :: Time (назовем ее My :: Date :: Time) в вашу установку? Например,

use lib 'my-module/dependencies/';

use My::Date::Time;
0 голосов
/ 27 января 2010

Портативный способ - сравнить вывод localtime с gmtime

    $t = time;
    @a = localtime($t);
    @b = gmtime($t);

    $hh = $a[2] - $b[2];
    $mm = $a[1] - $b[1];
    # in the unlikely event that localtime and gmtime are in different years
    if ($a[5]*366+$a[4]*31+$a[3] > $b[5]*366+$b[4]*31+$b[3]) {
      $hh += 24;
    } elsif ($a[5]*366+$a[4]*31+$a[3] < $b[5]*366+$b[4]*31+$b[3]) {
      $hh -= 24;
    }
    if ($hh < 0 && $mm > 0) {
      $hh++;
      $mm = 60-$mm;
    }
    printf "%+03d:%02d\n", $hh, $mm;

Кто-то указывает, что это уже реализовано в модуле где-то в 5, 4, 3, ...

...