【问题标题】:Write and read Datetime to binary format in Python在 Python 中将 Datetime 写入和读取为二进制格式
【发布时间】:2013-09-02 05:16:16
【问题描述】:

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

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

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

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

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方法吗?”

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

感谢阅读!

【问题讨论】:

  • 在这里定义“二进制”。您希望与其他哪些软件进行互操作?以二进制格式存储日期时间本身并没有标准,大多数软件都会选择自己喜欢的格式,这可能基于也可能不基于 UNIX 时代。
  • @MartijnPieters 我希望以独立于语言和平台的方式将数据类型写入文件。查看我的编辑!
  • 将 sqlite 数据库视为一种可移植的二进制格式,以使用其原生 datetime 类型存储 gps 轨迹点作为 UTC(或 gps)时间。
  • 这个问题你解决了吗? (从字节“读取”时间戳)。我也有。
  • @garrythehotdog 在下面看到我自己的答案

标签: python datetime binary timestamp unpack


【解决方案1】:

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

我原来的变化在于将calendar.timegm 替换为time.mktimeutctimetuple 替换为timetuple,以保持一切幼稚。

这个:

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 写入文件,稍后再读取。

【讨论】:

  • 对我来说,微秒很重要,使用长整数是什么意思?
  • @le_lemon unix 时间戳太大而无法存储在 32 位有符号整数上,因此为了以微秒分辨率正确存储它,您需要更大的数字格式,例如 uint、long、甚至更好的 ulong(无符号 64 位整数)。请检查这一切,也许我刚才说的并不完全正确,但这些是原则。
  • @heltonbiker 看起来 stamp 需要在打包前转换为整数:binarydatetime = struct.pack('&lt;L', int(stamp))
【解决方案2】:

到目前为止,最简单的解决方案是使用 Temporenc:http://temporenc.readthedocs.org/

它负责所有的编码/解码,并允许您将 Python 日期时间对象写入文件:

now = datetime.datetime.now()
temporenc.pack(fp, now)

要读回它,这就足够了:

dt = temporenc.unpack(fp)
print(dt)

【讨论】:

    【解决方案3】:

    如果你想将一个对象保存为二进制文件,你可以考虑pickle

    据我所知,它写的是字节流,所以是二进制的,但结果是

    Python 特定

    另外,我认为它应该适用于日期时间。

    你会得到这个来保存:

    with open('your_file', 'wb') as file:
        pickle.Pickler(file).dump(your_var)
    

    这是为了恢复

    with open('your_file', 'rb') as file:
         recovered=pickle.Unpickler(file).load()
    

    【讨论】:

    • 实际上我想要一种独立于语言和平台的方式来存储datetime 数据类型。查看我的编辑。
    • 啊,我还以为泡菜不行。看,我想不出另一种方法来做到这一点,所以现在它肯定已经足够好了。 ''Pythonic'' 是一个非常抽象的概念(PEP 20 也是如此)。我只有
    • 您可以使用 str.encode('encodage') 来获得十六进制、utf-8 或任何字符串表示形式,但这有点离题了。 (5 分钟的编辑时间太短了)帮不了你。
    • 其实我存储的不是一个代表日期和时间的字符串,而是一个“原生”datetime.datetime 对象:docs.python.org/2/library/datetime.html#datetime.datetime
    猜你喜欢
    • 2014-01-07
    • 2021-03-03
    • 1970-01-01
    • 2010-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多