pola-rs/polars · error

first cast to integer before multiplying datelike dtypes

Error message

first cast to integer before multiplying datelike dtypes

What it means

Raised by Series.__mul__ when multiplying a datelike Series (Date, Datetime, Time) by anything, unless the left operand is a Duration. Multiplying a calendar value by a scalar has no meaningful result, so Polars rejects it; Duration * n (scaling a timespan) is allowed and dispatched through the expression engine.

Source

Thrown at py-polars/src/polars/series/series.py:1319

    def __invert__(self) -> Series:
        return self.not_()

    @overload
    def __mul__(self, other: Expr) -> Expr: ...

    @overload
    def __mul__(self, other: DataFrame) -> DataFrame: ...

    @overload
    def __mul__(self, other: Any) -> Series: ...

    def __mul__(self, other: Any) -> Series | DataFrame | Expr:
        if isinstance(other, pl.Expr):
            return F.lit(self) * other
        if self.dtype.is_temporal() and not isinstance(self.dtype, Duration):
            msg = "first cast to integer before multiplying datelike dtypes"
            raise TypeError(msg)
        if isinstance(other, (int, float)) and (
            self.dtype.is_decimal() or isinstance(self.dtype, Duration)
        ):
            return self.to_frame().select(F.col(self.name) * other).to_series()
        elif isinstance(other, pl.DataFrame):
            return other * self
        else:
            return self._arithmetic(other, "mul", "mul_<>")

    @overload
    def __mod__(self, other: Expr) -> Expr: ...

    @overload
    def __mod__(self, other: Any) -> Series: ...

    def __mod__(self, other: Any) -> Series | Expr:
        if isinstance(other, pl.Expr):
            return F.lit(self).__mod__(other)

View on GitHub (pinned to df599052da)

Solutions

  1. Cast to integer before multiplying: `s.cast(pl.Int64) * n`.
  2. Use dt accessors for the quantity you actually want scaled: `s.dt.epoch('d') * n`.
  3. If you intended to shift a date rather than scale it, add a duration instead: `s + pl.duration(days=n)`.
  4. Fix upstream dtype: specify `schema_overrides` at read time so the column stays numeric.

Example fix

// before
dates = pl.Series([date(2024,1,1)]).cast(pl.Date)
dates * 2  # TypeError

// after
dates.cast(pl.Int64) * 2
# shifting, not scaling:
dates + pl.duration(days=2)
Defensive patterns

Strategy: type-guard

Validate before calling

if s.dtype.is_temporal() and not isinstance(s.dtype, pl.Duration):
    s = s.cast(pl.Int64)
result = s * n

Type guard

def supports_mul(s: pl.Series) -> bool:
    return not (s.dtype.is_temporal() and not isinstance(s.dtype, pl.Duration))

Try / catch

try:
    out = s * n
except TypeError as e:
    if 'multiplying datelike' not in str(e):
        raise
    out = s.cast(pl.Int64) * n

Prevention

When it happens

Trigger: Calling `*` on a Series where self.dtype.is_temporal() and not Duration, with a non-Expr right operand: `date_series * 2`, `datetime_series * 1.5`. Also fires for `s * pl.DataFrame(...)`? No - the DataFrame branch is checked after the raise, so `date_series * df` also raises here.

Common situations: Attempting to scale epoch-like columns that arrived as Date/Datetime; converting 'days since epoch' style columns where the dtype drifted to Date during CSV inference; copying unit-test math from integer columns onto date columns.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/280f3cf72e42529b. Report an issue: GitHub.