【问题标题】:How to calculate local time at timezone given GMT/UTC offset in Perl?如何在 Perl 中给定 GMT/UTC 偏移量的时区计算本地时间?
【发布时间】:2011-09-07 20:20:52
【问题描述】:

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

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

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

请帮忙。

谢谢, 苏尼尔

【问题讨论】:

    标签: perl timezone


    【解决方案1】:

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

    【讨论】:

    • @Sunyl,我在第一个 sn-p 中添加了两行。我应该帮助消除你的疑问。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2011-05-01
      • 2016-09-05
      • 1970-01-01
      • 2011-02-18
      • 1970-01-01
      • 2016-04-24
      • 1970-01-01
      • 2012-04-15
      • 1970-01-01
      相关资源
      最近更新 更多