在 Python 中将 Datetime 写入和读取为二进制格式

2022-01-09 00:00:00 python datetime binary timestamp unpack

问题描述

我想将日期时间列表存储在 Python 中的二进制文件中.

I want to store a list of datetimes in a binary file in Python.

二进制"是指每种数据类型的最佳数字表示.其应用是保存由(unix-timestamp, latitude, longitude,elevation)组成的GPS轨迹点,所以整个结构是little-endianLong,float,float,float",每个值有四个字节.

by "binary" I mean the best digital representation for each datatype. The application for this is to save GPS trackpoints composed by (unix-timestamp, latitude, longitude, elevation), so the whole structure is little-endian "Long, float, float, float", with four bytes to each value.

注意:出于对 Unix 平台的任何影响,我不使用unix-timestamp",而只是作为表示日期时间值的明确方式.

NOTE: I don't use "unix-timestamp" due to any affection to the Unix platform, but only as an unequivocal way to represent the value of a datetime.

目前,我正在像下面的代码那样做,但除了一些我仍在解决的时区混淆(我的时区是 -3)之外,我相信转换为 int 并返回可能不是正确的方法,因为 datetimedatetime64 是 python/numpy 中的本机类型,如果我没记错的话.因此,datetime64 需要 8 个字节,而不是我用于 (long)unix-timestamp 的 4 个字节.

Currently, I am doing like the code below, but besides some timezone confusion that I'm still working out (my timezone is -3), I believe converting to int and back might not be the right way, since datetime and datetime64 are native types in python/numpy, if I'm not mistaken. Thus, a datetime64 would need eight bytes instead of the four I am using for the (long)unix-timestamp.

import datetime
import calendar
import struct

now = datetime.datetime.now()
print now

stamp = calendar.timegm(now.utctimetuple())
print stamp

binarydatetime = struct.pack('<L', stamp)
recoverstamp = struct.unpack('<L', binarydatetime)[0]
print recoverstamp

recovernow = datetime.datetime.fromtimestamp(recoverstamp)
print recovernow

所以主要问题是:这是将原始日期时间转换为二进制并返回的pythonic方法吗?"

So the main question is: "is this the pythonic way to converting naive datetime to binary and back?"

另外一个问题是:如果这段代码中的所有内容都应该是幼稚的,为什么我会有一个时区偏移量?"

And the aditional question is: "if everything in this code is supposed to be naive, why do I have a timezone offset?"

感谢阅读!


解决方案

我找到了一种使用 Unix 时间戳并将其存储为整数的方法.这对我有用,因为我不需要亚秒级分辨率,但我认为长整数可以通过对代码进行一些修改来实现微秒级分辨率.

I have found a way using the Unix timestamp and storing it as an integer. This works for me because I don't need a subsecond resolution, but I think long integers would allow for microsecond resolution with some modifications of the code.

我原来的变化在于将 calendar.timegm 替换为 time.mktime 以及 utctimetuple 替换为 timetuple,让一切都保持幼稚.

The changes from my original consist in replacing calendar.timegm by time.mktime and also utctimetuple by timetuple, to keep everything naive.

这个:

import datetime
import struct
import time

now = datetime.datetime.now()
print now

stamp = time.mktime(now.timetuple())
print stamp

recoverstamp = datetime.datetime.fromtimestamp(stamp)
print recoverstamp

binarydatetime = struct.pack('<L', stamp)
recoverbinstamp = struct.unpack('<L', binarydatetime)[0]
print recoverbinstamp

recovernow = datetime.datetime.fromtimestamp(recoverbinstamp)
print recovernow

返回这个:

2013-09-02 11:06:28.064000
1378130788.0
2013-09-02 11:06:28
1378130788
2013-09-02 11:06:28

由此,我可以轻松地将打包后的 binarydatetime 写入文件,稍后再读取.

From this, I can easily write the packed binarydatetime to file, and read it back later.

相关文章