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

发布于 2024-12-03 11:07:31 字数 298 浏览 0 评论 0原文

我需要找出给定地点的当地时间。我有该位置的 GMT/UTC 偏移量。我试图通过获取该时区中设置的截止日期之间的差异来获取持续时间,以在该特定时区中达到截止日期时触发发送电子邮件。

例如,如果西雅图的截止日期设置为 2011 年 9 月 10 日 12:00:00 GMT -7:00,如果我现在在英国,我需要计算西雅图现在的时间,给定 GMT 偏移量 -7:00 一旦我得到我可以计算差异,如果差异为 0,那么我会发送一封电子邮件,说明截止日期已到。

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

请帮忙。

谢谢, 苏尼尔

I need to find out what is local time at a given location. I have GMT/UTC offset for that location. I am trying to get a time duration by taking a difference between deadline set in that time zone to trigger emails being sent out when deadline is met in that perticular time zone.

Ex.If deadline is set in Seattle to be Sept 10, 2011 12:00:00 GMT -7:00 now if I am in UK I need to calculate what time is now in Seattle given GMT offset -7:00 once I get that I can calculate the difference if the difference is 0 then I will sent out an email saying deadline is met.

How can I do the time calculation part in Perl?

Please help.

Thanks,
Sunyl

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

习ぎ惯性依靠 2024-12-10 11:07:31

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

Create a DateTime object, and compare it to DateTime->now. The DateTime object is aware of the time zone associated with the timestamp therein, so it can do what you want with no fuss.

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";

Above, I assumed you miscopied the date format. If the date is formatted as you provided, you won't be able to use Strptime because the timestamp uses nonstandard names for the months and a nonstandard format for the offset.

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),
);
在巴黎塔顶看东京樱花 2024-12-10 11:07:31

您可以使用 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;

You can use the DateTime module from CPAN to do time calculations.

http://metacpan.org/pod/DateTime

It's got time zone stuff that you can leverage as well. Should be pretty straight forward as the documentation is pretty clear.

Specifically,

$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.

Hope that helps!

Edit:

Also this is probably important/will make life easier,

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文