首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在Perl中将跨多个时区的unix日期输出转换为UTC?

如何在Perl中将跨多个时区的unix日期输出转换为UTC?
EN

Stack Overflow用户
提问于 2010-10-13 02:01:24
回答 6查看 2.8K关注 0票数 5

在Perl中,如何有效地解析unix的date命令的输出,考虑到时区,并将其转换为UTC?

我在stackoverflow上读到过很多类似的问题,但似乎很少考虑到解析多个时区。相反,他们似乎手动设置时区,并假设它保持固定。

代码语言:javascript
复制
# Example Input Strings:
my @inputs = (
              'Tue Oct 12 06:31:48 EDT 2010',
              'Tue Oct 12 07:49:54 BST 2010',
             );

我尝试了以下方法,但都无济于事:

代码语言:javascript
复制
foreach my $input ( @inputs ) {
  my $t = Time::Piece->strptime( $input,
                                 '%a %b %d %T %Z %Y' );
  print $t->cdate, "\n";
}

似乎问题出在时区(%Z)。此外,time::块中似乎不存在时区字段,这需要我编写自定义代码来转换为UTC,这似乎...不对。

上下文:我正在尝试解析来自各种源的遗留日志,这些源使用unix date命令来获取时间戳。理想情况下,我希望将所有时间戳转换为UTC。

任何帮助都将不胜感激。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-10-13 14:48:16

如果您知道如何消除TZs的歧义,只需将它们弹出到调度表中:

代码语言:javascript
复制
use strict; use warnings;
use DateTime::Format::Strptime ();

my @inputs = (
    'Tue Oct 12 06:31:48 EDT 2010',
    'Tue Oct 12 07:49:54 BST 2010',
);

my %tz_dispatch = (
    EDT => build_parser( 'EST5EDT' ),
    BST => build_parser( '+0100' ),
    # ... etc
    default => build_parser( ),
);

for my $input (@inputs) {
    my ($parser, $date) = parse_tz( $input, %tz_dispatch );
    print $parser->parse_datetime( $date ), "\n";
}

sub build_parser {
    my ($tz) = @_;

    my %conf = (
        pattern   => '%a %b %d %T %Z %Y',
        on_error  => 'croak',
    );
    @conf{qw/time_zone pattern/} = ($tz, '%a %b %d %T %Y')
    if $tz;

    return DateTime::Format::Strptime->new( %conf );
}

sub parse_tz {
    my ($date, %tz_dispatch) = @_;
    my (@date) = split /\s/, $date;

    my $parser = $tz_dispatch{splice @date, 4, 1};

    return $parser
    ? ($parser, join ' ', @date)
    : ($tz_dispatch{default}, $date);
}
票数 5
EN

Stack Overflow用户

发布于 2010-10-13 02:23:15

Perl DateTime FAQ on timezones很好地解释了为什么在大多数转换中不能使用EDT和EST。问题是,其他国家的东部时区也有相同的3个字母的缩写。EST EDT是模棱两可的,没有其他线索。

您可以查看other modules,或者假设"EDT“与"EST5EDT”相同,如果这是真的。

票数 5
EN

Stack Overflow用户

发布于 2011-03-25 09:44:44

如果您使用的是Date:: Time ::Strptime,那么您可以使用%O作为Olson时区名称,并在解析之前进行手动修复。

例如,如果您知道输入中的EDT表示America/New_York,请执行以下操作:

$time_in =~ s{EDT}{America/New_York};

而不是

%a %b %d %T %Z %Y

对于您的时区规范,请使用

%a %b %d %T %O %Y

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3917606

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档