Python:读取带有日期/时间的二进制文件

Python:读取带有日期/时间的二进制文件,python,binaryfiles,Python,Binaryfiles,我有一个表示开始时间的二进制文件的一部分 我试图用Python读取文件中的时间/日期值,但遇到了问题 >>>file = open('file1',"rb") >>>data = file.read() >>>data[16:24] b'Q\xca\rk\x9c\xc6\xd7\x88' >>>unpacked, = unpack('<Q', data[16:24]) 986056828426425

我有一个表示开始时间的二进制文件的一部分

我试图用Python读取文件中的时间/日期值,但遇到了问题

>>>file = open('file1',"rb")
>>>data = file.read()
>>>data[16:24]
b'Q\xca\rk\x9c\xc6\xd7\x88'
>>>unpacked, = unpack('<Q', data[16:24])
9860568284264254033
有人知道如何在Python中正确阅读它吗

如果有帮助的话

>>> unpack('q',data[16:24])
(-8586175789445297583,)
>>> unpack('Q',data[16:24])
(9860568284264254033,)
我试着做:

>>> unpacked
9860568284264254033
>>> secs = unpacked / 10.0 **7
>>> secs
986056828426.4253
>>> delta = datetime.timedelta(seconds = secs)
>>> delta
datetime.timedelta(days=11412694, seconds=66826, microseconds=425293)
>>> ts = datetime.datetime(1,1,1) + delta

导致溢出错误:日期值超出范围

我想我已经解决了

从datetime导入datetime,timedelta
时间字节=b'Q\xca\rk\x9c\xc6\xd7\x88'
time_int=int.from_字节(time_字节,“little”)
time\u bin=bin(time\u int)
#删除两个不相关的位并转换为整数个刻度
n_ticks=int(time_bin[:2]+time_bin[4:],2)
秒=n_刻度/1e7
d1=日期时间(1,1,1)
t1=时间增量(秒=秒)
打印(d1+t1)
产出:

2020-03-12 15:45:40.947823
所以它在时区内是正确的

编辑: 要获取实际时区,请再次使用
timedelta

zone_delta=timedelta(小时=-4)
打印(d1+t1+zone_delta)
给予


我们在评论中浏览了很多这方面的信息,但如果评论被删除,这里有一个答案

自2001年1月1日(21世纪初)以来,通过将62个低位编码为记号,将C#datetime对象转换为二进制,并将2个高位编码为位置/种类信息。这意味着我们需要先提取62个低位,然后才能使用它们。然后我们简单地将这些秒转换成一个timedelta,并执行算法来检索python datetime对象

现在这里会有误差,因为我们忽略的种类信息被用来确定时区。您可以更深入地研究这些比特是什么,看看是否可以检索时区以使结果更加一致,但对于这个答案,我没有

unpacked = unpack('<Q', data[16:24])
# 64 bits with two most significant bits as 0 is decimal: 4611686018427387903
# Here I am performing a bitwise mask to keep only the 62 least significant bits.
# I prefer this method in stead of string manipulation from bin() for potential memory efficiency reasons
ticks = unpacked & 4611686018427387903
# There are 10,000,000 ticks in a second
seconds = ticks / 10000000
td = datetime.timedelta(seconds=seconds)
epoch = datetime.datetime(year=1, month=1, day=1)

resultDate = td + epoch

unpack=unpack('您能编辑问题并发布完整的代码并展示您是如何读取文件的吗?从上的C#文档来看,似乎有两个位用于存储位置(种类属性)剩下的62位是21世纪初的节拍数。提取这些节拍数,然后执行一些奇怪的python datetime.timedelta数学,我相信你可以找到答案。我会发布我尝试过的数学,但它弹出错误消息,说OverflowerError:date value out of therange@akb515那个时候lta不正确,快速的健全性检查表明您看到的时间增量大约为31267年。找出用于存储滴答数的62位,确定滴答与秒之间的时间转换,然后对表示2001年1月1日的datetime对象执行时间增量。@Zircoz感谢您的澄清!我刚刚w评论说@akb515提出了相同的解决方案。无论如何,也许有人以后会使用它。对于时区,因为我知道它应该是上午11:45,我该如何更改最后三行。这是4小时的差异,所以在哪里会包括此更改?只是将其添加到解决方案中一个稍微简单一点:
n_ticks=time\u int&0x3fffffffffff
,使用按位
&
清除顶部的两位。十六进制值为
(1我同意这是一个更干净的位。
2020-03-12 11:45:40.947830
unpacked = unpack('<Q', data[16:24])
# 64 bits with two most significant bits as 0 is decimal: 4611686018427387903
# Here I am performing a bitwise mask to keep only the 62 least significant bits.
# I prefer this method in stead of string manipulation from bin() for potential memory efficiency reasons
ticks = unpacked & 4611686018427387903
# There are 10,000,000 ticks in a second
seconds = ticks / 10000000
td = datetime.timedelta(seconds=seconds)
epoch = datetime.datetime(year=1, month=1, day=1)

resultDate = td + epoch