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

vle*_*lee 5 perl timezone date

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

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

# Example Input Strings:
my @inputs = (
              'Tue Oct 12 06:31:48 EDT 2010',
              'Tue Oct 12 07:49:54 BST 2010',
             );
Run Code Online (Sandbox Code Playgroud)

我尝试了以下无济于事:

foreach my $input ( @inputs ) {
  my $t = Time::Piece->strptime( $input,
                                 '%a %b %d %T %Z %Y' );
  print $t->cdate, "\n";
}
Run Code Online (Sandbox Code Playgroud)

似乎问题是时区(%Z).另外,Time :: Piece中似乎不存在时区字段,这需要我编写自定义代码以转换为UTC,这似乎是错误的.

上下文:我正在尝试从使用unix date命令获取时间戳的各种源解析旧日志.理想情况下,我想将所有时间戳转换为UTC.

任何帮助将不胜感激.

daw*_*awg 5

关于时区的Perl DateTime 常见问题解答很好地说明了为什么在大多数转换中不能使用EDT和EST.问题是其他国家的东部时区也有相同的3个字母缩写.EST EDT模糊不清,没有其他线索.

您可以查看其他模块,或者假设"EDT"与"EST5EDT"相同,如果这是真的.


Ped*_*lva 5

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

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);
}
Run Code Online (Sandbox Code Playgroud)