Description
What happened:
xarray.cftime_range
does not accept dates that use base classcftime.datetime
objects.
What you expected to happen:
I expected xarray.cftime_range
to raise an exception that this is an unsupported cftime.datetime
type and for the documentation to reflect this.
Minimal Complete Verifiable Example:
import cftime
import xarray
date = cftime.datetime(10,1,1)
xarray.cftime_range(date, periods=3, freq='Y')
Anything else we need to know?:
Returns this error:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-29-d090ea15e436> in <module>
2 import xarray
3 date = cftime.datetime(10,1,1)
----> 4 xarray.cftime_range(date, periods=3, freq='Y')
/g/data3/hh5/public/apps/miniconda3/envs/analysis3-20.07/lib/python3.7/site-packages/xarray/coding/cftime_offsets.py in cftime_range(start, end, periods, freq, normalize, name, closed, calendar)
973 else:
974 offset = to_offset(freq)
--> 975 dates = np.array(list(_generate_range(start, end, periods, offset)))
976
977 left_closed = False
/g/data3/hh5/public/apps/miniconda3/envs/analysis3-20.07/lib/python3.7/site-packages/xarray/coding/cftime_offsets.py in _generate_range(start, end, periods, offset)
744 """
745 if start:
--> 746 start = offset.rollforward(start)
747
748 if end:
/g/data3/hh5/public/apps/miniconda3/envs/analysis3-20.07/lib/python3.7/site-packages/xarray/coding/cftime_offsets.py in rollforward(self, date)
526 def rollforward(self, date):
527 """Roll date forward to nearest end of year"""
--> 528 if self.onOffset(date):
529 return date
530 else:
/g/data3/hh5/public/apps/miniconda3/envs/analysis3-20.07/lib/python3.7/site-packages/xarray/coding/cftime_offsets.py in onOffset(self, date)
522 """Check if the given date is in the set of possible dates created
523 using a length-one version of this offset class."""
--> 524 return date.day == _days_in_month(date) and date.month == self.month
525
526 def rollforward(self, date):
/g/data3/hh5/public/apps/miniconda3/envs/analysis3-20.07/lib/python3.7/site-packages/xarray/coding/cftime_offsets.py in _days_in_month(date)
195 else:
196 reference = type(date)(date.year, date.month + 1, 1)
--> 197 return (reference - timedelta(days=1)).day
198
199
TypeError: unsupported operand type(s) for -: 'cftime._cftime.datetime' and 'datetime.timedelta'
Works if a datetime
object with a calendar is used:
import cftime
import xarray
date = cftime.DatetimeGregorian(10,1,1)
xarray.cftime_range(date, periods=3, freq='Y')
Returns:
CFTimeIndex([0010-12-31 00:00:00, 0011-12-31 00:00:00, 0012-12-31 00:00:00], dtype='object')
as expected.
The error occurs here
https://github.com/pydata/xarray/blob/master/xarray/coding/cftime_offsets.py#L197
because this operation is not defined for the base class
https://github.com/Unidata/cftime/blob/master/cftime/_cftime.pyx#L1054
The relevant tests all seem to use datetime strings which are by default standard
calendar:
https://github.com/pydata/xarray/blob/master/xarray/coding/cftime_offsets.py#L788
Environment:
Output of xr.show_versions()
INSTALLED VERSIONS
commit: None
python: 3.7.8 | packaged by conda-forge | (default, Jul 31 2020, 02:25:08)
[GCC 7.5.0]
python-bits: 64
OS: Linux
OS-release: 2.6.32-754.18.2.el6.x86_64
machine: x86_64
processor: x86_64
byteorder: little
LC_ALL: en_AU.utf8
LANG: en_AU.UTF-8
LOCALE: en_AU.UTF-8
libhdf5: 1.10.5
libnetcdf: 4.7.4
xarray: 0.16.0
pandas: 1.1.0
numpy: 1.19.1
scipy: 1.5.2
netCDF4: 1.5.3
pydap: installed
h5netcdf: 0.8.1
h5py: 2.10.0
Nio: 1.5.5
zarr: 2.4.0
cftime: 1.0.3.4
nc_time_axis: 1.2.0
PseudoNetCDF: None
rasterio: 1.1.5
cfgrib: 0.9.8.4
iris: 2.4.0
bottleneck: 1.3.2
dask: 2.22.0
distributed: 2.22.0
matplotlib: 3.3.0
cartopy: 0.18.0
seaborn: 0.10.1
numbagg: None
pint: 0.14
setuptools: 49.2.0.post20200712
pip: 20.1.1
conda: installed
pytest: 6.0.1
IPython: 7.17.0
sphinx: 3.2.0