Explain Codes LogoExplain Codes Logo

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

python
datetime
timezone
parsing
Alex KataevbyAlex Kataev·Jan 25, 2025
TLDR

Effortlessly retain timezone information by leveraging python-dateutil's parser. This is pivotal because strptime() yields naive datetime objects, which discard the timezones. Implement it as follows:

from dateutil import parser dt = parser.parse("2023-02-20T14:30:00-05:00") # Cheers to parse and timezone!

The parse function brilliantly preserves the -05:00 timezone offset, ensuring the datetime object maintains awareness of its timezone.

Parsing with strftime and strptime

strptime() teams up with the %z directive to birth timezone-aware datetime objects. Here's how they operate:

from datetime import datetime # Time-travel with %z in action datetime_obj = datetime.strptime("2023-04-01T14:30:00-0500", "%Y-%m-%dT%H:%M:%S%z")

However, avoid %Z in strptime() as much as coffee after 10 pm. It struggles to parse timezone names effectively. The repercussion? Misinterpreted datetimes, especially when the timezone abbreviation is deceptive (like EST).

Manual timezone adjustments in datetime

In instances where the timezone is known and consistent, manually adjusting the tzinfo of a datetime object could be a smart move:

from datetime import datetime, timezone, timedelta # Meet Mr. Consistent timezone naive_datetime = datetime.strptime("2023-04-01 14:30:00", "%Y-%m-%d %H:%M:%S") aware_datetime = naive_datetime.replace(tzinfo=timezone(timedelta(hours=-5)))

Note, this method should only be your plan when the timezone doesn't need dynamic parsing from strings.

Parsing email timestamps with parsedate_tz

For some date strings such as those from emails, parsedate_tz from email.utils could prove invaluable for handling timezones:

from email.utils import parsedate_tz, mktime_tz # Santa's elf handling timezone work date_tuple = parsedate_tz('Mon, 20 Feb 2023 14:30:00 -0500') timestamp = mktime_tz(date_tuple) # Here you go, the right present: timestamp!

The reward? The correct Unix timestamp inclusive of the timezone.

Timing the use of alternative libraries

Python-dateutil is undoubtedly an ace, but alternatives like pendulum can sometimes swing the game in your favor due to its simplification of timezone handling and parsing:

import pendulum dt = pendulum.parse("2023-02-20T14:30:00-05:00") # Pendulum making the swing

Unveiling timezone name and offsets

Verify each timezone abbreviation when dealing with diverse timezones. Obtain the timezone name from a datetime object using the tzname() method:

from datetime import datetime, timezone # Detective tzname() at work! dt = datetime.now(timezone.utc) print(dt.tzname()) # Will spill the beans: 'UTC'

The ingenious tzname() method comes in handy when you need to extract a timezone name from a timezone-aware object.

Timestamp adjustments for peculiar cases

Sometimes, timestamps just need a little tweak, like those from a Blackberry IPD backup tagged with EST. For locations like Australia, where EST signifies a different offset, manual adjustments become a must:

import pytz # Blackberry to Kangaroo switch timestamp = "2023-04-01 14:30:00 EST" aus_tz = pytz.timezone('Australia/Sydney') corrected_time = aus_tz.localize(datetime.strptime(timestamp, "%Y-%m-%d %H:%M:%S %Z"))