Question

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.

Was it helpful?

Solution

Using timezone.localize:

>>> from datetime import datetime
>>> from pytz import UTC, timezone
>>>
>>> CET = timezone('CET')
>>>
>>> a = datetime.strptime('16:18:57.925 Wed Sep 11 2013', '%H:%M:%S.%f %a %b %d %Y')
>>> print CET.localize(a).astimezone(UTC)
2013-09-11 14:18:57.925000+00:00
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top