Hidden binary 64 bit timestamp offset from GPS era to python datetime object

I'm trying to figure out what, in my opinion, should be an 8-bit / 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 that the value (s?) As a result of t1 and t2 should be offset from GPS_EPOCH. However, I cannot force the result to match the expected datetime result.

I read, and it seems logical that this will be divided into two parts, and one of them can be fractional and other seconds (4 bytes each?). However, I did not find links to temporary formats based on the GPS era.

Any ideas on how this can be converted to the expected result?

+4
source share
3 answers

I have it. You have provided enough examples.

 >>> t1 = "\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) 
+8
source

You can see if your eight bytes encodes a 64-bit integer using the standard struct module:

 >>> import struct >>> number = struct.unpack('q', "\x00\x00\xBF\x13\xDB\x79\xC0\x00") >>> "{:,}".format(number) '54,177,177,364,529,152' 

This is a pretty big whole! But is this related to the era you are listing? Probably not ...

Maybe this is not an integer. I have a raw GPS module that I played with, and its data comes out as serial in NMEA sentences. You can find format information for anyone on the Internet.

+2
source

EDITED

Sorry, this is not a solution , only some starting point , if someone has more time to touch the depth.

The stored "hidden" number for the first date should be:

 import datetime from datetime import datetime, timedelta GPS_EPOCH = datetime(1980, 1, 6) date_1 = datetime(2012,10,04, 01,00,51,759) d=(date_1 - GPS_EPOCH) ( d.days * 24 * 60 * 60 + d.seconds ) * 1000 + d.microseconds ----> 1.033.347.651.759 <---- 

But the number you get decompresses the first hexadecimal data code:

 struct.unpack('q', "\xBF\x13\xDB\x79\xC0\x00\x00\x00" )[0] ----> 826.678.121.407 <---- 

Note that I move \ xBF to the position with the least significant digit. I do this because in your example 1 millisecond is \ xC0 - \ xBF. The least significant digit seems to be \ xBF in the first example.

Then for your sample data, the formula could be:

  milliseconds = ( 1033347651759 - 826678121407 ) + unpack_your_string_with_offset GPS_EPOCH + milliseconds 

Testing with less data ...

 >>> milliseconds = ( 1033347651759 - 826678121407 ) + \ struct.unpack('q', "\xBF\x13\xDB\x79\xC0\x00\x00\x00" )[0] >>> >>> GPS_EPOCH + timedelta( milliseconds = milliseconds) datetime.datetime(2012, 10, 4, 1, 0, 51, 759000) 

Please post more sample data and expected results to test or develop a new formula.

I took the unpacking method from @leon_matthews: +1;)

I hope some solution Raiman finds a solution. I will follow your answer.

+1
source

Source: https://habr.com/ru/post/1438831/


All Articles