簡體   English   中英

Python:讀取帶有日期/時間的二進制文件

[英]Python: Reading binary file with date/time

我有一個表示開始時間的二進制文件的一部分。

我正在嘗試讀取 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

我已經知道 16-24 位置包含 8 字節大小的 Int64。

在 C# 中,我可以通過執行成功獲得值 {3/12/2020 11:45:40 AM}

var value = _reader.ReadInt64();
sdatetime = DateTime.FromBinary(value);

有誰知道如何在 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

這只是導致溢出錯誤:日期值超出范圍

我想我已經明白了

from datetime import datetime, timedelta

time_bytes = b'Q\xca\rk\x9c\xc6\xd7\x88'
time_int = int.from_bytes(time_bytes, 'little')
time_bin = bin(time_int)

# remove two unrelated bits and convert to integer number of ticks
n_ticks = int(time_bin[:2] + time_bin[4:], 2)
secs = n_ticks / 1e7

d1 = datetime(1, 1, 1)
t1 = timedelta(seconds=secs)
print(d1 + t1)

輸出:

2020-03-12 15:45:40.947823

所以到時區是正確的

編輯:

要獲得實際的時區,請再次使用timedelta

zone_delta = timedelta(hours=-4)
print(d1 + t1 + zone_delta)  

2020-03-12 11:45:40.947830

我們在評論中瀏覽了很多此類信息,但如果評論被刪除/刪除,這里有一個答案。

DateTime.FromBinary()將 C# 日期時間對象轉換為二進制,方法是將 62 個低位編碼為自 2001 年 1 月 1 日(21 世紀開始)以來的刻度,將高 2 個位編碼為位置/種類信息。 這意味着我們需要先提取低 62 位才能使用它們。 然后我們只需將這些秒數轉換為時間增量並執行算術以檢索我們的 python 日期時間 object。

現在這里會有一個誤差范圍,因為我們忽略的 Kind 信息用於確定時區。 您可以更深入地研究 Kind 位是什么,看看您是否可以檢索時區以使您的結果更加一致,但對於這個答案,我沒有。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM