Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Covert binary 64-bit timestamp offset from the GPS epoch to python datetime object

I'm trying to figure out what I think should be an 8byte/64-bit timestamp.

import datetime
GPS_EPOCH = datetime.datetime(1980, 1, 6)
t1 = "\x00\x00\xBF\x13\xDB\x79\xC0\x00" # expected: 2012-10-04 01:00:51.759
t2 = "\x00\x00\xC0\x13\xDB\x79\xC0\x00" # expected: 2012-10-04 01:00:51.760
t3 = "\x00\x00\xC2\x13\xDB\x79\xC0\x00" # expected: 2012-10-04 01:00:51.763
t4 = "\x00\x00\x80\xE7\xFB\x79\xC0\x00" # expected: 2012-10-04 01:45:40.960

I believe the value(s?) resulting from t1 and t2 should be offset from the GPS_EPOCH. However, I can't seem to get the result to match the expected result datetime.

I've been reading up and it seems logical that this would be split into 2 parts, with one perhaps being fractional and the other seconds (4 bytes each?). However, I haven't found any reference for timestamp formats that are based off the GPS epoch.

Any ideas how this could be transformed into the expected result?

like image 352
monkut Avatar asked Dec 21 '22 15:12

monkut


1 Answers

I have it. You provided just enough examples.

>>> t1 = b"\x00\x00\xBF\x13\xDB\x79\xC0\x00" # expected: 2012-10-04 01:00:51.759
>>> import struct
>>> import datetime
>>> GPS_EPOCH = datetime.datetime(1980, 1, 6)
>>> t1_unpacked = struct.unpack('<q', t1)[0]
>>> t1_seconds = t1_unpacked // 52428800
>>> t1_us = int(round((t1_unpacked % 52428800) / 52.428800, 0))
>>> GPS_EPOCH + datetime.timedelta(seconds=t1_seconds, microseconds=t1_us)
datetime.datetime(2012, 10, 4, 1, 0, 51, 758750)

Putting it all together:

def gps_time(timestamp):
    unpacked = struct.unpack('<q', timestamp)[0]
    seconds = unpacked // 52428800
    microseconds = int(round((unpacked % 52428800) / 52.428800, 0))
    return GPS_EPOCH + datetime.timedelta(seconds=seconds, microseconds=microseconds)

>>> gps_time(t2)
datetime.datetime(2012, 10, 4, 1, 0, 51, 760000)
>>> gps_time(t3)
datetime.datetime(2012, 10, 4, 1, 0, 51, 762500)
>>> gps_time(t4)
datetime.datetime(2012, 10, 4, 1, 45, 40, 960000)
like image 153
Mark Ransom Avatar answered May 14 '23 16:05

Mark Ransom