RustPython/RustPython · error · ValueError

Isoformat time too short

Error message

Isoformat time too short

What it means

_parse_isoformat_time needs at least a two-digit hour to begin parsing; a time string shorter than 2 characters raises ValueError('Isoformat time too short') before any component work starts. It fires when a datetime string ends at (or right after) the date/time separator, leaving an empty or single-character time part.

Source

Thrown at Lib/_pydatetime.py:448

            len_remainder = len_str - pos

            if len_remainder >= 6:
                to_parse = 6
            else:
                to_parse = len_remainder

            time_comps[3] = int(tstr[pos:(pos+to_parse)])
            if to_parse < 6:
                time_comps[3] *= _FRACTION_CORRECTION[to_parse-1]

    return time_comps

def _parse_isoformat_time(tstr):
    # Format supported is HH[:MM[:SS[.fff[fff]]]][+HH:MM[:SS[.ffffff]]]
    len_str = len(tstr)
    if len_str < 2:
        raise ValueError("Isoformat time too short")

    # This is equivalent to re.search('[+-Z]', tstr), but faster
    tz_pos = (tstr.find('-') + 1 or tstr.find('+') + 1 or tstr.find('Z') + 1)
    timestr = tstr[:tz_pos-1] if tz_pos > 0 else tstr

    time_comps = _parse_hh_mm_ss_ff(timestr)

    hour, minute, second, microsecond = time_comps
    became_next_day = False
    error_from_components = False
    if (hour == 24):
        if all(time_comp == 0 for time_comp in time_comps[1:]):
            hour = 0
            time_comps[0] = hour
            became_next_day = True
        else:
            error_from_components = True

View on GitHub (pinned to aaeab4f754)

Solutions

  1. Supply at least 'HH': '2021-01-01T07' (and prefer the full 'HH:MM' or 'HH:MM:SS')
  2. Treat an empty time part as midnight explicitly: parse the date with date.fromisoformat and combine with time(0, 0)
  3. Check len(timestr) >= 2 before calling fromisoformat on split parts

Example fix

# before
datetime.fromisoformat('2021-01-01T')  # Isoformat time too short

# after
datetime.combine(date.fromisoformat('2021-01-01'), time(0, 0))
Defensive patterns

Strategy: validation

Validate before calling

date_part, sep, time_part = s.partition('T')
if sep and len(time_part) < 2:
    # empty or 1-char time: treat as midnight instead of failing
    dt = datetime.combine(date.fromisoformat(date_part), time(0, 0))
else:
    dt = datetime.fromisoformat(s)

Try / catch

try:
    dt = datetime.fromisoformat(s)
except ValueError as e:
    if 'too short' in str(e):
        dt = datetime.combine(date.fromisoformat(s.rstrip('T')), time(0, 0))
    else:
        raise

Prevention

When it happens

Trigger: datetime.fromisoformat('2021-01-01T') (empty time part) or '2021-01-01T7' (single hour digit) — the time portion after the separator has len < 2.

Common situations: Truncated exports that cut the string at a fixed width; code that appends 'T' optimistically; user input where the time was never entered.

Related errors


AI-assisted analysis of RustPython/RustPython@aaeab4f754 (2026-08-17). Data as JSON: /api/errors/d4da4cde9f27b5cc. Report an issue: GitHub.