Repository: pandas-dev/pandas

Issue:
DOC: "Invalid datetime unit in metadata string "[d]""
http://pandas-docs.github.io/pandas-docs-travis/timeseries.html#time-deltas-conversions

```
In [253]: to_timedelta(np.arange(5),unit='d')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-253-bab05b276f33> in <module>()
----> 1 to_timedelta(np.arange(5),unit='d')

/home/travis/virtualenv/python2.7_with_system_site_packages/local/lib/python2.7/site-packages/pandas/tseries/timedeltas.pyc in to_timedelta(arg, box, unit)
     61         return Series(values, index=arg.index, name=arg.name, dtype='m8[ns]')
     62     elif is_list_like(arg):
---> 63         return _convert_listlike(arg, box=box, unit=unit)
     64 
     65     # ...so it must be a scalar value. Return scalar.

/home/travis/virtualenv/python2.7_with_system_site_packages/local/lib/python2.7/site-packages/pandas/tseries/timedeltas.pyc in _convert_listlike(arg, box, unit)
     42         elif is_integer_dtype(arg):
     43             # these are shortcutable
---> 44             value = arg.astype('timedelta64[{0}]'.format(unit)).astype('timedelta64[ns]')
     45         else:
     46             try:

TypeError: Invalid datetime unit in metadata string "[d]"
```



Discussion:
The same error in whatsnew of 0.13: http://pandas-docs.github.io/pandas-docs-travis/whatsnew.html#id11

Did there change something recently?

yeh...i think i made a change, guess I broke this; numpy doesn't like 'd' in timedelta64, only 'D'
(which is odd if you ask me,  but ok).


Resolving patch:
diff --git a/pandas/tseries/timedeltas.py b/pandas/tseries/timedeltas.py
--- a/pandas/tseries/timedeltas.py
+++ b/pandas/tseries/timedeltas.py
@@ -40,6 +40,8 @@ def _convert_listlike(arg, box, unit):
         if is_timedelta64_dtype(arg):
             value = arg.astype('timedelta64[ns]')
         elif is_integer_dtype(arg):
+            unit = _validate_timedelta_unit(unit)
+
             # these are shortcutable
             value = arg.astype('timedelta64[{0}]'.format(unit)).astype('timedelta64[ns]')
         else:
@@ -65,6 +67,15 @@ def _convert_listlike(arg, box, unit):
     # ...so it must be a scalar value. Return scalar.
     return _coerce_scalar_to_timedelta_type(arg, unit=unit)
 
+def _validate_timedelta_unit(arg):
+    """ provide validation / translation for timedelta short units """
+
+    if re.search("Y|W|D",arg,re.IGNORECASE) or arg == 'M':
+        return arg.upper()
+    elif re.search("h|m|s|ms|us|ns",arg,re.IGNORECASE):
+        return arg.lower()
+    raise ValueError("invalid timedelta unit {0} provided".format(arg))
+
 _short_search = re.compile(
     "^\s*(?P<neg>-?)\s*(?P<value>\d*\.?\d*)\s*(?P<unit>d|s|ms|us|ns)?\s*$",re.IGNORECASE)
 _full_search = re.compile(


Test patch:
diff --git a/pandas/tseries/tests/test_timedeltas.py b/pandas/tseries/tests/test_timedeltas.py
--- a/pandas/tseries/tests/test_timedeltas.py
+++ b/pandas/tseries/tests/test_timedeltas.py
@@ -199,6 +199,17 @@ def conv(v):
         expected = Series([ np.timedelta64(1,'D') ]*5)
         tm.assert_series_equal(result, expected)
 
+        # validate all units
+        # GH 6855
+        for unit in ['Y','M','W','D','y','w','d']:
+            result = to_timedelta(np.arange(5),unit=unit)
+            expected = Series([ np.timedelta64(i,unit.upper()) for i in np.arange(5).tolist() ])
+            tm.assert_series_equal(result, expected)
+        for unit in ['h','m','s','ms','us','ns','H','S','MS','US','NS']:
+            result = to_timedelta(np.arange(5),unit=unit)
+            expected = Series([ np.timedelta64(i,unit.lower()) for i in np.arange(5).tolist() ])
+            tm.assert_series_equal(result, expected)
+
         # these will error
         self.assertRaises(ValueError, lambda : to_timedelta(['1h']))
         self.assertRaises(ValueError, lambda : to_timedelta(['1m']))