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 string is not one of the four supported numpy datetime/timedelta resolutions: 's', 'ms', 'us', 'ns'. pandas only stores sub-second precision down to nanoseconds and only exposes second-granularity as the coarsest supported unit, so coarser (e.g. 'm','h') or finer (e.g. 'ps') units are rejected.

Solutions

  1. Map to the nearest supported unit: use 's' for minute/hour/day precision (precision is truncated up to second).
  2. If you only need display formatting, format the timestamps as strings instead of changing the dtype unit.
  3. For sub-nanosecond needs, keep the value as an integer count or use a custom dtype; pandas cannot store it.

Example fix

// before
idx = pd.date_range('2020-01-01', periods=3)
idx.as_unit('m')  # ValueError: Supported units are 's', 'ms', 'us', 'ns'

// after
idx.as_unit('s')
Defensive patterns

Strategy: validation

Validate before calling

SUPPORTED_UNITS = {"s","ms","us","ns"}
def safe_as_unit(idx, unit):
    if unit not in SUPPORTED_UNITS:
        raise ValueError(f"unit must be one of {SUPPORTED_UNITS}, got {unit!r}")
    return idx.as_unit(unit)

Type guard

def is_supported_unit(unit: str) -> bool:
    return unit in {"s","ms","us","ns"}

Try / catch

try:
    out = idx.as_unit(unit)
except ValueError as e:
    if "Supported units are" in str(e):
        out = idx.as_unit("s")  # coarsest supported fallback
    else:
        raise

Prevention

When it happens

Trigger: Calling .as_unit('m'), .as_unit('h'), .as_unit('ps'), or any non-listed string on a DatetimeIndex/TimedeltaIndex/DatetimeArray/TimedeltaArray.

Common situations: Assuming as_unit accepts the same vocabulary as numpy's time units; passing an IUPAC-style code; copy-pasting a unit string from a different library (e.g. arrow/pendulum).

Related errors


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

Appendix: source

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

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