Skip to content

Commit 0d858c4

Browse files
fjdiodjreback
authored andcommitted
ENH: add iso-format support to to_timedelta (#21877) (#21933)
1 parent 1a586e2 commit 0d858c4

File tree

4 files changed

+18
-1
lines changed

4 files changed

+18
-1
lines changed

doc/source/whatsnew/v0.24.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ Other Enhancements
119119
- :meth:`Series.nlargest`, :meth:`Series.nsmallest`, :meth:`DataFrame.nlargest`, and :meth:`DataFrame.nsmallest` now accept the value ``"all"`` for the ``keep`` argument. This keeps all ties for the nth largest/smallest value (:issue:`16818`)
120120
- :class:`IntervalIndex` has gained the :meth:`~IntervalIndex.set_closed` method to change the existing ``closed`` value (:issue:`21670`)
121121
- :func:`~DataFrame.to_csv` and :func:`~DataFrame.to_json` now support ``compression='infer'`` to infer compression based on filename (:issue:`15008`)
122+
- :func:`to_timedelta` now supports iso-formated timedelta strings (:issue:`21877`)
122123
-
123124

124125
.. _whatsnew_0240.api_breaking:

pandas/_libs/tslibs/timedeltas.pyx

+5-1
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,11 @@ cpdef convert_to_timedelta64(object ts, object unit):
183183
ts = cast_from_unit(ts, unit)
184184
ts = np.timedelta64(ts)
185185
elif is_string_object(ts):
186-
ts = np.timedelta64(parse_timedelta_string(ts))
186+
if len(ts) > 0 and ts[0] == 'P':
187+
ts = parse_iso_format_string(ts)
188+
else:
189+
ts = parse_timedelta_string(ts)
190+
ts = np.timedelta64(ts)
187191
elif hasattr(ts, 'delta'):
188192
ts = np.timedelta64(delta_to_nanoseconds(ts), 'ns')
189193

pandas/tests/indexes/timedeltas/test_construction.py

+7
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,13 @@ def test_constructor(self):
4444
tm.assert_index_equal(TimedeltaIndex([400, 450, 1200], unit='ms'),
4545
expected)
4646

47+
def test_constructor_iso(self):
48+
# GH #21877
49+
expected = timedelta_range('1s', periods=9, freq='s')
50+
durations = ['P0DT0H0M{}S'.format(i) for i in range(1, 10)]
51+
result = to_timedelta(durations)
52+
tm.assert_index_equal(result, expected)
53+
4754
def test_constructor_coverage(self):
4855
rng = timedelta_range('1 days', periods=10.5)
4956
exp = timedelta_range('1 days', periods=10)

pandas/tests/scalar/timedelta/test_timedelta.py

+5
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,11 @@ def check(value):
233233
assert tup.microseconds == 999
234234
assert tup.nanoseconds == 0
235235

236+
def test_iso_conversion(self):
237+
# GH #21877
238+
expected = Timedelta(1, unit='s')
239+
assert to_timedelta('P0DT0H0M1S') == expected
240+
236241
def test_nat_converters(self):
237242
assert to_timedelta('nat', box=False).astype('int64') == iNaT
238243
assert to_timedelta('nan', box=False).astype('int64') == iNaT

0 commit comments

Comments
 (0)