pandas-dev/pandas · error · TypeError

Casting to unit-less dtype 'datetime64' is not supported. Pa

Error message

Casting to unit-less dtype 'datetime64' is not supported. Pass e.g. 'datetime64[ns]' instead.

What it means

Raised by DatetimeArray.astype when the target is a unit-less numpy datetime64 (e.g. np.dtype('datetime64') or the string 'datetime64'). Unit-less datetime64 is legacy numpy and pandas requires every datetime storage to declare a resolution ('s','ms','us','ns'); accepting the bare form would leave the unit ambiguous and pick a default silently.

Source

Thrown at pandas/core/arrays/datetimes.py:743

            # TODO: preserve freq?

        elif self.tz is not None and lib.is_np_dtype(dtype, "M"):
            # pre-2.0 behavior for DTA/DTI was
            #  values.tz_convert("UTC").tz_localize(None), which did not match
            #  the Series behavior
            raise TypeError(
                "Cannot use .astype to convert from timezone-aware dtype to "
                "timezone-naive dtype. Use obj.tz_localize(None) or "
                "obj.tz_convert('UTC').tz_localize(None) instead."
            )

        elif (
            self.tz is None
            and lib.is_np_dtype(dtype, "M")
            and dtype != self.dtype
            and is_unitless(dtype)
        ):
            raise TypeError(
                "Casting to unit-less dtype 'datetime64' is not supported. "
                "Pass e.g. 'datetime64[ns]' instead."
            )

        elif isinstance(dtype, PeriodDtype):
            return self.to_period(freq=dtype.freq)
        return dtl.DatetimeLikeArrayMixin.astype(self, dtype, copy)

    # -----------------------------------------------------------------
    # Rendering Methods

    def _format_native_types(
        self, *, na_rep: str | float = "NaT", date_format=None, **kwargs
    ) -> npt.NDArray[np.object_]:
        if date_format is None and self._is_dates_only:
            # Only dates and no timezone: provide a default format
            date_format = "%Y-%m-%d"

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Specify a unit: s.astype('datetime64[ns]') (or 's','ms','us').
  2. For tz-aware data, strip the tz first (tz_localize/tz_convert) then astype to a unit-ful datetime64.
  3. If you just want a unit change, use obj.as_unit('s').

Example fix

# before
s.astype('datetime64')

# after
s.astype('datetime64[ns]')
Defensive patterns

Strategy: validation

Validate before calling

if isinstance(target, str) and target == 'datetime64':
    raise ValueError("specify a unit: 'datetime64[ns]' (or s/ms/us)")
if isinstance(target, np.dtype) and target == np.dtype('datetime64'):
    raise ValueError('unit-less datetime64 not allowed; use datetime64[ns]')

Type guard

def is_unitless_dt64(t) -> bool:
    try:
        return np.dtype(t).name == 'datetime64'  # no [unit]
    except TypeError:
        return False

Try / catch

try:
    s.astype(target)
except TypeError as e:
    if 'unit-less dtype' in str(e):
        s.astype('datetime64[ns]')
    else: raise

Prevention

When it happens

Trigger: s.astype('datetime64'); idx.astype(np.dtype('datetime64')); df['ts'].astype('datetime64') where ts is tz-naive and dtype != self.dtype.

Common situations: Old numpy idioms (np.dtype('datetime64')); tutorials/StackOverflow snippets using the bare form; config files that store dtype strings without a unit suffix.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/22093928d8f5b8d6. Report an issue: GitHub.