4

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

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

我相信由 GPS_EPOCH 产生的值t1并且t2应该从 GPS_EPOCH 偏移。但是,我似乎无法获得与预期结果日期时间相匹配的结果。

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

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

4

3 回答 3

8

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

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

把它们放在一起:

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)
于 2012-10-11T02:52:23.197 回答
2

struct您可以使用标准库的模块查看您的 8 个字节是否编码了 64 位整数:

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

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

也许它不是一个整数。我有一个我一直在玩的原始 GPS 模块,它的数据以 NMEA 语句中的序列形式出现。您可以在网上找到这些格式的信息。

于 2012-10-10T09:04:44.567 回答
1

已编辑

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

第一次存储的“隐藏”号码应该是:

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', "\xBF\x13\xDB\x79\xC0\x00\x00\x00" )[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', "\xBF\x13\xDB\x79\xC0\x00\x00\x00" )[0]
>>> 
>>> GPS_EPOCH + timedelta( milliseconds = milliseconds)
datetime.datetime(2012, 10, 4, 1, 0, 51, 759000)

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

我从@leon_matthews 采取了 unpack 方法:+1 ;)

我希望一些雷曼人能找到解决方案。我会按照你的回答。

于 2012-10-10T09:00:06.247 回答