python/cpython · error · ValueError

microsecond must be in 0..999999, not {microsecond}

Error message

microsecond must be in 0..999999, not {microsecond}

What it means

Raised by _check_time_fields() when the microsecond argument to time()/datetime() is not in 0..999999. A second holds at most 999999 microseconds; passing 1000000 or a nanosecond-scale value (which can reach 9 digits) fails this check.

Source

Thrown at Lib/_pydatetime.py:593

        raise ValueError(f"month must be in 1..12, not {month}")
    dim = _days_in_month(year, month)
    if not 1 <= day <= dim:
        raise ValueError(f"day {day} must be in range 1..{dim} for month {month} in year {year}")
    return year, month, day

def _check_time_fields(hour, minute, second, microsecond, fold):
    hour = _index(hour)
    minute = _index(minute)
    second = _index(second)
    microsecond = _index(microsecond)
    if not 0 <= hour <= 23:
        raise ValueError(f"hour must be in 0..23, not {hour}")
    if not 0 <= minute <= 59:
        raise ValueError(f"minute must be in 0..59, not {minute}")
    if not 0 <= second <= 59:
        raise ValueError(f"second must be in 0..59, not {second}")
    if not 0 <= microsecond <= 999999:
        raise ValueError(f"microsecond must be in 0..999999, not {microsecond}")
    if fold not in (0, 1):
        raise ValueError(f"fold must be either 0 or 1, not {fold}")
    return hour, minute, second, microsecond, fold

def _check_tzinfo_arg(tz):
    if tz is not None and not isinstance(tz, tzinfo):
        raise TypeError(
            "tzinfo argument must be None or of a tzinfo subclass, "
            f"not {type(tz).__name__!r}"
        )

def _divide_and_round(a, b):
    """divide a by b and round result to the nearest integer

    When the ratio is exactly half-way between two integers,
    the even integer is returned.
    """
    # Based on the reference implementation for divmod_near

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Divide nanoseconds by 1000 before passing: us = ns // 1000
  2. Carry overflow: sec += us // 1000000; us %= 1000000
  3. Validate 0 <= microsecond <= 999999 on values from external APIs

Example fix

// before
dt = datetime.fromtimestamp(ts, tz)
dt = dt.replace(microsecond=ns_part)  # ns_part is nanoseconds
// after
dt = dt.replace(microsecond=ns_part // 1000)
Defensive patterns

Strategy: validation

Validate before calling

if not 0 <= microsecond <= 999999:
    raise ValueError('microsecond must be 0..999999')

Type guard

def valid_microsecond(us) -> bool:
    return 0 <= us <= 999999

Prevention

When it happens

Trigger: time(0, 0, 0, 1000000); passing a nanosecond timestamp's fractional part (e.g. 123456789) directly as microseconds; converting Java Instant.getNano() or time.time_ns() remainders without dividing by 1000.

Common situations: Interop with nanosecond-precision systems (Java, Go, time.time_ns(), pandas); unit mismatch when the source API's sub-second field is nanoseconds but the code assumes microseconds.

Related errors


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