working with high precision timestamps in python
Hey I am working in python with datetime and I am wondering what the best way to parse this timestamp is.
The timestamps are ISO standard, here is an example "2010-06-19T08:17:14.078685237Z"
Now so far I have used
time = datetime.datetime.strptime(timestamp.split(".")[0], "%Y-%m-%dT%H:%M:%S")
precisetime = time + datetime.timedelta(0,float("." + timestamp[:-1].split(".")[0]))
This kind of works, but I feel like there should be a more streamlined way (I am very new to python, and I am sure I am doing this like an ass). Also, I have nanoseconds in my timestamp, but only microseconds in my datetime object, is there a better module to work with? I need to be able to do 开发者_JAVA技巧operations on the time such as subtracting times and putting them in the scheduler.
Any better way to go about this?
You can use Numpy's datetime64: http://docs.scipy.org/doc/numpy-dev/reference/arrays.datetime.html
It supports nanoseconds and higher precisions.
>>> import numpy as np
>>> np.version.version
'1.7.1'
>>> np.datetime64("2010-06-19T08:17:14.078685237Z", dtype="datetime64[ns]")
numpy.datetime64('2010-06-19T08:17:14.078685237+0000')
datetime
is only precise to microseconds. I.e. 10e-6
.
So
14.078685237
will get truncated to
14.078685
if you do what you did above.
It's better to just hold the sub-seconds separately in a float
, and do some floating point modulus operations to keep track of this.
I find it ridiculous that datetime
doesn't do this.
And for the people that say clocks aren’t accurate enough. That isn't the only use case. When your converting back and forth from distance to time. (Multiplying by the speed of light.) 1 micro second is 300m. 300 meters is the length of 3 football fields. Which is total crap for accuracy.
There's nothing inherently ass-like with your approach, but you may like to try pyiso8601 or dateutil
Your code looks fine. I don't know a better way, but I'm not a datetime
expert. Personally, I would wrap it in a function and do a little less work per line, but that's just my style:
def parse_iso_timestamp(timestamp)
ts, partial_seconds = timestamp[:-1].split('.')
partial_seconds = float("." + partial_seconds)
time = datetime.datetime.strptime(ts, "%Y-%m-%dT%H:%M:%S")
precisedatetime = time + datetime.timedelta(seconds=partial_seconds)
return precisedatetime
edit: I agree with Rob Cowie's answer. No need to reinvent the wheel.
Here is an alternative approach using a regular expression that you may (or may not) find cleaner:
import re
timestamp = "2010-06-19T08:17:14.078685237Z"
ts_regex = re.compile(r"(\d{4})-(\d{1,2})-(\d{1,2})T(\d{2}):(\d{2}):(\d{2})\.(\d{6})")
precisetime = datetime.datetime(*map(int, ts_regex.match(timestamp).groups()))
Here it is broken into a few more steps to provide some clarity:
>>> ts_regex.match(timestamp).groups()
('2010', '06', '19', '08', '17', '14', '078685')
>>> map(int, ts_regex.match(timestamp).groups())
[2010, 6, 19, 8, 17, 14, 78685]
We can pass this list directly into the initialization of a datetime
object using argument expansion with *
, since the arguments are in the correct order.
精彩评论