ccfddl/ccf-deadlines · error · ValueError
Invalid timezone format
Error message
Invalid timezone format: {tz_str} What it means
get_timezone in extensions/cli/ccfddl/utils.py (used by parse_datetime_with_tz) maps a timezone string to a datetime.timezone, accepting only 'AoE', 'UTC', and the pattern UTC[+-]\d{1,2} (e.g. UTC+8, UTC-12). Anything else fails the regex and raises ValueError("Invalid timezone format: {tz_str}").
Solutions
- Normalize the input timezone to the accepted 'UTC±h' format (e.g. 'EST' → 'UTC-5') before calling parse_datetime_with_tz.
- Use 'AoE' for anywhere-on-earth deadlines or 'UTC' for zero offset; match capitalization exactly.
- Pre-validate tz strings with the same regex the function uses, and clean/fix source data that violates it.
- Broaden the parser (zoneinfo.ZoneInfo for IANA names, or accept UTC±HH:MM) if minute-precision or named zones are required.
Example fix
// before
parse_datetime_with_tz("2026-10-01 23:59 UTC+05:30") # ValueError: Invalid timezone format: UTC+05:30
// after
parse_datetime_with_tz("2026-10-01 23:59 UTC+5") # parsed with timezone(timedelta(hours=5)) Defensive patterns
Strategy: validation
Validate before calling
import re
def is_supported_tz(tz_str):
return tz_str in ("AoE", "UTC") or re.match(r"UTC([+-])(\d{1,2})$", tz_str) is not None
if not is_supported_tz(tz_str):
raise ValueError(f"pre-check failed for tz: {tz_str!r}") Try / catch
try:
dt = parse_datetime_with_tz(s)
except ValueError as e:
if "Invalid timezone format" in str(e):
logging.warning("bad tz in %r, defaulting to AoE", s)
dt = parse_datetime_with_tz(s.rsplit(" ", 1)[0] + " AoE")
else:
raise Prevention
- Validate/normalize the tz suffix of every datetime string before parsing.
- Convert IANA zone names and abbreviations (PST, JST) to UTC±h at data-ingestion time.
- Reject or fix 'UTC±HH:MM' minute-offset strings since the parser only accepts whole hours.
- Add a shared regex constant/test so all callers agree on the accepted tz grammar.
When it happens
Trigger: parse_datetime_with_tz receiving a datetime string whose timezone suffix is not one of the three accepted forms — e.g. 'Asia/Tokyo', 'UTC+05:30', 'GMT+9', 'EST', 'utc+2', or a missing/empty tz token.
Common situations: Parsing conference deadline strings scraped from web pages that use IANA zone names or common abbreviations; data files produced by other tools with 'UTC+05:30'-style offsets including minutes; locale-dependent or lowercased tz strings from user input.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
AI-assisted analysis of ccfddl/ccf-deadlines@dedf5e76ab (2026-09-11).
Data as JSON: /api/errors/ca6aa72b0a7b5ad4.
Report an issue: GitHub.
Appendix: source
Thrown at extensions/cli/ccfddl/utils.py:57
- 'UTC' (UTC+0)
- 'UTC+8', 'UTC-5' (UTC with offset)
Args:
tz_str: Timezone string
Returns:
A timezone object
Raises:
ValueError: If the timezone format is invalid
"""
if tz_str == "AoE":
return timezone(timedelta(hours=-12))
if tz_str == "UTC":
return timezone.utc
match = re.match(r"UTC([+-])(\d{1,2})$", tz_str)
if not match:
raise ValueError(f"Invalid timezone format: {tz_str}")
sign, hours = match.groups()
offset = int(hours) if sign == "+" else -int(hours)
return timezone(timedelta(hours=offset))
def parse_datetime_with_tz(
dt_str: str, tz_str: str, format_str: str = "%Y-%m-%d %H:%M:%S"
) -> datetime:
"""Parse datetime string with timezone.
Args:
dt_str: Datetime string (e.g., '2025-01-15 23:59:59')
tz_str: Timezone string (e.g., 'UTC-8', 'AoE')
format_str: Datetime format string
Returns:
Timezone-aware datetime object
View on GitHub (pinned to dedf5e76ab)