I have a time string like this: 2013-08-22 16:56:19 Etc/GMT
I need to parse it to a datetime object. I'm getting hung up on the posix-style time zone, which I can't get Python to natively grok.
Here are a couple of attempts and their failures. I'm including the timezone-stripped version first to show the parsing is otherwise correct.
datetime.strptime
>>> datetime.datetime.strptime("2013-08-22 16:56:19 UTC", "%Y-%m-%d %H:%M:%S %Z")
datetime.datetime(2013, 8, 22, 16, 56, 19)
>>> datetime.datetime.strptime("2013-08-22 16:56:19 Etc/GMT", "%Y-%m-%d %H:%M:%S %Z")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_strptime.py", line 325, in _strptime
(data_string, format))
ValueError: time data '2013-08-22 16:56:19 Etc/GMT' does not match format '%Y-%m-%d %H:%M:%S %Z'
time.strptime
>>> time.strptime("2013-08-22 16:56:19 UTC", "%Y-%m-%d %H:%M:%S %Z")
time.struct_time(tm_year=2013, tm_mon=8, tm_mday=22, tm_hour=16, tm_min=56, tm_sec=19, tm_wday=3, tm_yday=234, tm_isdst=0)
>>> time.strptime("2013-08-22 16:56:19 Etc/GMT", "%Y-%m-%d %H:%M:%S %Z")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_strptime.py", line 454, in _strptime_time
return _strptime(data_string, format)[0]
File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/_strptime.py", line 325, in _strptime
(data_string, format))
ValueError: time data '2013-08-22 16:56:19 Etc/GMT' does not match format '%Y-%m-%d %H:%M:%S %Z'
dateutil.parser
>>> dateutil.parser.parse("2013-08-22 16:56:19")
datetime.datetime(2013, 8, 22, 16, 56, 19)
>>> dateutil.parser.parse("2013-08-22 16:56:19 Etc/GMT")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/python_dateutil-2.1-py2.7.egg/dateutil/parser.py", line 720, in parse
return DEFAULTPARSER.parse(timestr, **kwargs)
File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/python_dateutil-2.1-py2.7.egg/dateutil/parser.py", line 310, in parse
raise ValueError("unknown string format")
ValueError: unknown string format
tzinfos
It seems like dateutil's tzinfos argument should be perfect for this, but it doesn't work either... or I'm misreading the trace and doing something wrong. (I used this as an example)
>>> dateutil.parser.parse("2013-08-22 16:56:19 Etc/GMT", tzinfos={ 'Etc/GMT': pytz.timezone('UTC') })
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/python_dateutil-2.1-py2.7.egg/dateutil/parser.py", line 720, in parse
return DEFAULTPARSER.parse(timestr, **kwargs)
File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/python_dateutil-2.1-py2.7.egg/dateutil/parser.py", line 310, in parse
raise ValueError("unknown string format")
ValueError: unknown string format
tzinfos, round two
It seems like this stackoverflow answer is getting towards the usage of tzinfos that I might need. I tried the simplified version of the above (where value=offset seconds). Still fails.
>>> dateutil.parser.parse("2013-08-22 16:56:19 Etc/GMT", tzinfos={ 'Etc/GMT': 0 })
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/python_dateutil-2.1-py2.7.egg/dateutil/parser.py", line 720, in parse
return DEFAULTPARSER.parse(timestr, **kwargs)
File "/usr/local/Cellar/python/2.7.3/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/python_dateutil-2.1-py2.7.egg/dateutil/parser.py", line 310, in parse
raise ValueError("unknown string format")
ValueError: unknown string format
do it the wrong way
I could always use something like regex or string matching to find and change this timezone, but it feels wrong.
red herrings
The common problem with the posix ETC/xxx timezones is that they have reversed signs. This is a UTC ("no offset") posix time zone, and many of the questions I've found that deal with "etc" have to do with this reversed offset.
How about this:
datetime
object via strptime()
pytz
timezonetzinfo
on the datetime object via replace()
from datetime import datetime
import pytz
date_string = "2013-08-22 16:56:19"
tz_string = "Etc/GMT"
dt = datetime.strptime(date_string, "%Y-%m-%d %H:%M:%S")
dt = dt.replace(tzinfo=pytz.timezone('Etc/GMT'))
print dt
prints:
2013-08-22 16:56:19+00:00
This actually correctly understands and reverses signs in the POSIX timezone format, for example:
dt = dt.replace(tzinfo=pytz.timezone('Etc/GMT-1'))
print dt # prints 2013-08-22 16:56:19+01:00
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