Skip to content

Commit b11d29b

Browse files
committed
Fix time encoding regression
1 parent d5f1785 commit b11d29b

File tree

3 files changed

+15
-4
lines changed

3 files changed

+15
-4
lines changed

doc/whats-new.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@ Deprecations
3838
Bug fixes
3939
~~~~~~~~~
4040

41+
- Fix datetime encoding precision loss regression introduced in previous
42+
release for datetimes encoded with units requiring floating point values, and
43+
a reference date not equal to the minimum of the datetime array
44+
(:issue:`8271`). By `Spencer Clark <https://github.com/spencerkclark>`_.
45+
4146

4247
Documentation
4348
~~~~~~~~~~~~~

xarray/coding/times.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -714,7 +714,8 @@ def encode_cf_datetime(
714714
if data_units != units:
715715
# this accounts for differences in the reference times
716716
ref_delta = abs(data_ref_date - ref_date).to_timedelta64()
717-
if ref_delta > np.timedelta64(0, "ns"):
717+
data_delta = _time_units_to_timedelta64(needed_units)
718+
if (ref_delta % data_delta) > np.timedelta64(0, "ns"):
718719
needed_units = _infer_time_units_from_diff(ref_delta)
719720

720721
# needed time delta to encode faithfully to int64

xarray/tests/test_coding_times.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1363,18 +1363,23 @@ def test_roundtrip_timedelta64_nanosecond_precision_warning() -> None:
13631363

13641364

13651365
def test_roundtrip_float_times() -> None:
1366+
# Regression test for GitHub issue #8271
13661367
fill_value = 20.0
1367-
times = [np.datetime64("2000-01-01 12:00:00", "ns"), np.datetime64("NaT", "ns")]
1368+
times = [
1369+
np.datetime64("1970-01-01 00:00:00", "ns"),
1370+
np.datetime64("1970-01-01 06:00:00", "ns"),
1371+
np.datetime64("NaT", "ns"),
1372+
]
13681373

1369-
units = "days since 2000-01-01"
1374+
units = "days since 1960-01-01"
13701375
var = Variable(
13711376
["time"],
13721377
times,
13731378
encoding=dict(dtype=np.float64, _FillValue=fill_value, units=units),
13741379
)
13751380

13761381
encoded_var = conventions.encode_cf_variable(var)
1377-
np.testing.assert_array_equal(encoded_var, np.array([0.5, 20.0]))
1382+
np.testing.assert_array_equal(encoded_var, np.array([3653, 3653.25, 20.0]))
13781383
assert encoded_var.attrs["units"] == units
13791384
assert encoded_var.attrs["_FillValue"] == fill_value
13801385

0 commit comments

Comments
 (0)