Skip to content

Commit e3f7d26

Browse files
committed
BUG: Timedelta.round() raises ZeroDivisionError when internal unit is 's' and target frequency is sub-second
1 parent 039a339 commit e3f7d26

3 files changed

Lines changed: 24 additions & 0 deletions

File tree

doc/source/whatsnew/v3.0.2.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Fixed regressions
2222
~~~~~~~~~~~~~~~~~
2323
- Fixed regression in :meth:`HDFStore.select` where the ``where`` clause on a datetime index silently returned empty results when the index had non-nanosecond resolution (:issue:`64310`)
2424
- Fixed regression in :meth:`Series.interpolate` where ``limit_direction="both"`` with ``limit`` greater than the Series length raised ``ValueError`` (:issue:`64322`)
25+
- Fixed regression in :meth:`Timedelta.round`, :meth:`Timedelta.floor`, and :meth:`Timedelta.ceil` raising ``ZeroDivisionError`` for sub-second ``freq`` (:issue:`64828`)
2526

2627
.. ---------------------------------------------------------------------------
2728
.. _whatsnew_302.bug_fixes:

pandas/_libs/tslibs/timedeltas.pyx

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2343,8 +2343,24 @@ class Timedelta(_Timedelta):
23432343
cdef:
23442344
int64_t result, unit
23452345
ndarray[int64_t] arr
2346+
_Timedelta td_ns
23462347

23472348
unit = get_unit_for_round(freq, self._creso)
2349+
if unit == 0:
2350+
unit = get_unit_for_round(freq, NPY_FR_ns)
2351+
if unit == 0:
2352+
raise ValueError("Division by zero in rounding")
2353+
td_ns = (<_Timedelta>self)._as_creso(NPY_FR_ns, round_ok=True)
2354+
arr = np.array([td_ns._value], dtype="i8")
2355+
try:
2356+
result = round_nsint64(arr, mode, unit)[0]
2357+
except OverflowError as err:
2358+
raise OutOfBoundsTimedelta(
2359+
f"Cannot round {self} to freq={freq} without overflow"
2360+
) from err
2361+
return (<_Timedelta>Timedelta._from_value_and_reso(
2362+
result, NPY_FR_ns
2363+
))._as_creso((<_Timedelta>self)._creso, round_ok=True)
23482364

23492365
arr = np.array([self._value], dtype="i8")
23502366
try:

pandas/tests/scalar/timedelta/methods/test_round.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,10 @@ def test_round_non_nano(self, unit):
185185
res = td.ceil("min")
186186
assert res == Timedelta("1 days 02:35:00")
187187
assert res._creso == td._creso
188+
189+
def test_round_freq_finer_than_resolution(self):
190+
# GH#64828
191+
td = Timedelta(1.0, unit="days")
192+
assert td.round("100ms") == Timedelta("1 days 00:00:00")
193+
assert td.floor("100ms") == Timedelta("1 days 00:00:00")
194+
assert td.ceil("100ms") == Timedelta("1 days 00:00:00")

0 commit comments

Comments
 (0)