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
- Pass an explicit unit: `obj.astype('datetime64[ns]')` (or `[s]`, `[ms]`, `[us]`).
- If the unit string is built dynamically, ensure the `[unit]` suffix is appended before passing to astype.
- 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
- Never build dtype strings by truncating the `[unit]` suffix.
- Validate user-supplied dtype strings before forwarding to astype.
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
- Cannot use .astype to convert from timezone-aware dtype to…
- Passing in 'datetime64' dtype with no precision is not…
- Cannot convert to ; subtypes are incompatible
- Cannot pass both a timezone-aware dtype and tz=None
- cannot supply both a tz and a dtype with a tz
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)