How to preserve timezone when parsing date/time strings with strptime()?

Viewed 277810

I have a CSV dumpfile from a Blackberry IPD backup, created using IPDDump. The date/time strings in here look something like this (where EST is an Australian time-zone):

Tue Jun 22 07:46:22 EST 2010

I need to be able to parse this date in Python. At first, I tried to use the strptime() function from datettime.

>>> datetime.datetime.strptime('Tue Jun 22 12:10:20 2010 EST', '%a %b %d %H:%M:%S %Y %Z')

However, for some reason, the datetime object that comes back doesn't seem to have any tzinfo associated with it.

I did read on this page that apparently datetime.strptime silently discards tzinfo, however, I checked the documentation, and I can't find anything to that effect documented here.

Is there any way to get strptime() to play nicely with timezones?

6 Answers

Since strptime returns a datetime object which has tzinfo attribute, We can simply replace it with desired timezone.

>>> import datetime

>>> date_time_str = '2018-06-29 08:15:27.243860'
>>> date_time_obj = datetime.datetime.strptime(date_time_str, '%Y-%m-%d %H:%M:%S.%f').replace(tzinfo=datetime.timezone.utc)
>>> date_time_obj.tzname()
'UTC'

Ran into this exact problem.

What I ended up doing:

# starting with date string
sdt = "20190901"
std_format = '%Y%m%d'

# create naive datetime object
from datetime import datetime
dt = datetime.strptime(sdt, sdt_format)

# extract the relevant date time items
dt_formatters = ['%Y','%m','%d']
dt_vals = tuple(map(lambda formatter: int(datetime.strftime(dt,formatter)), dt_formatters))

# set timezone
import pendulum
tz = pendulum.timezone('utc')

dt_tz = datetime(*dt_vals,tzinfo=tz)

As an extension to Joe Shaw's answer, dateutil's parser offers the possibility to supply a mapping of time zone name abbreviations to timezone objects derived from IANA time zone names.

import dateutil

tzdict = {'EST': dateutil.tz.gettz('America/New_York'),
          'EDT': dateutil.tz.gettz('America/New_York')}

dt = dateutil.parser.parse("Tue Jun 22 07:46:22 EST 2010", tzinfos=tzdict)

print(dt)
# 2010-06-22 07:46:22-04:00
      
print(repr(dt))
# datetime.datetime(2010, 6, 22, 7, 46, 22, tzinfo=tzfile('US/Eastern'))

The advantage over a fixed UTC offset is that time zone rules (e.g. DST transitions) will be taken into account if you perform any timedelta arithmetic with the obtained datetime object.

Related