如何在Perl中给定GMT / UTC偏移量的时区计算本地时间?

时间:2011-09-07 20:20:52

标签: perl timezone

我需要找出在给定位置的当地时间。我有该位置的GMT / UTC偏移量。我试图通过在该时区设置的截止日期之间的差异来触发在该特定时区内满足截止日期时发送的电子邮件的时间段。

Ex.If截止日期在西雅图设定为2011年9月10日12:00:00格林威治标准时间-7:00现在如果我在英国我需要计算西雅图现在的时间,因为GMT偏移-7:00一旦我得到了,我可以计算差异,如果差异为0,那么我会发送一封电子邮件说满足截止日期。

如何在Perl中进行时间计算?

请帮忙。

谢谢, Sunyl

2 个答案:

答案 0 :(得分:3)

您可以使用CPAN中的DateTime模块进行时间计算。

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.

希望有所帮助!

编辑:

这也许很重要/会让生活更轻松,

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;

答案 1 :(得分:3)

创建一个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),
);