Reputation: 21243
I have date as
In [1]: a = "Sun 10 May 2015 13:34:36 -0700"
When I try to convert it using strptime
, its giving error.
In [3]: datetime.strptime(a, "%a %d %b %Y %H:%M:%S %Z"
...: )
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-3-973ef1c6daca> in <module>()
----> 1 datetime.strptime(a, "%a %d %b %Y %H:%M:%S %Z"
2 )
/usr/lib/python2.7/_strptime.pyc in _strptime(data_string, format)
323 if not found:
324 raise ValueError("time data %r does not match format %r" %
--> 325 (data_string, format))
326 if len(data_string) != found.end():
327 raise ValueError("unconverted data remains: %s" %
ValueError: time data 'Sun 10 May 2015 13:34:36 -0700' does not match format '%a %d %b %Y %H:%M:%S %Z'
In [6]: datetime.strptime(a, "%a %d %b %Y %H:%M:%S %z")
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-6-e4870e34edda> in <module>()
----> 1 datetime.strptime(a, "%a %d %b %Y %H:%M:%S %z")
/usr/lib/python2.7/_strptime.pyc in _strptime(data_string, format)
315 del err
316 raise ValueError("'%s' is a bad directive in format '%s'" %
--> 317 (bad_directive, format))
318 # IndexError only occurs when the format string is "%"
319 except IndexError:
ValueError: 'z' is a bad directive in format '%a %d %b %Y %H:%M:%S %z'
As per doc, correct format is %z
, but I might missing some part.
Upvotes: 0
Views: 3374
Reputation: 414149
You can parse your input format using only stdlib even in Python 2.7:
>>> from datetime import datetime
>>> from email.utils import mktime_tz, parsedate_tz
>>> mktime_tz(parsedate_tz("Sun 10 May 2015 13:34:36 -0700"))
1431290076
>>> datetime.utcfromtimestamp(_)
datetime.datetime(2015, 5, 10, 20, 34, 36)
The result is a naive datetime object that represents time in UTC.
See other solutions and the way to get an aware datetime object in Python: parsing date with timezone from an email.
Upvotes: 1
Reputation: 13616
Your format string is correct and works fine in Python 3.3:
>>> a = "Sun 10 May 2015 13:34:36 -0700"
>>> datetime.strptime(a, "%a %d %b %Y %H:%M:%S %z")
datetime.datetime(2015, 5, 10, 13, 34, 36, tzinfo=datetime.timezone(datetime.timedelta(-1, 61200)))
It gives the error in Python 2.7 indeed.
Unlike strftime()
, which is implemented by calling the libc function, strptime()
is implemented in the Python library. Here you can see that the version used in Python 2.7 doesn’t support the z
format. On the other hand here is the version from Python 3.3, which supports that (I think this was added around 3.2).
So, basically, you have two options:
z
.strptime()
and parsing the second one manually). Looking at how this is done in the Python library might be helpful.I tried to parse this to return an “aware” object, but it is somewhat complicated.
>>> a = "Sun 10 May 2015 13:34:36 -0700"
>>> time, tz = a.rsplit(' ', 1)
>>> d = datetime.strptime(time, '%a %d %b %Y %H:%M:%S')
datetime.datetime(2015, 5, 10, 13, 34, 36)
Now I have to call d.replace(tzinfo=…tz…)
to replace the timezone, but the problem is that I can’t get an instance of tzinfo
because just knowing the offset from UTC is not enough to identify a timezone.
In Python 3.2 there is a special timezone
class that is a subclass of tzinfo
representing a “fake” timezone defined by just its offset. So there are two ways to proceed:
timezone
class from Python 3 and use it in your parser.Return a “naive” object:
>>> d + timedelta(hours=int(tz[1:]) * (1 if tz.startswith('-') else -1))
datetime.datetime(2015, 6, 8, 17, 34, 36)
Upvotes: 2
Reputation: 8144
From the link you provided for the python doc, I found that you are using Python 2.7
It looks as if strptime doesn't always support %z
. Python appears to just call the C
function, and strptime doesn't support %z
on your platform.
Note: from Python 3.2 onwards it will always work.
I am using Python 3.4 in which it is working fine
>>> a = "Sun 10 May 2015 13:34:36 -0700"
>>> datetime.strptime(a, "%a %d %b %Y %H:%M:%S %z")
Update using dateutil
$ pip install python-dateutil
from dateutil import parser
parsed_date = parser.parse(date)
>>> parsed_date
datetime.datetime(2015, 3, 14, 18, 43, 19)
Upvotes: 3