Repository: pandas-dev/pandas

Issue:
Timedelta ISO Format Constructor
#### Code Sample, a copy-pastable example if possible

```python
In : pd.Timedelta('1 day').isoformat()
Out: 'P1DT0H0M0S'

In : pd.Timedelta(pd.Timedelta('1 day').isoformat())
Out: ValueError: invalid abbreviation: P
```
#### Problem description

A ``Timedelta`` can be formatted as an ISO 8601 Duration, but cannot be constructed from one. This makes it difficult to natively parse and convert any ISO 8601 Durations into their respective ``Timedelta`` objects. 

For a specific example, ``write_json`` takes a ``Timedelta`` and writes it out in the ISO format, but ``read_json`` cannot reasonably parse that format back into a ``Timedelta`` object without such a constructor (see #19039)

<details>

INSTALLED VERSIONS
------------------
commit: 4319335aadd7355e54236bde2ab6dc130eedf9ad
python: 3.6.1.final.0
python-bits: 64
OS: Darwin
OS-release: 17.3.0
machine: x86_64
processor: i386
byteorder: little
LC_ALL: None
LANG: en_US.UTF-8
LOCALE: en_US.UTF-8

pandas: 0.23.0.dev0+31.g4319335aa
pytest: None
pip: 9.0.1
setuptools: 27.2.0
Cython: None
numpy: 1.13.1
scipy: 0.19.1
pyarrow: None
xarray: None
IPython: 6.1.0
sphinx: 1.6.5
patsy: None
dateutil: 2.6.1
pytz: 2017.2
blosc: None
bottleneck: None
tables: None
numexpr: None
feather: None
matplotlib: None
openpyxl: None
xlrd: None
xlwt: None
xlsxwriter: None
lxml: None
bs4: 4.6.0
html5lib: 0.999999999
sqlalchemy: None
pymysql: None
psycopg2: None
jinja2: 2.9.6
s3fs: None
fastparquet: None
pandas_gbq: None
pandas_datareader: None
</details>



Discussion:
How odd!  If you can make it possible, go for it!
This was never implemented, a patch to do so would be straightorward & welcome.

Resolving patch:
diff --git a/asv_bench/benchmarks/timedelta.py b/asv_bench/benchmarks/timedelta.py
--- a/asv_bench/benchmarks/timedelta.py
+++ b/asv_bench/benchmarks/timedelta.py
@@ -1,9 +1,40 @@
+import datetime
+
 import numpy as np
 import pandas as pd
 
 from pandas import to_timedelta, Timestamp, Timedelta
 
 
+class TimedeltaConstructor(object):
+    goal_time = 0.2
+
+    def time_from_int(self):
+        Timedelta(123456789)
+
+    def time_from_unit(self):
+        Timedelta(1, unit='d')
+
+    def time_from_components(self):
+        Timedelta(days=1, hours=2, minutes=3, seconds=4, milliseconds=5,
+                  microseconds=6, nanoseconds=7)
+
+    def time_from_datetime_timedelta(self):
+        Timedelta(datetime.timedelta(days=1, seconds=1))
+
+    def time_from_np_timedelta(self):
+        Timedelta(np.timedelta64(1, 'ms'))
+
+    def time_from_string(self):
+        Timedelta('1 days')
+
+    def time_from_iso_format(self):
+        Timedelta('P4DT12H30M5S')
+
+    def time_from_missing(self):
+        Timedelta('nat')
+
+
 class ToTimedelta(object):
     goal_time = 0.2
 


Test patch:
diff --git a/pandas/tests/scalar/test_timedelta.py b/pandas/tests/scalar/test_timedelta.py
--- a/pandas/tests/scalar/test_timedelta.py
+++ b/pandas/tests/scalar/test_timedelta.py
@@ -853,3 +853,29 @@ def test_isoformat(self):
         result = Timedelta(minutes=1).isoformat()
         expected = 'P0DT0H1M0S'
         assert result == expected
+
+    @pytest.mark.parametrize('fmt,exp', [
+        ('P6DT0H50M3.010010012S', Timedelta(days=6, minutes=50, seconds=3,
+                                            milliseconds=10, microseconds=10,
+                                            nanoseconds=12)),
+        ('P-6DT0H50M3.010010012S', Timedelta(days=-6, minutes=50, seconds=3,
+                                             milliseconds=10, microseconds=10,
+                                             nanoseconds=12)),
+        ('P4DT12H30M5S', Timedelta(days=4, hours=12, minutes=30, seconds=5)),
+        ('P0DT0H0M0.000000123S', Timedelta(nanoseconds=123)),
+        ('P0DT0H0M0.00001S', Timedelta(microseconds=10)),
+        ('P0DT0H0M0.001S', Timedelta(milliseconds=1)),
+        ('P0DT0H1M0S', Timedelta(minutes=1)),
+        ('P1DT25H61M61S', Timedelta(days=1, hours=25, minutes=61, seconds=61))
+    ])
+    def test_iso_constructor(self, fmt, exp):
+        assert Timedelta(fmt) == exp
+
+    @pytest.mark.parametrize('fmt', [
+        'PPPPPPPPPPPP', 'PDTHMS', 'P0DT999H999M999S',
+        'P1DT0H0M0.0000000000000S', 'P1DT0H0M00000000000S',
+        'P1DT0H0M0.S'])
+    def test_iso_constructor_raises(self, fmt):
+        with tm.assert_raises_regex(ValueError, 'Invalid ISO 8601 Duration '
+                                    'format - {}'.format(fmt)):
+            Timedelta(fmt)