Nov 13, 2023 · Snippets

Python Date Parser - Quick Snippet

I wanted to share how more easily deal with date parsing in python in this quick snippet.

I wanted to share how more easily deal with date parsing in python in this quick snippet.

Standard Python datetime

Normally, to parse a python date you will need the python datetime module and now the structure of the dates you are receiving:

>>> from datetime import datetime
>>> date_str = '2023-08-15'
>>> date_obj = datetime.strptime(date_str, '%Y-%m-%d')
>>> date_obj
datetime.datetime(2023, 8, 15, 0, 0)

To format it back to a string:

>>> date_obj.strftime('%A, %B %d, %Y %H:%M:%S')
'Tuesday, August 15, 2023 00:00:00'
>>> date_obj.strftime('%Y-%m-%dT%H:%M:%SZ')
'2023-08-15T00:00:00Z'

However, this can give you some problems. Specially on parsing when you are unsure on the string structure, or you need to support multiple structures:

>>> date_str_iso_z = '2023-08-15T00:00:00Z'
>>> date_str_iso = '2023-08-15T00:00:00'
>>> datetime.strptime(date_str_iso_z, '%Y-%m-%dT%H:%M:%SZ')
datetime.datetime(2023, 8, 15, 0, 0)
>>> datetime.strptime(date_str_iso, '%Y-%m-%dT%H:%M:%SZ')
...
ValueError: time data '2023-08-15T00:00:00' does not match format '%Y-%m-%dT%H:%M:%SZ'

Better approach: https://github.com/dateutil/dateutil

Using https://github.com/dateutil/dateutil, we can avoid this issues. This module is a dependency of pandas, so you might have it already installed by default

>>> from dateutil.parser import parse
>>> parse(date_str)
datetime.datetime(2023, 8, 15, 0, 0)
>>> parse(date_str_iso_z)
datetime.datetime(2023, 8, 15, 0, 0, tzinfo=tzutc())
>>> parse(date_str_iso)
datetime.datetime(2023, 8, 15, 0, 0)

As you can see, all the previous use cases are correctly parsed before.

The only main difference we need to account is the timezone info that the one with the trailing z is showing. This is expected behavior of the library, but just be aware that date times with different timezones might not be compatible

Bonus: isoformat()

To export your date times always in a ISO compatible format, use datetime.isoformat() instead of strftime

>>> date_obj.isoformat(timespec="seconds")
'2023-08-15T00:00:00'