From daea5df23209e8b7148067fd6272e2eed9f40bf1 Mon Sep 17 00:00:00 2001 From: Hauke Schulz <43613877+observingClouds@users.noreply.github.com> Date: Tue, 16 Mar 2021 11:00:23 +0100 Subject: [PATCH] Add date attribute to datetime accessor (#4994) * add date accessor to accessor_dt.py (GH4983) * raise error when using date with CFTimeIndex * Add tests * Mention changes in whats-new.rst * Add DatetimeAccessor.date to api-hidden.rst * Add attribute to api.rst * Change AttributeError message --- doc/api-hidden.rst | 1 + doc/api.rst | 1 + doc/whats-new.rst | 3 ++- xarray/core/accessor_dt.py | 8 ++++++++ xarray/tests/test_accessor_dt.py | 14 ++++++++++++++ 5 files changed, 26 insertions(+), 1 deletion(-) diff --git a/doc/api-hidden.rst b/doc/api-hidden.rst index 15d4759e9e0..f5e9348d4eb 100644 --- a/doc/api-hidden.rst +++ b/doc/api-hidden.rst @@ -287,6 +287,7 @@ core.accessor_dt.DatetimeAccessor.floor core.accessor_dt.DatetimeAccessor.round core.accessor_dt.DatetimeAccessor.strftime + core.accessor_dt.DatetimeAccessor.date core.accessor_dt.DatetimeAccessor.day core.accessor_dt.DatetimeAccessor.dayofweek core.accessor_dt.DatetimeAccessor.dayofyear diff --git a/doc/api.rst b/doc/api.rst index f58b89b0766..7e13c2feefe 100644 --- a/doc/api.rst +++ b/doc/api.rst @@ -507,6 +507,7 @@ Datetimelike properties DataArray.dt.daysinmonth DataArray.dt.season DataArray.dt.time + DataArray.dt.date DataArray.dt.is_month_start DataArray.dt.is_month_end DataArray.dt.is_quarter_end diff --git a/doc/whats-new.rst b/doc/whats-new.rst index e58f80cfcd3..e0c11fefd36 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -51,12 +51,13 @@ New Features grant from the `Chan Zuckerberg Initiative `_ and developed by `B-Open `_. By `Aureliana Barghini `_ and `Alessandro Amici `_. +- :py:attr:`~core.accessor_dt.DatetimeAccessor.date` added (:issue:`4983`, :pull:`4994`). + By `Hauke Schulz `_. - Implement ``__getitem__`` for both :py:class:`~core.groupby.DatasetGroupBy` and :py:class:`~core.groupby.DataArrayGroupBy`, inspired by pandas' :py:meth:`~pandas.core.groupby.GroupBy.get_group`. By `Deepak Cherian `_. - Breaking changes ~~~~~~~~~~~~~~~~ - :py:func:`open_dataset` and :py:func:`open_dataarray` now accept only the first argument diff --git a/xarray/core/accessor_dt.py b/xarray/core/accessor_dt.py index 561d5d30a79..1d4ef755fa0 100644 --- a/xarray/core/accessor_dt.py +++ b/xarray/core/accessor_dt.py @@ -31,6 +31,10 @@ def _access_through_cftimeindex(values, name): if name == "season": months = values_as_cftimeindex.month field_values = _season_from_months(months) + elif name == "date": + raise AttributeError( + "'CFTimeIndex' object has no attribute `date`. Consider using the floor method instead, for instance: `.time.dt.floor('D')`." + ) else: field_values = getattr(values_as_cftimeindex, name) return field_values.reshape(values.shape) @@ -415,6 +419,10 @@ def weekofyear(self): "time", "Timestamps corresponding to datetimes", object ) + date = Properties._tslib_field_accessor( + "date", "Date corresponding to datetimes", object + ) + is_month_start = Properties._tslib_field_accessor( "is_month_start", "Indicates whether the date is the first day of the month.", diff --git a/xarray/tests/test_accessor_dt.py b/xarray/tests/test_accessor_dt.py index 984bfc763bc..adfa2bed33b 100644 --- a/xarray/tests/test_accessor_dt.py +++ b/xarray/tests/test_accessor_dt.py @@ -59,6 +59,8 @@ def setup(self): "weekday", "dayofyear", "quarter", + "date", + "time", "is_month_start", "is_month_end", "is_quarter_start", @@ -144,6 +146,8 @@ def test_not_datetime_type(self): "weekday", "dayofyear", "quarter", + "date", + "time", "is_month_start", "is_month_end", "is_quarter_start", @@ -430,6 +434,16 @@ def test_isocalendar_cftime(data): data.time.dt.isocalendar() +@requires_cftime +def test_date_cftime(data): + + with raises_regex( + AttributeError, + r"'CFTimeIndex' object has no attribute `date`. Consider using the floor method instead, for instance: `.time.dt.floor\('D'\)`.", + ): + data.time.dt.date() + + @requires_cftime @pytest.mark.filterwarnings("ignore::RuntimeWarning") def test_cftime_strftime_access(data):