python/cpython · error · ValueError
Inconsistent use of : in {found_dict[group_key]}
Error message
Inconsistent use of : in {found_dict[group_key]} What it means
While post-processing a matched %z/%:z offset, _strptime normalizes colons out of the string; if the offset has a colon after the hours (z[3] == ':') it removes it, and then if seconds are present and the character at position 5 is not another ':', the format mixes colon and non-colon separators, raising this f-string ValueError showing the original matched group.
Source
Thrown at Lib/_strptime.py:704
# U starts week on Sunday.
week_of_year_start = 6
else:
# W starts week on Monday.
week_of_year_start = 0
elif group_key == 'V':
iso_week = int(found_dict['V'])
elif group_key in ('z', 'colon_z'):
z = found_dict[group_key]
if z:
if z == 'Z':
gmtoff = 0
else:
if z[3] == ':':
z = z[:3] + z[4:]
if len(z) > 5:
if z[5] != ':':
msg = f"Inconsistent use of : in {found_dict[group_key]}"
raise ValueError(msg)
z = z[:5] + z[6:]
hours = int(z[1:3])
minutes = int(z[3:5])
seconds = int(z[5:7] or 0)
gmtoff = (hours * 60 * 60) + (minutes * 60) + seconds
gmtoff_remainder = z[8:]
# Pad to always return microseconds.
gmtoff_remainder_padding = "0" * (6 - len(gmtoff_remainder))
gmtoff_fraction = int(gmtoff_remainder + gmtoff_remainder_padding)
if z.startswith("-"):
gmtoff = -gmtoff
gmtoff_fraction = -gmtoff_fraction
elif group_key == 'Z':
# Since -1 is default value only need to worry about setting tz if
# it can be something other than -1.
found_zone = found_dict['Z'].lower()
for value, tz_values in enumerate(locale_time.timezone):
if found_zone in tz_values:View on GitHub (pinned to bc6749cc3b)
Solutions
- Normalize the offset string to either fully colon-separated '+HH:MM:SS' or fully compact '+HHMMSS' before parsing
- Validate/repair offsets with a regex such as re.sub(r'(?<=\d{2}):(?=\d{2}(?!:))', '', s) to strip colons uniformly
Example fix
# before
>>> datetime.strptime('+05:0030', '%z')
ValueError: Inconsistent use of : in +05:0030
# after
>>> datetime.strptime('+050030', '%z')
datetime.datetime(2025, 8, 14, 0, 0, 30, tzinfo=datetime.timezone(datetime.timedelta(hours=5, seconds=30))) Defensive patterns
Strategy: validation
Validate before calling
import re
def normalize_offset(s: str) -> str:
# make offset uniformly compact: +HH:MM:SS -> +HHMMSS
return re.sub(r'(?<=[+-]\d{2}):(?=\d{2}(?!:))', '', s) Try / catch
try:
dt = datetime.strptime(s, '%z')
except ValueError as e:
if 'Inconsistent use of :' in str(e):
dt = datetime.strptime(normalize_offset(s), '%z')
else:
raise Prevention
- Generate offsets with one consistent separator style
- Validate offsets with a strict regex before parsing
- Use datetime.timezone(timedelta) to build offsets programmatically instead of string surgery
When it happens
Trigger: An offset like '+05:0030' (colon between hours and minutes but not before seconds) parsed with %z/%:z — hours and minutes colon-separated while seconds are concatenated without one.
Common situations: Hand-built or corrupted timezone strings; concatenating offset parts with inconsistent separators; data from sources that emit '+HH:MMSS' malformed offsets.
Related errors
- Missing colon in %:z before '{rest}', got '{data_string}'
- timezone changed during initialization
- time data %r does not match format %r
- unconverted data remains: %s
- tzinfo subclass must override utcoffset()
AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14).
Data as JSON: /api/errors/da912549363debc1.
Report an issue: GitHub.