Perl: Decoding timestamp in binary

I have a fixed width binary that I am decoding. One of the fields is a timestamp. It is 5 bytes long and formatted SS SS SS SS MS

. The first four bytes represent the seconds from 2000/01/01 00:00:00 data, and the byte MS

provides more precision by representing the number of 10ms interval in the second (values ​​range from 0 to 99).

The encoding type for this field is binary. For example: response time 2008-4-28 14:42:51.15

, field is being filled 0F A8 9E EB 0F

.

How to parse and convert binary data to timestamp format in Perl?

+3


source to share


2 answers


The module Time::Piece

is suitable for this purpose, and it has been a core module since version 10 of Perl 5, so it shouldn't need to be installed.

It unpack

is also the most convenient way to extract data fields from a string.

It will look like this. I used pack

to create the file content that you described and I had to add fractional seconds to the result separately as it Time::Piece

doesn't support fractional seconds.



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;
}   

      

Output

2008-04-28 14:42:51.15

      

+5


source


use the Time :: Moment CPAN module:



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

      

+4


source







All Articles