从 GPS 纪元到 python 日期时间对象的隐蔽二进制 64 位时间戳偏移量



我试图弄清楚我认为应该是 8 字节/64 位时间戳。

import datetime
GPS_EPOCH = datetime.datetime(1980, 1, 6)
t1 = "x00x00xBFx13xDBx79xC0x00" # expected: 2012-10-04 01:00:51.759
t2 = "x00x00xC0x13xDBx79xC0x00" # expected: 2012-10-04 01:00:51.760
t3 = "x00x00xC2x13xDBx79xC0x00" # expected: 2012-10-04 01:00:51.763
t4 = "x00x00x80xE7xFBx79xC0x00" # expected: 2012-10-04 01:45:40.960

我认为t1t2产生的值应该从GPS_EPOCH中抵消。但是,我似乎无法获得与预期结果日期时间匹配的结果。

我一直在阅读,这似乎合乎逻辑地将其分为两部分,一部分可能是小数部分,另一部分可能是秒(每部分 4 字节? 但是,我还没有找到任何基于 GPS 纪元的时间戳格式的参考。

任何想法如何转化为预期结果?

我有。你提供了足够多的例子。

>>> t1 = b"x00x00xBFx13xDBx79xC0x00" # 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)

把所有的东西放在一起:

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)
您可以使用

标准库的 struct 模块查看您的 8 个字节是否对 64 位整数进行编码:

>>> import struct
>>> number = struct.unpack('q', "x00x00xBFx13xDBx79xC0x00")
>>> "{:,}".format(number)
'54,177,177,364,529,152'

这是一个相当大的整数! 但它与您列出的时代有关吗? 应该不会...

也许它不是一个整数。 我有一个一直在玩的原始GPS模块,它的数据在NMEA句子中是连续的。 您可以在线查找这些格式信息。

已编辑

抱歉,这不是解决方案,如果其他人有更多时间深入接触,只有一些起点

第一个日期存储的"隐藏"数字应为:

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

但是您解压缩的第一个数据十六进制代码的数字是:

struct.unpack('q', "xBFx13xDBx79xC0x00x00x00" )[0]
---->     826.678.121.407   <----

请注意,我将 \xBF 移动到最低有效数字位置。我这样做是因为在您的示例中,1 毫秒是 \xC0 - \xBF。在第一个样本中,最低有效数字似乎是 \xBF。

然后,对于数据样本,公式可以是:

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

使用较少的数据进行测试...

>>> milliseconds =  ( 1033347651759 - 826678121407 ) +  
                    struct.unpack('q', "xBFx13xDBx79xC0x00x00x00" )[0]
>>> 
>>> GPS_EPOCH + timedelta( milliseconds = milliseconds)
datetime.datetime(2012, 10, 4, 1, 0, 51, 759000)

发布更多数据样本和预期结果,以检查或推断新公式。

我从@leon_matthews中采用了解包方法:+1 ;)

我希望一些Raiman家伙能找到解决方案。我会按照你的回答。

最新更新