From 346457df84633ab869b88bbf959e78758cd58f84 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Sun, 12 May 2024 23:58:09 +0200 Subject: [PATCH 1/4] bug-DatetimeIndex-is_year_start-breaks-on-freq-BusinessMonthStart --- pandas/_libs/tslibs/fields.pyx | 3 ++- pandas/tests/indexes/datetimes/test_scalar_compat.py | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/pandas/_libs/tslibs/fields.pyx b/pandas/_libs/tslibs/fields.pyx index 399a5c2e96cd5..24e619d81979c 100644 --- a/pandas/_libs/tslibs/fields.pyx +++ b/pandas/_libs/tslibs/fields.pyx @@ -253,7 +253,8 @@ def get_start_end_field( # month of year. Other offsets use month, startingMonth as ending # month of year. - if freq_name.lstrip("B")[0:2] in ["MS", "QS", "YS"]: + if (freq_name.lstrip("B")[0:2] in ["MS", "QS", "YS"]) or ( + freq_name.lstrip("CB")[0:2] in ["MS", "QS", "YS"]): end_month = 12 if month_kw == 1 else month_kw - 1 start_month = month_kw else: diff --git a/pandas/tests/indexes/datetimes/test_scalar_compat.py b/pandas/tests/indexes/datetimes/test_scalar_compat.py index 5831846c9ceb6..f215a9591e49e 100644 --- a/pandas/tests/indexes/datetimes/test_scalar_compat.py +++ b/pandas/tests/indexes/datetimes/test_scalar_compat.py @@ -343,3 +343,8 @@ def test_dti_is_year_start_freq_custom_business_day_with_digit(self): msg = "Custom business days is not supported by is_year_start" with pytest.raises(ValueError, match=msg): dr.is_year_start + + def test_dti_is_year_start_freq_business_month_start_with(self): + dr = date_range("2020-01-01", periods=1, freq="CBMS") + print(dr.is_year_start) + # assert all(dr.is_year_start) From 6197e695dcdd4d077fcca973743921799aba5f86 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Mon, 13 May 2024 00:36:16 +0200 Subject: [PATCH 2/4] correct def get_start_end_field --- pandas/_libs/tslibs/fields.pyx | 3 +-- pandas/tests/indexes/datetimes/test_scalar_compat.py | 5 ++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/pandas/_libs/tslibs/fields.pyx b/pandas/_libs/tslibs/fields.pyx index 24e619d81979c..a4531769f7d51 100644 --- a/pandas/_libs/tslibs/fields.pyx +++ b/pandas/_libs/tslibs/fields.pyx @@ -253,8 +253,7 @@ def get_start_end_field( # month of year. Other offsets use month, startingMonth as ending # month of year. - if (freq_name.lstrip("B")[0:2] in ["MS", "QS", "YS"]) or ( - freq_name.lstrip("CB")[0:2] in ["MS", "QS", "YS"]): + if freq_name[0:2] in ["MS", "QS", "YS"]: end_month = 12 if month_kw == 1 else month_kw - 1 start_month = month_kw else: diff --git a/pandas/tests/indexes/datetimes/test_scalar_compat.py b/pandas/tests/indexes/datetimes/test_scalar_compat.py index f215a9591e49e..1cc6f13a74477 100644 --- a/pandas/tests/indexes/datetimes/test_scalar_compat.py +++ b/pandas/tests/indexes/datetimes/test_scalar_compat.py @@ -345,6 +345,5 @@ def test_dti_is_year_start_freq_custom_business_day_with_digit(self): dr.is_year_start def test_dti_is_year_start_freq_business_month_start_with(self): - dr = date_range("2020-01-01", periods=1, freq="CBMS") - print(dr.is_year_start) - # assert all(dr.is_year_start) + dr = date_range("2020-01-01", periods=1, freq="BMS") + assert all(dr.is_year_start) From a9f4bb3d45ef788932eb14f4149c788f9127022b Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Mon, 3 Jun 2024 22:25:42 +0200 Subject: [PATCH 3/4] fixup --- pandas/_libs/tslibs/fields.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/_libs/tslibs/fields.pyx b/pandas/_libs/tslibs/fields.pyx index a4531769f7d51..91594c95a02ed 100644 --- a/pandas/_libs/tslibs/fields.pyx +++ b/pandas/_libs/tslibs/fields.pyx @@ -253,7 +253,7 @@ def get_start_end_field( # month of year. Other offsets use month, startingMonth as ending # month of year. - if freq_name[0:2] in ["MS", "QS", "YS"]: + if freq_name.lstrip("B")[0:2] in ["QS", "YS"]: end_month = 12 if month_kw == 1 else month_kw - 1 start_month = month_kw else: From 4e0b00d168259a1e20ab4e692a0b9cd2c7fc3288 Mon Sep 17 00:00:00 2001 From: Natalia Mokeeva Date: Tue, 4 Jun 2024 14:58:07 +0200 Subject: [PATCH 4/4] parametrize test, and a note to v3.0.0 --- doc/source/whatsnew/v3.0.0.rst | 1 + pandas/tests/indexes/datetimes/test_scalar_compat.py | 9 +++++++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 865996bdf8892..f266e94e64b79 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -456,6 +456,7 @@ Datetimelike - Bug in :func:`tseries.api.guess_datetime_format` would fail to infer time format when "%Y" == "%H%M" (:issue:`57452`) - Bug in :meth:`DatetimeIndex.is_year_start` and :meth:`DatetimeIndex.is_quarter_start` does not raise on Custom business days frequencies bigger then "1C" (:issue:`58664`) - Bug in :meth:`DatetimeIndex.is_year_start` and :meth:`DatetimeIndex.is_quarter_start` returning ``False`` on double-digit frequencies (:issue:`58523`) +- Bug in :meth:`DatetimeIndex.is_year_start` and :meth:`DatetimeIndex.is_quarter_start` where using Business month begin frequency (:issue:`58729`) - Bug in setting scalar values with mismatched resolution into arrays with non-nanosecond ``datetime64``, ``timedelta64`` or :class:`DatetimeTZDtype` incorrectly truncating those scalars (:issue:`56410`) Timedelta diff --git a/pandas/tests/indexes/datetimes/test_scalar_compat.py b/pandas/tests/indexes/datetimes/test_scalar_compat.py index 1cc6f13a74477..e58487923b7df 100644 --- a/pandas/tests/indexes/datetimes/test_scalar_compat.py +++ b/pandas/tests/indexes/datetimes/test_scalar_compat.py @@ -344,6 +344,11 @@ def test_dti_is_year_start_freq_custom_business_day_with_digit(self): with pytest.raises(ValueError, match=msg): dr.is_year_start - def test_dti_is_year_start_freq_business_month_start_with(self): - dr = date_range("2020-01-01", periods=1, freq="BMS") + @pytest.mark.parametrize("freq", ["BMS", offsets.BusinessMonthBegin()]) + def test_dti_is_year_quarter_start_freq_business_month_begin(self, freq): + # GH#58729 + dr = date_range("2020-01-01", periods=1, freq=freq) assert all(dr.is_year_start) + + dr = date_range("2020-01-01", periods=1, freq=freq) + assert all(dr.is_quarter_start)