As part of a logging system, I would like to parse a string timestamp coming from a Cisco device, which has the following format:
# show clock
16:26:19.990 GMT+1 Wed Sep 11 2013
The parsing result should be a UTC datetime
instance which will be stored in a SQLite database, thus the need for a timezone conversion.
Using just datetime.strptime
is not enough, because the %Z
directive only recognises local timezones (i.e. those related to the current $LANG
or $LC_*
environment). Therefore, I need to make use of the pytz package.
Because the format is always the same, I can do something like the following:
import pytz
from datetime import datetime
s = '16:26:19.990 CEST Wed Sep 11 2013'
tm, tz, dt = s.split(" ", 2)
naive = datetime.strptime("%s %s" % (tm, dt), "%H:%M:%S.%f %a %b %d %Y")
aware = naive.replace(timezone=pytz.timezone(tz))
universal = aware.astimezone(pytz.UTC)
This, however, does not work without some modifications. The value of tz
must be corrected to a name that is recognized by pytz. In the example, pytz.timezone('CEST')
raises an UnknownTimezoneError
because the real timezone is CET
. The problem is that the daylight savings correction is not applied then:
>>> from datetime import datetime
>>> from pytz import UTC, timezone
>>> a = datetime.strptime('16:18:57.925 Wed Sep 11 2013', '%H:%M:%S.%f %a %b %d %Y')
>>> b = a.replace(tzinfo=timezone('CET'))
>>> a
datetime.datetime(2013, 9, 11, 16, 18, 57, 925000)
>>> b
datetime.datetime(2013, 9, 11, 16, 18, 57, 925000, tzinfo=<DstTzInfo 'CET' CET+1:00:00 STD>)
>>> b.astimezone(UTC)
datetime.datetime(2013, 9, 11, 15, 18, 57, 925000, tzinfo=<UTC>)
Using normalize
does not seem to help:
>>> timezone('CET').normalize(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/etanol/virtualenvs/plexus/local/lib/python2.7/site-packages/pytz/tzinfo.py", line 235, in normalize
raise ValueError('Naive time - no tzinfo set')
ValueError: Naive time - no tzinfo set
>>> timezone('CET').normalize(b)
datetime.datetime(2013, 9, 11, 17, 18, 57, 925000, tzinfo=<DstTzInfo 'CET' CEST+2:00:00 DST>)
I don't really know what am I missing, but the wanted result is:
datetime.datetime(2013, 9, 11, 14, 18, 57, 925000, tzinfo=<UTC>)
Thanks in advance.