Как рассчитать местное время в часовом поясе с учетом смещения GMT / UTC в Perl? - PullRequest
0 голосов
/ 08 сентября 2011

Мне нужно узнать, какое местное время в данном месте. У меня есть смещение GMT ​​/ UTC для этого местоположения. Я пытаюсь определить продолжительность времени, используя разницу между крайним сроком, установленным в этом часовом поясе, чтобы инициировать отправку писем при наступлении крайнего срока в этом часовом поясе.

Пример. Если в Сиэтле установлен крайний срок 10 сентября 2011 года, 12:00:00 по Гринвичу -7: 00, сейчас, если я нахожусь в Великобритании, мне нужно рассчитать, сколько времени сейчас в Сиэтле, учитывая смещение по Гринвичу -7: 00 как только я получу, что могу вычислить разницу, если разница равна 0, я отправлю электронное письмо с сообщением о крайнем сроке.

Как мне выполнить расчёт времени в Perl?

Пожалуйста, помогите.

Спасибо, Sunyl

Ответы [ 2 ]

3 голосов
/ 08 сентября 2011

Создайте объект DateTime и сравните его с DateTime->now. Объект DateTime знает о часовом поясе, связанном с отметкой времени в нем, поэтому он может делать то, что вы хотите, без суеты.

use strict;
use warnings;
use feature qw( say );

use DateTime qw( );
use DateTime::Format::Strptime qw( );

my $strp = DateTime::Format::Strptime->new(
   pattern  => '%b %d, %Y %H:%M:%S GMT%z',
   locale   => 'en',
   on_error => 'croak',
);

my $target = 'Sep 10, 2011 12:00:00 GMT-0700';

my $target_dt = $strp->parse_datetime($target);
my $now_dt    = DateTime->now();

if ($now_dt > $target_dt) {
   say "It's too late";
} else {
   say "It's not too late";
}

$target_dt->set_time_zone('local');
say "The deadline is $target_dt, local time";

Выше я предположил, что вы неправильно скопировали формат даты. Если дата отформатирована так, как вы указали, вы не сможете использовать Strptime, поскольку временная метка использует нестандартные имена для месяцев и нестандартный формат для смещения.

my @months = qw( ... Sept ... );
my %months = map { $months[$_] => $_+1 } 0..$#months;

my ($m,$d,$Y,$H,$M,$S,$offS,$offH,$offM) = $target =~
      /^(\w+) (\d+), (\d+) (\d+):(\d+):(\d+) GMT ([+-])(\d+):(\d+)\z/
   or die;

my $target_dt = DateTime->new(
   year      => $Y,
   month     => $months{$m},
   day       => 0+$d,
   hour      => 0+$H,
   minute    => 0+$M,
   second    => 0+$S,
   time_zone => sprintf("%s%04d", $offS, $offH * 100 + $offM),
);
3 голосов
/ 08 сентября 2011

Вы можете использовать модуль DateTime из CPAN для расчета времени.

http://metacpan.org/pod/DateTime

У него есть вещи часового пояса, которые вы также можете использовать. Должно быть довольно простым, поскольку документация довольно ясна.

В частности,

$dt->subtract_datetime( $datetime )

This method returns a new DateTime::Duration object representing the difference between the two    dates. The duration is relative to the object from which $datetime is subtracted. For example:

   2003-03-15 00:00:00.00000000
-  2003-02-15 00:00:00.00000000
-------------------------------
= 1 month

Note that this duration is not an absolute measure of the amount of time between the two datetimes, because the length of a month varies, as well as due to the presence of leap seconds.

Надеюсь, это поможет!

Edit:

Также это, вероятно, важно / облегчит жизнь,

use UTC for all calculations

If you do care about time zones (particularly DST) or leap seconds, try to use non-UTC time zones for presentation and user input only. Convert to UTC immediately and convert back to the local time zone for presentation:

my $dt = DateTime->new( %user_input, time_zone => $user_tz );
$dt->set_time_zone('UTC');

# do various operations - store it, retrieve it, add, subtract, etc.

$dt->set_time_zone($user_tz);
print $dt->datetime;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...