Python 使用从二进制数据字符串中提取日期和时间

Python 使用从二进制数据字符串中提取日期和时间,python,datetime,struct,reverse-engineering,Python,Datetime,Struct,Reverse Engineering,我有一个第三方应用程序,它将时间序列数据存储为压缩二进制文件。我正在尝试创建一个工具来转换存储在此文件中的数据 下面显示的是此数据的快照 41 16 00 00 01 00 D7 11 00 00 01 00 E8 55 A6 20 08 1E D0 08 00 00 00 60 59 D5 86 40 03 E8 F5 2C 22 08 1E D0 08 00 00 00 00 C0 0B 87 40 01 E8 95 B3 23 08 1E D0 08 00 00 00 40 1E 00

我有一个第三方应用程序,它将时间序列数据存储为压缩二进制文件。我正在尝试创建一个工具来转换存储在此文件中的数据

下面显示的是此数据的快照

41 16 00 00 01 00 D7 11 00 00 01 00 E8 55 A6 20 08 1E D0 08 00 00 00 60 59 D5 
86 40 03 E8 F5 2C 22 08 1E D0 08 00 00 00 00 C0 0B 87 40 01 E8 95 B3 23 08 1E 
D0 08 00 00 00 40 1E 00 87 40 01 E8 35 3A 25 08 1E D0 08 00 00 00 60 13 F8 86
40 01 E8 D5 C0 26 08 1E D0 08 00 00 00 40 65 09 87 40 01 E8 75 47 28 08 1E D0 
08 00 00 00 20 8A F6 86 40 01 E8 15 CE 29 08
我知道该数据块对应于以下值

5/13/2013 17:46:11.558  730.6686401
5/13/2013 17:46:14.118  737.46875
5/13/2013 17:46:16.678  736.0147705
我可以提取值:它们的类型为
double
。例如,8个字节
00 00 60 59 D5 86 40
对应于
730.6686401

但是我被如何提取日期时间格式难住了。我知道它埋在这根绳子的某个地方。我怎样才能知道时间是什么格式的

我一直在使用Python的
struct
模块进行类型转换


有人有任何想法吗?< /P> < P>如果你在8个字节之前,立即在一个代码> double < /代码>,并把它看作一个整数(低字节,像double),那么你得到以下数字:

635040567715583464
635040567741183464
635040567766783464
如果将这些数字除以10**7,则日期以秒(和小数秒)为单位。至少它对应于分、秒和秒的分数。在这几个小时里,我犯了两个错误(时区?)。对于完整日期,日期735000(*)对应于2013年5月13日,如下所示。这是从第1年开始的天数:

>>> datetime.date(1,1,1) + datetime.timedelta(735000)
datetime.date(2013, 5, 13)
(*)这是这些数字中的任何一个除以10**7*60*60*24

或在单个步骤中:

>>> x = 635040567715583464 / 10.**7 / 86400
>>> datetime.datetime(1,1,1) + datetime.timedelta(x)
datetime.datetime(2013, 5, 13, 15, 46, 11, 558353)

根据编码为双精度的其他两个浮点值判断,它们之间只有9个字节用于编码日期时间值。此外,序列[08 1E D0 08]重复6次,始终间隔13个字节。这个块中只有3个值,还是有3个以上?@Aruistante:我想说至少有6组。序列[E8 X5]也会重复(在这种情况下是7,但看起来这个块可能会被截断,会有另一个08 1E序列),其中X是一个可变的数字,08 1E序列前2个字节8个字节是否足以存储信息?
datetime
支持序号(
datetime.datetime.fromordinal(735000)
)。因此,数字是从1/1/1 00:00:00纪元而不是UNIX纪元的偏移量?因此
ordinal,rem=divmod(635040567715583464,10**7*86400)
,然后
datetime.datetime.fromordinal(ordinal)+datetime.timedelta(微秒=rem/10.0)
为您提供了正确的日期
datetime.datetime(2013,5,12,15,46,558346)
,大概是UTC。我不确定Ordinal(735000)的确切功能,但结果是休息一天(第12天而不是第13天)。当然最后的结果仍然是2个小时,所以也许我们真的应该使用<代码> FrimDimalAL()/代码>,并认为结果是22或26个小时。如果有一个由一在那里,应该很容易纠正。我挖掘了2小时的差异。这可能是因为数据是在欧洲夏季收集的@Armin Rigo,时间转换是否以UTC表示时间?