将记录的日期时间转换为 UNIX 纪元时间戳的 Perl 脚本

Posted

技术标签:

【中文标题】将记录的日期时间转换为 UNIX 纪元时间戳的 Perl 脚本【英文标题】:Perl script to convert logged datetimes to UNIX epoch timestamps 【发布时间】:2013-03-25 17:07:30 【问题描述】:

我有一个日志文件 (datetimes.log),由数十万个时间戳组成:

YYYY-MM-DD HH:mm:ss

例如:

2013-03-28 06:43:51
2013-03-28 06:43:55
2013-03-28 06:44:03
...etc.

我想编写一个简单的 Perl 脚本来输出一个新的 unix_timestamps.log 文件,该文件包含相同的条目,但不是日期时间,而是具有相应的 UNIX 纪元时间戳。对于上面的示例,unix_timestamps.log 文件中将包含以下信息:

1364453031
1364453035
1364453043
...etc.

我唯一能想到的就是perl convert_2_timestamps.pl

#!/usr/bin/perl

use warnings;
use strict;

grep m/_(\d4)(\d\d)(\d\d)/ | POSIX::mktime(?, ?, ?, ?, ?, ?) > unix_timestamps.log

但不确定如何将参数传输到mktime,并且不确定这是否是正确的方法。提前致谢。

【问题讨论】:

您真的希望将其与您之前的问题结合起来吗?由于您并不真正知道自己在做什么,也许您应该告诉我们您最终想要实现的目标是什么。这让事情变得容易多了。 ;-) 使用什么时区?本地? 【参考方案1】:
use strict;
use warnings;
use DateTime::Format::Strptime;


my $parser = DateTime::Format::Strptime->new(
  pattern => '%Y-%m-%d %H:%M:%S',
  on_error => 'croak',
);

while( <DATA> ) 
   my $dt = $parser->parse_datetime($_);
   print $dt->epoch, "\n";


__DATA__
2013-03-28 06:43:51
2013-03-28 06:43:55
2013-03-28 06:44:03

【讨论】:

一些解释会很好。 我已经切换到使用 Time::Piece 来完成类似这样的简单解析任务。您不太可能让人们抱怨他们无法从 CPAN 安装模块 :-) @Dave 那是我的方式,你知道,TIMTOWTDI。但是有机会在不同的场景中安装 CPAN 模块。 哦,当然有!但是我发现,通过使用可用的核心模块,您可以专注于解决问题,而不是完全讨论非管理员如何安装 CPAN 模块。这只是我的实用主义:-) 我同意,避免潜在问题很聪明【参考方案2】:

这是Time::Piece 模块的完美使用,该模块已成为 Perl 发行版的标准部分超过五年。

#!/usr/bin/perl

use strict;
use warnings;
use 5.010;

use Time::Piece;

# Read the data a record at a time. Data ends up in $_.
# N.B. Using built-in DATA filehandle for this demo.
#      In the real world you'd open a separate filehandle.
while (<DATA>) 
  chomp;
  # Create a Time::Piece object using strptime (that's "string
  # parse time") and immediately call the epoch method on the
  # new object to get the value you want.
  say Time::Piece->strptime($_, '%Y-%m-%d %H:%M:%S')->epoch;


__DATA__
2013-03-28 06:43:51
2013-03-28 06:43:55
2013-03-28 06:44:03

【讨论】:

【参考方案3】:

您可以像这样分解 YYYY-MM-DD HH:mm:ss 格式:

my ( $y, $m, @t ) = split /[-: ]+/, $time_str;
my $time = mktime( reverse @t, $m - 1, $y - 1900 );

但你也可以像这样把它放在一个替换中:

s(\d4)-(0?[1-9]\d?)-(0?[1-9]\d?) (0?\d1,2):(0?\d1,2):(0?\d1,2)
    mktime( $6, $5, $4, $3, $2 - 1, $1 - 1900 )
 e;

【讨论】:

【参考方案4】:

试试Date::Parse CPAN 模块。 (http://metacpan.org/pod/Date::Parse)

有了它,你的convert_2_timestamps.pl 就可以了:

#!/usr/bin/perl

use warnings;
use strict;

use Date::Parse;

while (<>) 
  chomp;
  printf("%s\n", str2time("$_ GMT"));

请注意,我必须将 GMT 附加到您的示例输入中才能获得预期的输出。

运行方式:

perl convert_2_timestamps.pl < datetimes.log > unix_timestamps.log

【讨论】:

以上是关于将记录的日期时间转换为 UNIX 纪元时间戳的 Perl 脚本的主要内容,如果未能解决你的问题,请参考以下文章

如何将 13 位 unix 纪元时间格式转换为日期时间?

将 UNIX 纪元转换为日期对象

如何将自纪元以来的 Unix 时间/时间转换为标准日期和时间?

oracle 将 unix 纪元时间转换为日期

将日期、时间和 UTC 偏移值转换为自 unix 纪元以来的毫秒数?

用于将日期和时间列转换为 .csv 中的 unix 时间戳的 Bash 脚本