python/cpython · error · ValueError

Invalid microsecond separator

Error message

Invalid microsecond separator

What it means

After HH[:MM[:SS]] is consumed, the only legal next character is '.' or ',' starting the fractional-second part. Anything else (e.g. '12:30:00;5', trailing garbage after seconds) raises ValueError('Invalid microsecond separator').

Source

Thrown at Lib/_pydatetime.py:426

        time_comps[comp] = int(tstr[pos:pos+2])

        pos += 2
        next_char = tstr[pos:pos+1]

        if comp == 0:
            has_sep = next_char == ':'

        if not next_char or comp >= 2:
            break

        if has_sep and next_char != ':':
            raise ValueError("Invalid time separator: %c" % next_char)

        pos += has_sep

    if pos < len_str:
        if tstr[pos] not in '.,':
            raise ValueError("Invalid microsecond separator")
        else:
            pos += 1
            if not all(map(_is_ascii_digit, tstr[pos:])):
                raise ValueError("Non-digit values in fraction")

            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

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Accept both '.' and ',' by normalizing: s = s.replace(',', '.') applied only to the fraction position, or keep ',' as fromisoformat already allows it
  2. Strip/validate the tail: s.strip() and check re.fullmatch on the whole timestamp before parsing
  3. Trim junk after seconds with a regex capturing HH:MM:SS[.,fff]

Example fix

// before
dt = datetime.fromisoformat('2021-01-01T12:30:00;500')  # ValueError

# after
s = raw.replace(';', '.')
dt = datetime.fromisoformat(s)
Defensive patterns

Strategy: validation

Validate before calling

def norm_fraction_sep(t: str) -> str:
    # allow ';' or ' ' as the fraction delimiter like ','
    import re
    return re.sub(r'(?<=\d\d)[; ](?=\d)', '.', t)

Type guard

def fraction_separator_valid(t: str) -> bool:
    i = max(t.find('.'), t.find(','))
    return i == -1 or t[i] in '.,'

Prevention

When it happens

Trigger: datetime.fromisoformat('2021-01-01T12:30:00;500'); '12:30:00 000'; a timezone marker glued without sign such that parsing lands on a non '.,' char; trailing whitespace or junk after seconds.

Common situations: Excel/CSV exports using ';' or space as fraction delimiter; strings with invisible trailing characters (\r, \n, zero-width space) after seconds; half-sanitized timestamps where the 'T' was replaced but other chars left.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/5349af4915844b63. Report an issue: GitHub.