1.. _timedeltas:
2
3{{ header }}
4
5.. _timedeltas.timedeltas:
6
7***********
8Time deltas
9***********
10
11Timedeltas are differences in times, expressed in difference units, e.g. days, hours, minutes,
12seconds. They can be both positive and negative.
13
14``Timedelta`` is a subclass of ``datetime.timedelta``, and behaves in a similar manner,
15but allows compatibility with ``np.timedelta64`` types as well as a host of custom representation,
16parsing, and attributes.
17
18Parsing
19-------
20
21You can construct a ``Timedelta`` scalar through various arguments, including `ISO 8601 Duration`_ strings.
22
23.. ipython:: python
24
25   import datetime
26
27   # strings
28   pd.Timedelta("1 days")
29   pd.Timedelta("1 days 00:00:00")
30   pd.Timedelta("1 days 2 hours")
31   pd.Timedelta("-1 days 2 min 3us")
32
33   # like datetime.timedelta
34   # note: these MUST be specified as keyword arguments
35   pd.Timedelta(days=1, seconds=1)
36
37   # integers with a unit
38   pd.Timedelta(1, unit="d")
39
40   # from a datetime.timedelta/np.timedelta64
41   pd.Timedelta(datetime.timedelta(days=1, seconds=1))
42   pd.Timedelta(np.timedelta64(1, "ms"))
43
44   # negative Timedeltas have this string repr
45   # to be more consistent with datetime.timedelta conventions
46   pd.Timedelta("-1us")
47
48   # a NaT
49   pd.Timedelta("nan")
50   pd.Timedelta("nat")
51
52   # ISO 8601 Duration strings
53   pd.Timedelta("P0DT0H1M0S")
54   pd.Timedelta("P0DT0H0M0.000000123S")
55
56:ref:`DateOffsets<timeseries.offsets>` (``Day, Hour, Minute, Second, Milli, Micro, Nano``) can also be used in construction.
57
58.. ipython:: python
59
60   pd.Timedelta(pd.offsets.Second(2))
61
62Further, operations among the scalars yield another scalar ``Timedelta``.
63
64.. ipython:: python
65
66   pd.Timedelta(pd.offsets.Day(2)) + pd.Timedelta(pd.offsets.Second(2)) + pd.Timedelta(
67       "00:00:00.000123"
68   )
69
70to_timedelta
71~~~~~~~~~~~~
72
73Using the top-level ``pd.to_timedelta``, you can convert a scalar, array, list,
74or Series from a recognized timedelta format / value into a ``Timedelta`` type.
75It will construct Series if the input is a Series, a scalar if the input is
76scalar-like, otherwise it will output a ``TimedeltaIndex``.
77
78You can parse a single string to a Timedelta:
79
80.. ipython:: python
81
82   pd.to_timedelta("1 days 06:05:01.00003")
83   pd.to_timedelta("15.5us")
84
85or a list/array of strings:
86
87.. ipython:: python
88
89   pd.to_timedelta(["1 days 06:05:01.00003", "15.5us", "nan"])
90
91The ``unit`` keyword argument specifies the unit of the Timedelta:
92
93.. ipython:: python
94
95   pd.to_timedelta(np.arange(5), unit="s")
96   pd.to_timedelta(np.arange(5), unit="d")
97
98.. _timedeltas.limitations:
99
100Timedelta limitations
101~~~~~~~~~~~~~~~~~~~~~
102
103pandas represents ``Timedeltas`` in nanosecond resolution using
10464 bit integers. As such, the 64 bit integer limits determine
105the ``Timedelta`` limits.
106
107.. ipython:: python
108
109   pd.Timedelta.min
110   pd.Timedelta.max
111
112.. _timedeltas.operations:
113
114Operations
115----------
116
117You can operate on Series/DataFrames and construct ``timedelta64[ns]`` Series through
118subtraction operations on ``datetime64[ns]`` Series, or ``Timestamps``.
119
120.. ipython:: python
121
122   s = pd.Series(pd.date_range("2012-1-1", periods=3, freq="D"))
123   td = pd.Series([pd.Timedelta(days=i) for i in range(3)])
124   df = pd.DataFrame({"A": s, "B": td})
125   df
126   df["C"] = df["A"] + df["B"]
127   df
128   df.dtypes
129
130   s - s.max()
131   s - datetime.datetime(2011, 1, 1, 3, 5)
132   s + datetime.timedelta(minutes=5)
133   s + pd.offsets.Minute(5)
134   s + pd.offsets.Minute(5) + pd.offsets.Milli(5)
135
136Operations with scalars from a ``timedelta64[ns]`` series:
137
138.. ipython:: python
139
140   y = s - s[0]
141   y
142
143Series of timedeltas with ``NaT`` values are supported:
144
145.. ipython:: python
146
147   y = s - s.shift()
148   y
149
150Elements can be set to ``NaT`` using ``np.nan`` analogously to datetimes:
151
152.. ipython:: python
153
154   y[1] = np.nan
155   y
156
157Operands can also appear in a reversed order (a singular object operated with a Series):
158
159.. ipython:: python
160
161   s.max() - s
162   datetime.datetime(2011, 1, 1, 3, 5) - s
163   datetime.timedelta(minutes=5) + s
164
165``min, max`` and the corresponding ``idxmin, idxmax`` operations are supported on frames:
166
167.. ipython:: python
168
169   A = s - pd.Timestamp("20120101") - pd.Timedelta("00:05:05")
170   B = s - pd.Series(pd.date_range("2012-1-2", periods=3, freq="D"))
171
172   df = pd.DataFrame({"A": A, "B": B})
173   df
174
175   df.min()
176   df.min(axis=1)
177
178   df.idxmin()
179   df.idxmax()
180
181``min, max, idxmin, idxmax`` operations are supported on Series as well. A scalar result will be a ``Timedelta``.
182
183.. ipython:: python
184
185   df.min().max()
186   df.min(axis=1).min()
187
188   df.min().idxmax()
189   df.min(axis=1).idxmin()
190
191You can fillna on timedeltas, passing a timedelta to get a particular value.
192
193.. ipython:: python
194
195   y.fillna(pd.Timedelta(0))
196   y.fillna(pd.Timedelta(10, unit="s"))
197   y.fillna(pd.Timedelta("-1 days, 00:00:05"))
198
199You can also negate, multiply and use ``abs`` on ``Timedeltas``:
200
201.. ipython:: python
202
203   td1 = pd.Timedelta("-1 days 2 hours 3 seconds")
204   td1
205   -1 * td1
206   -td1
207   abs(td1)
208
209.. _timedeltas.timedeltas_reductions:
210
211Reductions
212----------
213
214Numeric reduction operation for ``timedelta64[ns]`` will return ``Timedelta`` objects. As usual
215``NaT`` are skipped during evaluation.
216
217.. ipython:: python
218
219   y2 = pd.Series(
220       pd.to_timedelta(["-1 days +00:00:05", "nat", "-1 days +00:00:05", "1 days"])
221   )
222   y2
223   y2.mean()
224   y2.median()
225   y2.quantile(0.1)
226   y2.sum()
227
228.. _timedeltas.timedeltas_convert:
229
230Frequency conversion
231--------------------
232
233Timedelta Series, ``TimedeltaIndex``, and ``Timedelta`` scalars can be converted to other 'frequencies' by dividing by another timedelta,
234or by astyping to a specific timedelta type. These operations yield Series and propagate ``NaT`` -> ``nan``.
235Note that division by the NumPy scalar is true division, while astyping is equivalent of floor division.
236
237.. ipython:: python
238
239   december = pd.Series(pd.date_range("20121201", periods=4))
240   january = pd.Series(pd.date_range("20130101", periods=4))
241   td = january - december
242
243   td[2] += datetime.timedelta(minutes=5, seconds=3)
244   td[3] = np.nan
245   td
246
247   # to days
248   td / np.timedelta64(1, "D")
249   td.astype("timedelta64[D]")
250
251   # to seconds
252   td / np.timedelta64(1, "s")
253   td.astype("timedelta64[s]")
254
255   # to months (these are constant months)
256   td / np.timedelta64(1, "M")
257
258Dividing or multiplying a ``timedelta64[ns]`` Series by an integer or integer Series
259yields another ``timedelta64[ns]`` dtypes Series.
260
261.. ipython:: python
262
263   td * -1
264   td * pd.Series([1, 2, 3, 4])
265
266Rounded division (floor-division) of a ``timedelta64[ns]`` Series by a scalar
267``Timedelta`` gives a series of integers.
268
269.. ipython:: python
270
271   td // pd.Timedelta(days=3, hours=4)
272   pd.Timedelta(days=3, hours=4) // td
273
274.. _timedeltas.mod_divmod:
275
276The mod (%) and divmod operations are defined for ``Timedelta`` when operating with another timedelta-like or with a numeric argument.
277
278.. ipython:: python
279
280   pd.Timedelta(hours=37) % datetime.timedelta(hours=2)
281
282   # divmod against a timedelta-like returns a pair (int, Timedelta)
283   divmod(datetime.timedelta(hours=2), pd.Timedelta(minutes=11))
284
285   # divmod against a numeric returns a pair (Timedelta, Timedelta)
286   divmod(pd.Timedelta(hours=25), 86400000000000)
287
288Attributes
289----------
290
291You can access various components of the ``Timedelta`` or ``TimedeltaIndex`` directly using the attributes ``days,seconds,microseconds,nanoseconds``. These are identical to the values returned by ``datetime.timedelta``, in that, for example, the ``.seconds`` attribute represents the number of seconds >= 0 and < 1 day. These are signed according to whether the ``Timedelta`` is signed.
292
293These operations can also be directly accessed via the ``.dt`` property of the ``Series`` as well.
294
295.. note::
296
297   Note that the attributes are NOT the displayed values of the ``Timedelta``. Use ``.components`` to retrieve the displayed values.
298
299For a ``Series``:
300
301.. ipython:: python
302
303   td.dt.days
304   td.dt.seconds
305
306You can access the value of the fields for a scalar ``Timedelta`` directly.
307
308.. ipython:: python
309
310   tds = pd.Timedelta("31 days 5 min 3 sec")
311   tds.days
312   tds.seconds
313   (-tds).seconds
314
315You can use the ``.components`` property to access a reduced form of the timedelta. This returns a ``DataFrame`` indexed
316similarly to the ``Series``. These are the *displayed* values of the ``Timedelta``.
317
318.. ipython:: python
319
320   td.dt.components
321   td.dt.components.seconds
322
323.. _timedeltas.isoformat:
324
325You can convert a ``Timedelta`` to an `ISO 8601 Duration`_ string with the
326``.isoformat`` method
327
328.. ipython:: python
329
330    pd.Timedelta(
331        days=6, minutes=50, seconds=3, milliseconds=10, microseconds=10, nanoseconds=12
332    ).isoformat()
333
334.. _ISO 8601 Duration: https://en.wikipedia.org/wiki/ISO_8601#Durations
335
336.. _timedeltas.index:
337
338TimedeltaIndex
339--------------
340
341To generate an index with time delta, you can use either the :class:`TimedeltaIndex` or
342the :func:`timedelta_range` constructor.
343
344Using ``TimedeltaIndex`` you can pass string-like, ``Timedelta``, ``timedelta``,
345or ``np.timedelta64`` objects. Passing ``np.nan/pd.NaT/nat`` will represent missing values.
346
347.. ipython:: python
348
349   pd.TimedeltaIndex(
350       [
351           "1 days",
352           "1 days, 00:00:05",
353           np.timedelta64(2, "D"),
354           datetime.timedelta(days=2, seconds=2),
355       ]
356   )
357
358The string 'infer' can be passed in order to set the frequency of the index as the
359inferred frequency upon creation:
360
361.. ipython:: python
362
363   pd.TimedeltaIndex(["0 days", "10 days", "20 days"], freq="infer")
364
365Generating ranges of time deltas
366~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
367
368Similar to :func:`date_range`, you can construct regular ranges of a ``TimedeltaIndex``
369using :func:`timedelta_range`.  The default frequency for ``timedelta_range`` is
370calendar day:
371
372.. ipython:: python
373
374   pd.timedelta_range(start="1 days", periods=5)
375
376Various combinations of ``start``, ``end``, and ``periods`` can be used with
377``timedelta_range``:
378
379.. ipython:: python
380
381   pd.timedelta_range(start="1 days", end="5 days")
382
383   pd.timedelta_range(end="10 days", periods=4)
384
385The ``freq`` parameter can passed a variety of :ref:`frequency aliases <timeseries.offset_aliases>`:
386
387.. ipython:: python
388
389   pd.timedelta_range(start="1 days", end="2 days", freq="30T")
390
391   pd.timedelta_range(start="1 days", periods=5, freq="2D5H")
392
393
394Specifying ``start``, ``end``, and ``periods`` will generate a range of evenly spaced
395timedeltas from ``start`` to ``end`` inclusively, with ``periods`` number of elements
396in the resulting ``TimedeltaIndex``:
397
398.. ipython:: python
399
400   pd.timedelta_range("0 days", "4 days", periods=5)
401
402   pd.timedelta_range("0 days", "4 days", periods=10)
403
404Using the TimedeltaIndex
405~~~~~~~~~~~~~~~~~~~~~~~~
406
407Similarly to other of the datetime-like indices, ``DatetimeIndex`` and ``PeriodIndex``, you can use
408``TimedeltaIndex`` as the index of pandas objects.
409
410.. ipython:: python
411
412   s = pd.Series(
413       np.arange(100),
414       index=pd.timedelta_range("1 days", periods=100, freq="h"),
415   )
416   s
417
418Selections work similarly, with coercion on string-likes and slices:
419
420.. ipython:: python
421
422   s["1 day":"2 day"]
423   s["1 day 01:00:00"]
424   s[pd.Timedelta("1 day 1h")]
425
426Furthermore you can use partial string selection and the range will be inferred:
427
428.. ipython:: python
429
430   s["1 day":"1 day 5 hours"]
431
432Operations
433~~~~~~~~~~
434
435Finally, the combination of ``TimedeltaIndex`` with ``DatetimeIndex`` allow certain combination operations that are NaT preserving:
436
437.. ipython:: python
438
439   tdi = pd.TimedeltaIndex(["1 days", pd.NaT, "2 days"])
440   tdi.to_list()
441   dti = pd.date_range("20130101", periods=3)
442   dti.to_list()
443   (dti + tdi).to_list()
444   (dti - tdi).to_list()
445
446Conversions
447~~~~~~~~~~~
448
449Similarly to frequency conversion on a ``Series`` above, you can convert these indices to yield another Index.
450
451.. ipython:: python
452
453   tdi / np.timedelta64(1, "s")
454   tdi.astype("timedelta64[s]")
455
456Scalars type ops work as well. These can potentially return a *different* type of index.
457
458.. ipython:: python
459
460   # adding or timedelta and date -> datelike
461   tdi + pd.Timestamp("20130101")
462
463   # subtraction of a date and a timedelta -> datelike
464   # note that trying to subtract a date from a Timedelta will raise an exception
465   (pd.Timestamp("20130101") - tdi).to_list()
466
467   # timedelta + timedelta -> timedelta
468   tdi + pd.Timedelta("10 days")
469
470   # division can result in a Timedelta if the divisor is an integer
471   tdi / 2
472
473   # or a Float64Index if the divisor is a Timedelta
474   tdi / tdi[0]
475
476.. _timedeltas.resampling:
477
478Resampling
479----------
480
481Similar to :ref:`timeseries resampling <timeseries.resampling>`, we can resample with a ``TimedeltaIndex``.
482
483.. ipython:: python
484
485   s.resample("D").mean()
486