Skip to content

Commit 1b0012a

Browse files
Fix time encoding regression (#8272)
1 parent 2cd8f96 commit 1b0012a

File tree

3 files changed

+16
-4
lines changed

3 files changed

+16
-4
lines changed

doc/whats-new.rst

+6
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,12 @@ Bug fixes
5050
when the operation was a no-op. (:issue:`8266`)
5151
By `Simon Hansen <https://github.com/hoxbro>`_.
5252

53+
- Fix datetime encoding precision loss regression introduced in the previous
54+
release for datetimes encoded with units requiring floating point values, and
55+
a reference date not equal to the first value of the datetime array
56+
(:issue:`8271`, :pull:`8272`). By `Spencer Clark
57+
<https://github.com/spencerkclark>`_.
58+
5359

5460
Documentation
5561
~~~~~~~~~~~~~

xarray/coding/times.py

+2-1
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

+8-3
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)