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

  1. Normalize the input timezone to the accepted 'UTC±h' format (e.g. 'EST' → 'UTC-5') before calling parse_datetime_with_tz.
  2. Use 'AoE' for anywhere-on-earth deadlines or 'UTC' for zero offset; match capitalization exactly.
  3. Pre-validate tz strings with the same regex the function uses, and clean/fix source data that violates it.
  4. 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

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)