我有一个我正在解码的固定宽度二进制文件。其中一个字段是时间戳。它长5个字节,格式为SS SS SS SS MS
。前四个字节表示数据2000/01/01 00:00:00的秒数,MS
字节通过表示秒内的10ms间隔倍数(值范围为0到99)提供更高的准确度。
此字段的编码类型为二进制。例如:答案时间为2008-4-28 14:42:51.15
,字段填充0F A8 9E EB 0F
。
如何在Perl中解析二进制数据并将其转换为时间戳格式?
答案 0 :(得分:5)
Time::Piece
模块适用于此目的,它自Perl 5的第10版以来一直是核心模块,所以它不需要安装。
此外,unpack
是从字符串中提取数据字段的最便捷方式。
看起来像这样。我使用pack
来创建您描述的文件内容,我必须将小数秒附加到结果中,因为Time::Piece
不支持部分秒。
use strict;
use warnings;
use Time::Piece;
my $data = pack 'H*', '0FA89EEB0F';
print decode_timestamp($data), "\n";
sub decode_timestamp {
my ($seconds, $ms) = unpack 'N C', shift;
my $base = Time::Piece->strptime('2000-01-01', '%Y-%m-%d');
($base + $seconds)->strftime('%Y-%m-%d %H:%M:%S') . sprintf '.%02d', $ms;
}
<强>输出强>
2008-04-28 14:42:51.15
答案 1 :(得分:4)
使用Time::Moment CPAN模块:
use Time::Moment;
my $data = 0x0FA89EEB0F;
my $seconds = $data >> 8; # Right shift to remove fractional second.
my $milliseconds = 10 * ( $data & 0xff ); # Hundredths to Milli
my $tm = Time::Moment->new( year => 2000, month => 1, day => 1 ); #base datetime
my $tm2 = $tm->plus_seconds($seconds)->plus_milliseconds($milliseconds);
print $tm2, "\n"; #<-- prints: 2008-04-28T14:42:51.150Z