Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python datetime.strptime: ignore fraction of a second

I'm working on converting a human readable time to a datetime object . In order to do this, I'm using datetime.datetime.strptime.

Simple enough, however, the human readable time that I have contains fractions of a second, which I'm not able to parse. If this was a constant, I could incorporate it as part of the format. However, since it is not a constant, I am unable to do so.

This is what I'm doing right now:

>>> humanTime = '2012/06/10T16:36:20.509Z'
>>> datetime.datetime.strptime(humanTime, "%Y/%m/%dT%H:%M:%SZ")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "lib/python2.7/_strptime.py", line 325, in _strptime
    (data_string, format))
ValueError: time data '2012-06-10T16:36:20.507Z' does not match format '%Y-%m-%dT%H:%M:%SZ'

So I figure that the issue here is that the fraction of a second is not parseable. I don't really care about that fraction of a second. Short of slicing the string, is there a way by which I can ask datetime to ignore the fraction of a second (preferably with the format)?

I have a feeling that I might be missing something very basic. I'd appreciate any help.

like image 818
inspectorG4dget Avatar asked Jul 02 '12 22:07

inspectorG4dget


3 Answers

Solution to your particular problem: use the %f for microseconds:

>>> datetime.datetime.strptime(humanTime, "%Y/%m/%dT%H:%M:%S.%fZ")

However, the problem is still there for a general case. If you'd have more than 6 digits after the dot, then this solution won't work.

The problem is that, to my knowledge, datetime.datetime.strptime accepted formats doesn't include floating seconds in general. The workaround is to ignore seconds when creating your datetime variable and afterwards add the seconds with datetime.timedelta.

>>> import numpy as np
>>> import datetime
>>> 
>>> humanTime = '2012/06/10T16:36:20.509Z'
>>> dt_time_no_seconds = datetime.datetime.strptime(humanTime[:-8], "%Y/%m/%dT%H:%M")
>>> seconds = np.float(humanTime[-7:-1])
>>> dt_time = dt_time_no_seconds+datetime.timedelta(seconds=seconds)
>>> dt_time_no_seconds
datetime.datetime(2012, 6, 10, 16, 36)
>>> dt_time
datetime.datetime(2012, 6, 10, 16, 36, 20, 509000)

Hope this helps.

like image 39
Héctor Avatar answered Sep 23 '22 22:09

Héctor


The directive %f will interpret fractional seconds: https://docs.python.org/2/library/datetime.html#strftime-strptime-behavior

import datetime
humanTime = '2012/06/10T16:36:20.509Z'
datetime.datetime.strptime(humanTime, '%Y/%m/%dT%H:%M:%S.%fZ')
 
>> datetime.datetime(2012, 6, 10, 16, 36, 20, 509000)

Pandas can also parse the string with fractional seconds...

import pandas as pd
humanTime = '2012/06/10T16:36:20.509Z'
pd.to_datetime(humanTime)

>> Timestamp('2012-06-10 16:36:20.509000+0000', tz='UTC')
like image 34
blaylockbk Avatar answered Sep 24 '22 22:09

blaylockbk


Since I really don't care about the fractions of a second, I should just take the first 19 characters of the human readable string, and apply a simple format on that.

>>> humanTime = '2012/06/10T16:36:20.509Z'
>>> datetime.datetime.strptime(humanTime[:19], "%Y/%m/%dT%H:%M:%S")
datetime.datetime(2012, 6, 10, 16, 36, 20)
like image 75
inspectorG4dget Avatar answered Sep 22 '22 22:09

inspectorG4dget