pandas-dev/pandas · error · NotImplementedError
nonexistent is not supported.
Error message
nonexistent is not supported.
What it means
Raised by ArrowExtensionArray._round_temporally when `nonexistent != "raise"`. The pyarrow-backed dt.ceil/floor/round cannot resolve nonexistent (skipped) times that appear during DST spring-forward; only the default 'raise' is supported. Passing 'shift_forward', 'shift_backward', 'NaT', or a timedelta triggers NotImplementedError.
Source
Thrown at pandas/core/arrays/arrow/array.py:4174
def _dt_normalize(self) -> Self:
result = pc.floor_temporal(self._pa_array, 1, "day")
return self._from_pyarrow_array(result)
def _dt_strftime(self, format: str) -> Self:
result = pc.strftime(self._pa_array, format=format)
return self._from_pyarrow_array(result)
def _round_temporally(
self,
method: Literal["ceil", "floor", "round"],
freq,
ambiguous: TimeAmbiguous = "raise",
nonexistent: TimeNonexistent = "raise",
) -> Self:
if ambiguous != "raise":
raise NotImplementedError("ambiguous is not supported.")
if nonexistent != "raise":
raise NotImplementedError("nonexistent is not supported.")
offset = to_offset(freq)
if offset is None:
raise ValueError(f"Must specify a valid frequency: {freq}")
pa_supported_unit = {
"Y": "year",
"YS": "year",
"Q": "quarter",
"QS": "quarter",
"M": "month",
"MS": "month",
"W": "week",
"D": "day",
"h": "hour",
"min": "minute",
"s": "second",
"ms": "millisecond",
"us": "microsecond",
"ns": "nanosecond",View on GitHub (pinned to 71959b8cb9)
Solutions
- Leave nonexistent at default 'raise' and filter/adjust the offending timestamps beforehand.
- Round in UTC then convert back: `s.dt.tz_convert("UTC").dt.floor("h").dt.tz_convert("US/Eastern")`.
- Cast to datetime64[ns, tz] for the operation: `s.astype("datetime64[ns, US/Eastern]").dt.floor("h", nonexistent="shift_forward")`.
- Drop DST timezone for rounding if precision loss is acceptable.
Example fix
# before
s.dt.floor("h", nonexistent="shift_forward") # NotImplementedError
# after
out = s.dt.tz_convert("UTC").dt.floor("h").dt.tz_convert("US/Eastern") Defensive patterns
Strategy: validation
Validate before calling
def safe_round(s, freq, method="floor", ambiguous="raise"):
if getattr(s.dt, "tz", None) is not None:
return s.dt.tz_convert("UTC").dt.__getattribute__(method)(freq, ambiguous=ambiguous).dt.tz_convert(s.dt.tz)
return s.dt.__getattribute__(method)(freq, ambiguous=ambiguous) Type guard
def needs_utc_rounding(s) -> bool:
return getattr(s.dt, "tz", None) is not None Try / catch
try:
out = s.dt.ceil(freq, nonexistent=nonexistent)
except NotImplementedError:
out = s.dt.tz_convert("UTC").dt.ceil(freq).dt.tz_convert(s.dt.tz) Prevention
- Keep nonexistent='raise' (default) for pyarrow timestamp rounding.
- Round tz-aware pyarrow timestamps in UTC, then convert back.
- Filter out DST-gap times before rounding with nonexistent='raise'.
When it happens
Trigger: Calling `s.dt.ceil("h", nonexistent="shift_forward")` on a tz-aware pyarrow timestamp Series whose values fall in a DST gap (e.g. 02:00-03:00 on US spring-forward). Reached through dt.ceil/floor/round on timestamp[pyarrow, tz=...].
Common situations: Localizing/rounding logs or sensor data timestamped in a tz with DST; porting rounding code from numpy-backed datetime64 that accepted nonexistent kwargs.
Related errors
- ambiguous is not supported.
- {ambiguous=} is not supported
- {nonexistent=} is not supported
- as_unit not implemented for {pa_type}
- replace is not supported with a re.Pattern, callable repl, c
AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07).
Data as JSON: /api/errors/b8c5d489c8ecb48a.
Report an issue: GitHub.