在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',
);我尝试了以下方法,但都无济于事:
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。
任何帮助都将不胜感激。
发布于 2010-10-13 14:48:16
如果您知道如何消除TZs的歧义,只需将它们弹出到调度表中:
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);
}发布于 2010-10-13 02:23:15
Perl DateTime FAQ on timezones很好地解释了为什么在大多数转换中不能使用EDT和EST。问题是,其他国家的东部时区也有相同的3个字母的缩写。EST EDT是模棱两可的,没有其他线索。
您可以查看other modules,或者假设"EDT“与"EST5EDT”相同,如果这是真的。
发布于 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
https://stackoverflow.com/questions/3917606
复制相似问题