Skip to content

Commit 8f271a3

Browse files
committed
Fix time encoding regression
1 parent d5f1785 commit 8f271a3

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
@@ -38,6 +38,12 @@ Deprecations
3838
Bug fixes
3939
~~~~~~~~~
4040

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

4248
Documentation
4349
~~~~~~~~~~~~~

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)