I want to store a list of datetimes in a binary file in Python.
EDIT: 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.
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.
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
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?"
Thanks for reading!
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.
The changes from my original consist in replacing calendar.timegm by time.mktime and also utctimetuple by timetuple, to keep everything naive.
This:
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
Returns this:
2013-09-02 11:06:28.064000
1378130788.0
2013-09-02 11:06:28
1378130788
2013-09-02 11:06:28
From this, I can easily write the packed binarydatetime to file, and read it back later.
By far the most simple solution is to use Temporenc: http://temporenc.readthedocs.org/
It takes care of all the encoding/decoding and allows you to write a Python datetime object to a file:
now = datetime.datetime.now()
temporenc.pack(fp, now)
To read it back, this suffices:
dt = temporenc.unpack(fp)
print(dt)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With