diff --git a/doc/whats-new.rst b/doc/whats-new.rst index d2f951dabe1..23af750060c 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -46,6 +46,9 @@ Bug Fixes By `Justus Magin `_. - Avoid casting custom indexes in ``Dataset.drop_attrs`` (:pull:`10961`) By `Justus Magin `_. +- Support decoding unsigned integers to ``np.timedelta64``. + By `Deepak Cherian `_. + Documentation ~~~~~~~~~~~~~ diff --git a/xarray/coding/times.py b/xarray/coding/times.py index 7b56d64814b..d45e8e4dc9f 100644 --- a/xarray/coding/times.py +++ b/xarray/coding/times.py @@ -626,6 +626,8 @@ def _numbers_to_timedelta( nan = np.asarray(np.isnan(flat_num)) elif flat_num.dtype.kind == "i": nan = np.asarray(flat_num == np.iinfo(np.int64).min) + elif flat_num.dtype.kind == "u": + nan = np.broadcast_to(np.asarray(False), flat_num.shape) # in case we need to change the unit, we fix the numbers here # this should be safe, as errors would have been raised above diff --git a/xarray/tests/test_coding_times.py b/xarray/tests/test_coding_times.py index 8261681849f..dc0bcf64543 100644 --- a/xarray/tests/test_coding_times.py +++ b/xarray/tests/test_coding_times.py @@ -1950,6 +1950,15 @@ def test_decode_timedelta_via_dtype( assert decoded.dtype == expected_dtype +@pytest.mark.parametrize("dtype", [np.uint64, np.int64, np.float64]) +def test_decode_timedelta_dtypes(dtype) -> None: + encoded = Variable(["time"], np.arange(10), {"units": "seconds"}) + coder = CFTimedeltaCoder(time_unit="s") + decoded = coder.decode(encoded) + assert decoded.dtype.kind == "m" + assert_equal(coder.encode(decoded), encoded) + + def test_lazy_decode_timedelta_unexpected_dtype() -> None: attrs = {"units": "seconds"} encoded = Variable(["time"], [0, 0.5, 1], attrs=attrs)