{"record":{"id":"a3b1c12f0865370c","repo":"pola-rs/polars","slug":"time-zone-of-dtype-dtype-tz-r-differs-from-tim","errorCode":null,"errorMessage":"time zone of dtype ({dtype_tz!r}) differs from time zone of value ({value_tz!r})","messagePattern":"time zone of dtype \\((.+?)\\) differs from time zone of value \\((.+?)\\)","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/functions/lit.py","lineNumber":142,"sourceCode":"                    value = value.astimezone(timezone.utc)\n                    tz = \"UTC\"\n\n            # dtype and value both have same time zone\n            elif str(value_tz) == dtype_tz:\n                tz = str(value_tz)\n\n            # given a fixed offset from UTC that matches the dtype tz offset\n            elif hasattr(value_tz, \"utcoffset\") and getattr(\n                ZoneInfo(dtype_tz).utcoffset(value), \"seconds\", 0\n            ) == getattr(value_tz.utcoffset(value), \"seconds\", 1):\n                tz = dtype_tz\n            else:\n                # value has time zone that differs from dtype time zone\n                msg = (\n                    f\"time zone of dtype ({dtype_tz!r}) differs from time zone of \"\n                    f\"value ({value_tz!r})\"\n                )\n                raise TypeError(msg)\n\n        dt_utc = value.replace(tzinfo=timezone.utc)\n        dt_utc_s = pl.Series(\"literal\", [dt_utc]).cast(Datetime(time_unit))\n        if tz is not None:\n            dt_utc_s = dt_utc_s.dt.replace_time_zone(\n                tz, ambiguous=\"earliest\" if value.fold == 0 else \"latest\"\n            )\n        expr = wrap_expr(plr.lit(dt_utc_s._s, allow_object=False, is_scalar=True))\n        return expr\n\n    elif isinstance(value, timedelta):\n        value_s = pl.Series(\"literal\", [value])\n        if dtype is not None and (tu := getattr(dtype, \"time_unit\", None)) is not None:\n            tu = cast(\"TimeUnit\", tu)\n            value_s = value_s.cast(Duration(tu))\n        expr = wrap_expr(plr.lit(value_s._s, allow_object=False, is_scalar=True))\n        return expr\n","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/functions/lit.py#L124-L160","documentation":"Raised by polars.lit when creating a datetime literal whose dtype carries a time zone that differs from the value's own tzinfo (and the value's offset does not coincidentally match the dtype tz offset at that instant). Polars refuses to silently reinterpret a zone; the zone on the value and on the Datetime dtype must agree.","triggerScenarios":"pl.lit(datetime(2024, 1, 1, tzinfo=ZoneInfo('Europe/Amsterdam')), dtype=Datetime('us', 'UTC')); mixing a timezone.utc value with a Datetime('us', 'America/New_York') dtype; passing a pytz/zoneinfo-aware datetime with a dtype tz from a different column schema.","commonSituations":"Hard-coding a dtype with a tz (e.g. copied from a schema dump) while user input datetimes carry local tzinfo; inconsistent tz handling between ingestion (UTC) and modeling (local tz); pytz-style localize vs zoneinfo conversions during migration.","solutions":["Convert the value to the dtype's zone first: value = value.astimezone(ZoneInfo(dtype_tz))","Or make the dtype match the value's zone: Datetime('us', value.tzinfo key)","Or drop the tz from the dtype and add it afterwards with dt.replace_time_zone / dt.convert_time_zone on the resulting expression"],"exampleFix":"// before\npl.lit(datetime(2024, 1, 1, tzinfo=ZoneInfo('Europe/Amsterdam')), dtype=Datetime('us', 'UTC'))\n// after\npl.lit(datetime(2024, 1, 1, tzinfo=ZoneInfo('Europe/Amsterdam')).astimezone(ZoneInfo('UTC')), dtype=Datetime('us', 'UTC'))","handlingStrategy":"validation","validationCode":"from datetime import datetime\nfrom zoneinfo import ZoneInfo\n\ndef align_literal_tz(value: datetime, dtype):\n    dtype_tz = getattr(dtype, 'time_zone', None)\n    if dtype_tz is not None and value.tzinfo is not None:\n        value_tz = value.tzinfo\n        if str(value_tz) != dtype_tz:\n            return value.astimezone(ZoneInfo(dtype_tz))\n    return value","typeGuard":"def tz_matches(value: datetime, dtype) -> bool:\n    dtype_tz = getattr(dtype, 'time_zone', None)\n    return dtype_tz is None or value.tzinfo is None or str(value.tzinfo) == dtype_tz","tryCatchPattern":"try:\n    e = pl.lit(dt, dtype=Datetime('us', 'UTC'))\nexcept TypeError:\n    e = pl.lit(dt.astimezone(ZoneInfo('UTC')), dtype=Datetime('us', 'UTC'))","preventionTips":["Normalize all tz-aware datetimes to UTC at ingestion","Derive the dtype's time_zone from the value instead of hard-coding","Keep one tz convention per project schema"],"tags":["polars","literal","timezone","datetime","type-mismatch"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}