我有具有时间戳的日志文件,例如:
Fri Nov 30 10:19:35:152.92 PST 2012
Fri Nov 30 10:19:35:228.8 PST 2012
or even:
Thu Nov 29 14:20:58:3.44 PST 2012
Fri Nov 30 10:27:50:742 PST 2012
我对 Perl 很陌生,但这里的每个人都在使用它,所以我正在努力快速学习它(刚刚开始这项工作)。我需要能够比较时间戳(我正在合并时间可能重叠的日志文件,并且需要在结果文件中连续的所有时间戳)。这是我提取时间并将其格式化为我可以比较的字符串的子例程:
my %months = ( 'Jan'=>1, 'Feb'=>2, 'Mar'=>3, 'Apr'=>4, 'May'=>5, 'Jun'=>6, 'Jul'=>7,
'Aug'=>8, 'Sep'=>9, 'Oct'=>10, 'Nov'=>11, 'Dec'=>12);
sub to_comparable {
my $date = shift;
my ($mmm, $d, $H, $M, $S, $mils, $fra, $tz, $Y) = $date =~
m{^<\w{3} (\w{3}) (\d{1,2}) (\d{1,2}):(\d{1,2}):(\d{1,2}):(\d{1,3})[.]{0,1}(\d{0,2}) (\w{3}) (\d{4})>}
or return undef;
if ($mils eq "") { $mils = 0; }
if ($fra eq "") { $fra = 0; }
my $m = $months{$mmm};
return sprintf('%04d%02d%02d%02d%02d%02d%03d%02d',$Y,$m,$d,$H,$M,$S,$mils,$fra);
}
只要时间戳都来自同一个时区,这就可以正常工作。但是,我想确保它们适用于与标准时间和夏令时的更改重叠的日志(或者如果我从其他时区获取日志)。我想也许 DateTime 包可以解决问题,但我对如何使用时区来获得可比较的时间感到困惑。除了用于时区的内容外,我可以创建一个日期/时间对象。在我的测试中,我在映射月份后添加了以下内容:
my $ns = sprintf('%03d.%02d',$mils,$fra);
$ns *= 1000;
my $dt = DateTime->new(
year => $Y,
month => $m,
day => $d,
hour => $H,
minute => $M,
second => $S,
nanosecond => $ns,
time_zone => "$tz",
);
这会导致错误“无效偏移:PST”。我找到了注释:“强烈建议您不要将这些名称用于显示以外的任何事情。这些名称不是官方的,其中许多只是奥尔森数据库维护者的发明。而且,这些名称不是唯一的。例如,在 -0500 和 +1000/+1100 处都有一个“EST”。和其他地方:“时区的短名称不是唯一的,因此任何从这样的名称确定实际时区的尝试都涉及猜测。请改用长名称。”
我无法控制给定的时区显示,所以我现在不知道该怎么做。如果我使用“PST8PDT”或“America/Los_Angeles”,如何指示给定时间是标准时间还是夏令时?美国的时区是否可以转换为 DateTime 将接受的时区?有人可以帮我解决这个问题吗?我合并日志文件的看似微不足道的项目一直在进行,我的老板认为我是个白痴。:-(