diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 1f15ad99bb3..478db357aec 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -62,6 +62,8 @@ New Features now accept a ``dim_order`` parameter allowing to specify the resulting dataframe's dimensions order (:issue:`4331`, :pull:`4333`). By `Thomas Zilio `_. +- Expose ``use_cftime`` option in :py:func:`~xarray.open_zarr` (:issue:`2886`, :pull:`3229`) + By `Samnan Rahee `_ and `Anderson Banihirwe `_. Bug fixes diff --git a/xarray/backends/zarr.py b/xarray/backends/zarr.py index 89ba97b3fa5..f74fddb694e 100644 --- a/xarray/backends/zarr.py +++ b/xarray/backends/zarr.py @@ -510,6 +510,7 @@ def open_zarr( overwrite_encoded_chunks=False, chunk_store=None, decode_timedelta=None, + use_cftime=None, **kwargs, ): """Load and decode a dataset from a Zarr store. @@ -576,6 +577,16 @@ def open_zarr( {'days', 'hours', 'minutes', 'seconds', 'milliseconds', 'microseconds'} into timedelta objects. If False, leave them encoded as numbers. If None (default), assume the same value of decode_time. + use_cftime: bool, optional + Only relevant if encoded dates come from a standard calendar + (e.g. "gregorian", "proleptic_gregorian", "standard", or not + specified). If None (default), attempt to decode times to + ``np.datetime64[ns]`` objects; if this is not possible, decode times to + ``cftime.datetime`` objects. If True, always decode times to + ``cftime.datetime`` objects, regardless of whether or not they can be + represented using ``np.datetime64[ns]`` objects. If False, always + decode times to ``np.datetime64[ns]`` objects; if this is not possible + raise an error. Returns ------- @@ -637,6 +648,7 @@ def maybe_decode_store(store, lock=False): decode_coords=decode_coords, drop_variables=drop_variables, decode_timedelta=decode_timedelta, + use_cftime=use_cftime, ) # TODO: this is where we would apply caching diff --git a/xarray/tests/test_backends.py b/xarray/tests/test_backends.py index 1173fed0055..fe93f5a9777 100644 --- a/xarray/tests/test_backends.py +++ b/xarray/tests/test_backends.py @@ -2025,6 +2025,16 @@ def test_chunk_encoding_with_partial_dask_chunks(self): ) as ds1: assert_equal(ds1, original) + @requires_cftime + def test_open_zarr_use_cftime(self): + ds = create_test_data() + with self.create_zarr_target() as store_target: + ds.to_zarr(store_target, consolidated=True) + ds_a = xr.open_zarr(store_target, consolidated=True) + assert_identical(ds, ds_a) + ds_b = xr.open_zarr(store_target, consolidated=True, use_cftime=True) + assert xr.coding.times.contains_cftime_datetimes(ds_b.time) + @requires_zarr class TestZarrDictStore(ZarrBase):