Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions src/xray/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ def decode_cf_datetime(num_dates, units, calendar=None):
or max_date > datetime(2262, 4, 11)):
dates = nc4.num2date(num_dates, units, calendar)
else:
# we can safely use np.datetime64
# we can safely use np.datetime64 with nanosecond precision (pandas
# likes ns precision so it can directly make DatetimeIndex objects)
if min_num == max_num:
# we can't safely divide by max_num - min_num
dates = np.repeat(np.datetime64(min_date), num_dates.size)
Expand All @@ -158,8 +159,8 @@ def decode_cf_datetime(num_dates, units, calendar=None):
denominator = max_num - min_num
dates = (time_delta * numerator / denominator
+ np.datetime64(min_date))
# restore original shape
dates = dates.reshape(num_dates.shape)
# restore original shape and ensure dates are given in ns
dates = dates.reshape(num_dates.shape).astype('M8[ns]')
return dates


Expand Down Expand Up @@ -203,11 +204,11 @@ def encode_cf_datetime(dates, units=None, calendar=None):
and np.issubdtype(dates.dtype, np.datetime64)):
# for now, don't bother doing any trickery like decode_cf_datetime to
# convert dates to numbers faster
# TODO: don't use pandas.DatetimeIndex to do the conversion
dates = pd.Index(dates.reshape(-1)).to_pydatetime().reshape(dates.shape)
# note: numpy's broken datetime conversion only works for us precision
dates = np.asarray(dates).astype('M8[us]').astype(datetime)

if hasattr(dates, 'ndim') and dates.ndim == 0:
# date2num doesn't like 0-dimensional arguments
# unpack dates because date2num doesn't like 0-dimensional arguments
dates = dates.item()

num = nc4.date2num(dates, units, calendar)
Expand Down
12 changes: 11 additions & 1 deletion test/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,17 @@ def test_cf_datetime(self):
for calendar in ['standard', 'gregorian', 'proleptic_gregorian']:
expected = nc4.num2date(num_dates, units, calendar)
actual = utils.decode_cf_datetime(num_dates, units, calendar)
self.assertArrayEqual(expected, actual)
if (isinstance(actual, np.ndarray)
and np.issubdtype(actual.dtype, np.datetime64)):
self.assertEqual(actual.dtype, np.dtype('M8[ns]'))
# For some reason, numpy 1.8 does not compare ns precision
# datetime64 arrays as equal to arrays of datetime objects,
# but it works for us precision. Thus, convert to us
# precision for the actual array equal comparison...
actual_cmp = actual.astype('M8[us]')
else:
actual_cmp = actual
self.assertArrayEqual(expected, actual_cmp)
encoded, _, _ = utils.encode_cf_datetime(actual, units, calendar)
self.assertArrayEqual(num_dates, np.around(encoded))
if (hasattr(num_dates, 'ndim') and num_dates.ndim == 1
Expand Down