pandas-dev/pandas · error · ValueError

Supported units are 's', 'ms', 'us', 'ns'

Error message

Supported units are 's', 'ms', 'us', 'ns'

What it means

Raised by DatetimeLikeArrayMixin.as_unit when the requested unit is not one of the four supported time resolutions. pandas datetime/timedelta storage only supports seconds, milliseconds, microseconds, and nanoseconds; finer (e.g. picoseconds) or coarser (minutes, hours) units are not valid internal storage units, though they may appear as frequencies.

Source

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

        >>> idx = pd.DatetimeIndex(["2020-01-02 01:02:03.004005006"])
        >>> idx
        DatetimeIndex(['2020-01-02 01:02:03.004005006'],
                      dtype='datetime64[ns]', freq=None)
        >>> idx.as_unit("s")
        DatetimeIndex(['2020-01-02 01:02:03'], dtype='datetime64[s]', freq=None)

        For :class:`pandas.TimedeltaIndex`:

        >>> tdelta_idx = pd.to_timedelta(["1 day 3 min 2 us 42 ns"])
        >>> tdelta_idx
        TimedeltaIndex(['1 days 00:03:00.000002042'],
                        dtype='timedelta64[ns]', freq=None)
        >>> tdelta_idx.as_unit("s")
        TimedeltaIndex(['1 days 00:03:00'], dtype='timedelta64[s]', freq=None)
        """
        if unit not in ["s", "ms", "us", "ns"]:
            raise ValueError("Supported units are 's', 'ms', 'us', 'ns'")

        dtype = np.dtype(f"{self.dtype.kind}8[{unit}]")
        new_values = astype_overflowsafe(self._ndarray, dtype, round_ok=round_ok)

        if isinstance(self.dtype, np.dtype):
            new_dtype = new_values.dtype
        else:
            tz = cast("DatetimeArray", self).tz
            new_dtype = DatetimeTZDtype(tz=tz, unit=unit)

        return type(self)._simple_new(
            new_values,
            dtype=new_dtype,
        )

    # TODO: annotate other as DatetimeArray | TimedeltaArray | Timestamp | Timedelta
    #  with the return type matching input type.  TypeVar?
    def _ensure_matching_resos(self, other):

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Pass one of 's', 'ms', 'us', 'ns' to as_unit.
  2. If you wanted minute/hourly spacing, that is a frequency — use .asfreq() / date_range(freq=...) instead of as_unit.
  3. If you need finer-than-nanosecond resolution, use a pyarrow-backed dtype (pd.ArrowDtype(pa.timestamp('ns'))) — picosecond storage is still unsupported.

Example fix

# before
idx.as_unit('m')

# after (minutes are a frequency, not a storage unit)
idx.as_unit('s')            # coarsest storage unit
idx.asfreq('min')           # resample to a minute grid
Defensive patterns

Strategy: validation

Validate before calling

VALID_UNITS = {'s','ms','us','ns'}
if unit not in VALID_UNITS:
    raise ValueError(f'unit must be one of {VALID_UNITS}, got {unit!r}')

Type guard

from typing import Literal
def is_valid_time_unit(u: str) -> bool:
    return u in {'s','ms','us','ns'}
# or: isinstance guard via Literal['s','ms','us','ns']

Try / catch

try:
    idx.as_unit(unit)
except ValueError as e:
    if 'Supported units are' in str(e):
        idx.as_unit('ns')
    else: raise

Prevention

When it happens

Trigger: idx.as_unit('m') (intending minutes), idx.as_unit('us5'), idx.as_unit('ps'), or passing an offset alias like 'h'/'T' to as_unit. Also reached by Series.dt.as_unit with the wrong alias.

Common situations: Confusing frequency aliases ('T'/'min', 'h') with storage units. Reading code that uses numpy-style unit strings. Wanting sub-nanosecond precision from Arrow-backed data.

Related errors


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