Parsing with fromisoformat and strptime

datetime · Essentials · 8 min

Dates arrive as text from CSV files, forms, logs and APIs.

For ISO 8601 strings, use fromisoformat. Since Python 3.11 it accepts most ISO formats, including a trailing Z for UTC, offsets like +05:30, T or space separators, fractional seconds and basic formats like 20250301:

datetime.fromisoformat("2025-03-01T14:30:00Z")   # aware, UTC

It's fast and strict, which is exactly what you want for machine data.

For other formats, use strptime ("string parse time") with the same codes as strftime. The format must match the whole string exactly, including separators:

datetime.strptime("01/03/2025 14:30", "%d/%m/%Y %H:%M")

A mismatch raises ValueError with a message showing the data and format, so wrap parsing of untrusted input in try/except.

Watch out for:

  • Ambiguous formats: 03/01/2025 is March 1 in the US and January 3 elsewhere. Know your source.
  • %z parses +0100, +01:00 and Z, producing an aware datetime; without it the result is naive.
  • %Z matches only a few names (UTC, GMT, local zone names) and doesn't attach a time zone.
  • date.fromisoformat and time.fromisoformat exist for the separate types; datetime.strptime(...).date() works for dates in custom formats.

For free-form or messy dates, the third-party dateutil.parser is more forgiving.

Example

from datetime import datetime

a = datetime.fromisoformat("2025-03-01T14:30:00Z")
print(a, a.tzinfo)              # 2025-03-01 14:30:00+00:00 UTC
print(datetime.fromisoformat("2025-03-01 14:30:00.5+05:30"))
# 2025-03-01 14:30:00.500000+05:30
print(datetime.fromisoformat("20250301"))     # 2025-03-01 00:00:00

b = datetime.strptime("01/03/2025 2:30 PM", "%d/%m/%Y %I:%M %p")
print(b)                        # 2025-03-01 14:30:00
c = datetime.strptime("Mar 1 2025 +0100", "%b %d %Y %z")
print(c.utcoffset())            # 1:00:00

try:
    datetime.strptime("2025-03-01", "%d/%m/%Y")
except ValueError as e:
    print(e)    # time data '2025-03-01' does not match format '%d/%m/%Y'

Remember

  • fromisoformat parses ISO 8601, including 'Z', since 3.11
  • strptime needs a format that matches the whole string exactly
  • Use %z to get an aware datetime; beware ambiguous day/month orders

Watch out for

  • Parsing ISO strings with a hand-written strptime format that breaks on fractional seconds or a 'Z' suffix.

Check yourself

  1. What does datetime.fromisoformat('2025-06-01T08:00:00Z') return in Python 3.13?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat