{"record":{"id":"ca6aa72b0a7b5ad4","repo":"ccfddl/ccf-deadlines","slug":"invalid-timezone-format-tz-str","errorCode":null,"errorMessage":"Invalid timezone format: {tz_str}","messagePattern":"Invalid timezone format: (.+?)","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"extensions/cli/ccfddl/utils.py","lineNumber":57,"sourceCode":"        - 'UTC' (UTC+0)\n        - 'UTC+8', 'UTC-5' (UTC with offset)\n\n    Args:\n        tz_str: Timezone string\n\n    Returns:\n        A timezone object\n\n    Raises:\n        ValueError: If the timezone format is invalid\n    \"\"\"\n    if tz_str == \"AoE\":\n        return timezone(timedelta(hours=-12))\n    if tz_str == \"UTC\":\n        return timezone.utc\n    match = re.match(r\"UTC([+-])(\\d{1,2})$\", tz_str)\n    if not match:\n        raise ValueError(f\"Invalid timezone format: {tz_str}\")\n    sign, hours = match.groups()\n    offset = int(hours) if sign == \"+\" else -int(hours)\n    return timezone(timedelta(hours=offset))\n\n\ndef parse_datetime_with_tz(\n    dt_str: str, tz_str: str, format_str: str = \"%Y-%m-%d %H:%M:%S\"\n) -> datetime:\n    \"\"\"Parse datetime string with timezone.\n\n    Args:\n        dt_str: Datetime string (e.g., '2025-01-15 23:59:59')\n        tz_str: Timezone string (e.g., 'UTC-8', 'AoE')\n        format_str: Datetime format string\n\n    Returns:\n        Timezone-aware datetime object\n","sourceCodeStart":39,"sourceCodeEnd":75,"githubUrl":"https://github.com/ccfddl/ccf-deadlines/blob/dedf5e76ab05c38b3cba2ba4f1fbf4d04fd403ba/extensions/cli/ccfddl/utils.py#L39-L75","documentation":"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}\").","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nparse_datetime_with_tz(\"2026-10-01 23:59 UTC+05:30\")  # ValueError: Invalid timezone format: UTC+05:30\n// after\nparse_datetime_with_tz(\"2026-10-01 23:59 UTC+5\")  # parsed with timezone(timedelta(hours=5))","handlingStrategy":"validation","validationCode":"import re\ndef is_supported_tz(tz_str):\n    return tz_str in (\"AoE\", \"UTC\") or re.match(r\"UTC([+-])(\\d{1,2})$\", tz_str) is not None\n\nif not is_supported_tz(tz_str):\n    raise ValueError(f\"pre-check failed for tz: {tz_str!r}\")","typeGuard":null,"tryCatchPattern":"try:\n    dt = parse_datetime_with_tz(s)\nexcept ValueError as e:\n    if \"Invalid timezone format\" in str(e):\n        logging.warning(\"bad tz in %r, defaulting to AoE\", s)\n        dt = parse_datetime_with_tz(s.rsplit(\" \", 1)[0] + \" AoE\")\n    else:\n        raise","preventionTips":["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."],"tags":["timezone","python","validation","datetime","regex"],"backgroundTag":"invalid-argument-format","analyzedSha":"dedf5e76ab05c38b3cba2ba4f1fbf4d04fd403ba","analyzedAt":"2026-09-11T16:18:10.249Z","contentChangedAt":"2026-09-11T16:18:10.249Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}