pandas-dev/pandas · error · TypeError

cannot subtract a datelike from a

Error message

cannot subtract a datelike from a {type(self).__name__}

What it means

Raised by _sub_datetimelike_scalar when self.dtype.kind != 'M'. Subtracting a datetime scalar (datetime / np.datetime64) is only defined for DatetimeArray (point - point -> TimedeltaArray); subtracting a datetime from a TimedeltaArray or PeriodArray is meaningless and rejected.

Solutions

  1. Ensure the left operand is a DatetimeArray (dtype kind 'M') before subtracting a datetime scalar.
  2. If working with TimedeltaArray, subtract a Timedelta scalar instead.
  3. Convert Periods to timestamps with .to_timestamp() if you need point-in-time subtraction.

Example fix

// before
res = tda - pd.Timestamp('2020-01-01')  # TypeError

// after
res = dta - pd.Timestamp('2020-01-01')  # use a DatetimeArray
Defensive patterns

Strategy: type-guard

Validate before calling

import pandas as pd

def sub_datetime_scalar(arr, other):
    if arr.dtype.kind != 'M':
        raise TypeError('left operand must be a DatetimeArray to subtract a datetime scalar')
    return arr - other

Type guard

import pandas as pd

def is_datetime_array(a) -> bool:
    return getattr(a, 'dtype', None) is not None and a.dtype.kind == 'M'

Try / catch

try:
    res = arr - other
except TypeError as e:
    if 'cannot subtract a datelike' in str(e):
        # convert other to a Timedelta if the array is a TimedeltaArray
        res = arr - pd.Timedelta(other)
    else:
        raise

Prevention

When it happens

Trigger: TimedeltaArray - Timestamp(...); PeriodArray - datetime.datetime(...); any non-datetime datetimelike array minus a datelike scalar.

Common situations: Confusing a duration column with a date column when computing elapsed time; Period-indexed data being differenced against an absolute date.

Related errors


AI-assisted analysis of pandas-dev/pandas@3b7651241d (2026-08-11). Data as JSON: /api/errors/bf001520f8f349d9. Report an issue: GitHub.

Appendix: source

Thrown at pandas/core/arrays/datetimelike.py:1092

        res_values = result.view(f"M8[{self.unit}]")
        return DatetimeArray._simple_new(res_values, dtype=dtype)

    @final
    def _add_datetime_arraylike(self, other: DatetimeArray) -> DatetimeArray:
        if not lib.is_np_dtype(self.dtype, "m"):
            raise TypeError(
                f"cannot add {type(self).__name__} and {type(other).__name__}"
            )

        # defer to DatetimeArray.__add__
        return other + self

    @final
    def _sub_datetimelike_scalar(
        self, other: datetime | np.datetime64
    ) -> TimedeltaArray:
        if self.dtype.kind != "M":
            raise TypeError(f"cannot subtract a datelike from a {type(self).__name__}")

        self = cast("DatetimeArray", self)
        # subtract a datetime from myself, yielding an ndarray[timedelta64[ns]]

        if isna(other):
            # i.e. np.datetime64("NaT")
            return self - NaT

        ts = Timestamp(other)

        self, ts = self._ensure_matching_resos(ts)
        return self._sub_datetimelike(ts)

    @final
    def _sub_datetime_arraylike(self, other: DatetimeArray) -> TimedeltaArray:
        if self.dtype.kind != "M":
            raise TypeError(f"cannot subtract a datelike from a {type(self).__name__}")

View on GitHub (pinned to 3b7651241d)