pola-rs/polars · error · TypeError
time zone of dtype ( ) differs from time zone of value ( )
Error message
time zone of dtype ({dtype_tz!r}) differs from time zone of value ({value_tz!r}) What it means
`pl.lit` was given a tz-aware datetime and a `Datetime` dtype whose time zone differs from the value's time zone. Polars will not silently reinterpret time zones, so it raises rather than producing shifted timestamps.
Solutions
- Make the dtype time zone match the value's, e.g. `pl.Datetime('us', 'UTC')` for a UTC-aware value
- Convert the value first: `value.astimezone(zoneinfo.ZoneInfo(dtype_tz))`
- Use a tz-naive dtype + `dt.replace_time_zone` on the resulting expression if you want wall-clock semantics
Example fix
// before
pl.lit(dt_paris, dtype=pl.Datetime('us', 'UTC'))
// after
pl.lit(dt_paris.astimezone(ZoneInfo('Europe/Paris')), dtype=pl.Datetime('us', 'Europe/Paris')) Defensive patterns
Strategy: validation
Validate before calling
value_tz = str(value.tzinfo) if value.tzinfo else None
if value_tz and dtype.time_zone and value_tz != dtype.time_zone:
value = value.astimezone(ZoneInfo(dtype.time_zone)) Type guard
def tz_matches(value, dtype) -> bool:
return value.tzinfo is None or dtype.time_zone is None or str(value.tzinfo) == dtype.time_zone Try / catch
try:
expr = pl.lit(value, dtype=dt_dtype)
except TypeError as e:
if 'time zone of dtype' in str(e):
value = value.astimezone(ZoneInfo(dt_dtype.time_zone))
expr = pl.lit(value, dtype=dt_dtype)
else:
raise Prevention
- Normalize all datetimes to a canonical zone before pl.lit
- Keep dtype time_zone and value tzinfo sourced from the same constant
When it happens
Trigger: `pl.lit(datetime_with_tz, dtype=pl.Datetime('us', 'Other/Zone'))` where the Python datetime's `tzinfo` resolves to a different zone name than the dtype's `time_zone`.
Common situations: Mixing 'UTC' with a named zone like 'Europe/Paris'; building literals from user-supplied datetimes with arbitrary tzinfo; DST-related code that swaps tzinfo.
Related errors
- comparing datetimes with different units or timezones is…
- datetime time zone does not match Series timezone
- expected 'time' to be a Python time or Polars expression…
- incorrect NumPy datetime resolution 'D' (datetime only)…
- `time_unit` must be one of
AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18).
Data as JSON: /api/errors/a3b1c12f0865370c.
Report an issue: GitHub.
Appendix: source
Thrown at py-polars/src/polars/functions/lit.py:155
value = value.astimezone(timezone.utc)
tz = "UTC"
# dtype and value both have same time zone
elif str(value_tz) == dtype_tz:
tz = str(value_tz)
# given a fixed offset from UTC that matches the dtype tz offset
elif hasattr(value_tz, "utcoffset") and getattr(
ZoneInfo(dtype_tz).utcoffset(value), "seconds", 0
) == getattr(value_tz.utcoffset(value), "seconds", 1):
tz = dtype_tz
else:
# value has time zone that differs from dtype time zone
msg = (
f"time zone of dtype ({dtype_tz!r}) differs from time zone of "
f"value ({value_tz!r})"
)
raise TypeError(msg)
dt_utc = value.replace(tzinfo=timezone.utc)
dt_utc_s = pl.Series("literal", [dt_utc]).cast(Datetime(time_unit))
if tz is not None:
dt_utc_s = dt_utc_s.dt.replace_time_zone(
tz, ambiguous="earliest" if value.fold == 0 else "latest"
)
expr = wrap_expr(plr.lit(dt_utc_s._s, allow_object=False, is_scalar=True))
return expr
elif isinstance(value, timedelta):
value_s = pl.Series("literal", [value])
if dtype is not None and (tu := getattr(dtype, "time_unit", None)) is not None:
tu = cast("TimeUnit", tu)
value_s = value_s.cast(Duration(tu))
expr = wrap_expr(plr.lit(value_s._s, allow_object=False, is_scalar=True))
return expr
View on GitHub (pinned to fe841f959e)