python/cpython · error · ValueError
time data %r does not match format %r
Error message
time data %r does not match format %r
What it means
After compiling the format into a regex, _strptime runs format_regex.match(data_string); if the match fails entirely, this ValueError reports both the data and the format with %r reprs. It means the input string does not fit the format at the very first mismatching position.
Source
Thrown at Lib/_strptime.py:574
format_regex = _regex_cache.get(format)
if not format_regex:
try:
format_regex = _TimeRE_cache.compile(format)
# KeyError raised when a bad format is found; can be specified as
# \\, in which case it was a stray % but with a space after it
except KeyError as err:
bad_directive = err.args[0]
del err
bad_directive = bad_directive.replace('\\s', '')
if not bad_directive:
raise ValueError("stray %% in format '%s'" % format) from None
bad_directive = bad_directive.replace('\\', '', 1)
raise ValueError("'%s' is a bad directive in format '%s'" %
(bad_directive, format)) from None
_regex_cache[format] = format_regex
found = format_regex.match(data_string)
if not found:
raise ValueError("time data %r does not match format %r" %
(data_string, format))
if len(data_string) != found.end():
rest = data_string[found.end():]
# Specific check for '%:z' directive
if (
"colon_z" in found.re.groupindex
and found.group("colon_z") is not None
and rest[0] != ":"
):
raise ValueError(
f"Missing colon in %:z before '{rest}', got '{data_string}'"
)
raise ValueError("unconverted data remains: %s" % rest)
iso_year = year = None
month = day = 1
hour = minute = second = fraction = 0
tz = -1View on GitHub (pinned to bc6749cc3b)
Solutions
- Compare the reprs in the message to spot the first divergent field and fix the format (or the data)
- Strip the input: data.strip() before parsing
- For variable formats, try datetime.fromisoformat or dateutil.parser
- Normalize the input first (e.g. zfill parts, or re.split on separators)
Example fix
# before
>>> datetime.strptime('01-02-2020', '%Y-%m-%d')
ValueError: time data '01-02-2020' does not match format '%Y-%m-%d'
# after
>>> datetime.strptime('01-02-2020', '%d-%m-%Y')
datetime.datetime(2020, 2, 1, 0, 0) Defensive patterns
Strategy: fallback
Validate before calling
from datetime import datetime
def try_parse(s: str, fmts):
for f in fmts:
try:
return datetime.strptime(s.strip(), f)
except ValueError:
continue
raise ValueError(f'unparseable date: {s!r}') Try / catch
for fmt in ('%Y-%m-%d', '%d/%m/%Y', '%m/%d/%Y'):
try:
dt = datetime.strptime(s.strip(), fmt)
break
except ValueError:
continue
else:
raise ValueError(f'unparseable: {s!r}') Prevention
- Normalize inputs (strip whitespace/newlines) before parsing
- Validate incoming data at the boundary (schema/regex) instead of trusting format alignment
- Prefer datetime.fromisoformat for ISO inputs; dateutil.parser for messy ones
When it happens
Trigger: datetime.strptime('2020-1-2', '%Y-%m-%d') can pass but '01-02-2020' with '%Y-%m-%d' fails; any case where literals, order, or directive values differ between data and format, e.g. strptime('12/31/99', '%Y-%m-%d') or 24-hour '25:00' with '%H'.
Common situations: Mixed source data (US vs ISO date order), zero-padded vs non-padded numbers, locale-dependent month names, AM/PM strings with %H, trailing whitespace/newline in the input.
Related errors
- unconverted data remains: %s
- Day of month directive '%d' may not be used without a year d
- Inconsistent use of : in {found_dict[group_key]}
- Day of the year directive '%j' is not compatible with ISO ye
- ISO year directive '%G' must be used with the ISO week direc
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/621b2926b9c27d16.
Report an issue: GitHub.