pandas-dev/pandas · error · TypeError

Casting to unit-less dtype 'datetime64' is not supported…

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 array is tz-naive, the target dtype is a numpy datetime64 kind 'M' that differs from the current dtype, and the target is 'unit-less' (i.e. exactly `datetime64` with no `[ns]`/`[s]`/etc. unit). numpy's bare `datetime64` is ambiguous about resolution, so pandas refuses to pick one silently. You must state a concrete unit like `datetime64[ns]`.

Solutions

  1. Pass an explicit unit: `obj.astype('datetime64[ns]')` (or `[s]`, `[ms]`, `[us]`).
  2. If the unit string is built dynamically, ensure the `[unit]` suffix is appended before passing to astype.
  3. If you actually want unit-less numpy semantics, call `.to_numpy()` and handle the resulting ndarray yourself.

Example fix

// before
arr = dta.astype('datetime64')

// after
arr = dta.astype('datetime64[ns]')
Defensive patterns

Strategy: validation

Validate before calling

import pandas as pd

SUPPORTED_UNITS = {'s', 'ms', 'us', 'ns'}

def ensure_unit(dtype_str: str) -> str:
    if dtype_str == 'datetime64' or dtype_str == 'M8':
        return 'datetime64[ns]'
    return dtype_str

Type guard

import re
def is_unitful_datetime_dtype(s: str) -> bool:
    return bool(re.fullmatch(r'datetime64\[(s|ms|us|ns)\]', s))

Try / catch

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

Prevention

When it happens

Trigger: Calling `dta.astype('datetime64')`, `dta.astype(np.dtype('M8'))`, or `dta.astype('datetime64')` on a tz-naive DatetimeArray/Index whose dtype already differs from the bare M8 dtype. Distinguished from [312] in that [312] fires at construction/validation time for any input; this fires inside astype specifically.

Common situations: User forms a dtype string dynamically (e.g. truncating `'datetime64[ns]'` to `'datetime64'`) or passes an old code path that pre-dates unit-aware datetime64. Confusing numpy's tolerance of unitless datetime64 with pandas' requirement.

Related errors


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

Appendix: 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 3b7651241d)