From 963c4802273a0e8db53bff59658cbab863facadf Mon Sep 17 00:00:00 2001 From: David Kleindienst Date: Mon, 2 Jan 2023 16:05:55 +0100 Subject: [PATCH 1/9] Fix BusinessHour times 0 and add tests --- pandas/_libs/tslibs/offsets.pyx | 9 +++++++-- pandas/tests/tseries/offsets/test_business_hour.py | 5 ++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx index 0bc9751694e9f..b0c75bca0b1c2 100644 --- a/pandas/_libs/tslibs/offsets.pyx +++ b/pandas/_libs/tslibs/offsets.pyx @@ -1847,15 +1847,20 @@ cdef class BusinessHour(BusinessMixin): earliest_start = self.start[0] latest_start = self.start[-1] + if self.n == 0: + is_same_sign = sign > 0 + else: + is_same_sign = self.n * sign >=0 + if not self.next_bday.is_on_offset(other): # today is not business day other = other + sign * self.next_bday - if self.n * sign >= 0: + if is_same_sign: hour, minute = earliest_start.hour, earliest_start.minute else: hour, minute = latest_start.hour, latest_start.minute else: - if self.n * sign >= 0: + if is_same_sign: if latest_start < other.time(): # current time is after latest starting time in today other = other + sign * self.next_bday diff --git a/pandas/tests/tseries/offsets/test_business_hour.py b/pandas/tests/tseries/offsets/test_business_hour.py index 79e7a5ff67010..78e1c363d2cb7 100644 --- a/pandas/tests/tseries/offsets/test_business_hour.py +++ b/pandas/tests/tseries/offsets/test_business_hour.py @@ -231,8 +231,9 @@ def test_add_datetime( assert offset8 + dt == datetime(2014, 7, 1, 11) assert offset9 + dt == datetime(2014, 7, 1, 22) assert offset10 + dt == datetime(2014, 7, 1, 1) + assert dt + 0 * offset1 == dt - def test_sub(self, dt, offset2, _offset): + def test_sub(self, dt, offset1, offset2, _offset): off = offset2 msg = "Cannot subtract datetime from offset" with pytest.raises(TypeError, match=msg): @@ -241,6 +242,8 @@ def test_sub(self, dt, offset2, _offset): assert dt - offset2 == dt + _offset(-3) + assert dt - 0 * offset1 == dt + def testRollback1( self, dt, From ea608408a9c6f1fbd214c15abd8828f2c32849e7 Mon Sep 17 00:00:00 2001 From: David Kleindienst Date: Mon, 2 Jan 2023 16:15:11 +0100 Subject: [PATCH 2/9] Codestyle --- pandas/_libs/tslibs/offsets.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx index b0c75bca0b1c2..e32195216c101 100644 --- a/pandas/_libs/tslibs/offsets.pyx +++ b/pandas/_libs/tslibs/offsets.pyx @@ -1850,7 +1850,7 @@ cdef class BusinessHour(BusinessMixin): if self.n == 0: is_same_sign = sign > 0 else: - is_same_sign = self.n * sign >=0 + is_same_sign = self.n * sign >= 0 if not self.next_bday.is_on_offset(other): # today is not business day From 68ffc84fa0029806c88be7d918cb770aa7035c4f Mon Sep 17 00:00:00 2001 From: David Kleindienst Date: Mon, 2 Jan 2023 16:23:47 +0100 Subject: [PATCH 3/9] Codestyle --- pandas/_libs/tslibs/offsets.pyx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/_libs/tslibs/offsets.pyx b/pandas/_libs/tslibs/offsets.pyx index e32195216c101..b59d17321d8bf 100644 --- a/pandas/_libs/tslibs/offsets.pyx +++ b/pandas/_libs/tslibs/offsets.pyx @@ -1849,7 +1849,7 @@ cdef class BusinessHour(BusinessMixin): if self.n == 0: is_same_sign = sign > 0 - else: + else: is_same_sign = self.n * sign >= 0 if not self.next_bday.is_on_offset(other): From 3cd8bf45cc50201db47ade512529c85c37c3e5eb Mon Sep 17 00:00:00 2001 From: David Kleindienst Date: Mon, 2 Jan 2023 19:23:37 +0100 Subject: [PATCH 4/9] Add test & whatsnew --- doc/source/whatsnew/v1.5.3.rst | 2 +- pandas/tests/tseries/offsets/test_business_hour.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.5.3.rst b/doc/source/whatsnew/v1.5.3.rst index 0cb8796e3fb5d..be0f75b7ef405 100644 --- a/doc/source/whatsnew/v1.5.3.rst +++ b/doc/source/whatsnew/v1.5.3.rst @@ -30,7 +30,7 @@ Bug fixes - Bug in :meth:`.Styler.to_excel` leading to error when unrecognized ``border-style`` (e.g. ``"hair"``) provided to Excel writers (:issue:`48649`) - Bug when chaining several :meth:`.Styler.concat` calls, only the last styler was concatenated (:issue:`49207`) - Fixed bug when instantiating a :class:`DataFrame` subclass inheriting from ``typing.Generic`` that triggered a ``UserWarning`` on python 3.11 (:issue:`49649`) -- +- Fixed bug in :class:`BusinessHour` that could cause creation of `DatetimeIndex` to fail (:issue:`#49835`) .. --------------------------------------------------------------------------- .. _whatsnew_153.other: diff --git a/pandas/tests/tseries/offsets/test_business_hour.py b/pandas/tests/tseries/offsets/test_business_hour.py index 78e1c363d2cb7..eb4a6897df017 100644 --- a/pandas/tests/tseries/offsets/test_business_hour.py +++ b/pandas/tests/tseries/offsets/test_business_hour.py @@ -975,6 +975,10 @@ def test_datetimeindex(self): for idx in [idx1, idx2, idx3]: tm.assert_index_equal(idx, expected) + idx4 = date_range(start="2014-07-01 10:00", freq="BH", periods=1) + expected4 = DatetimeIndex(["2014-07-01 10:00"], freq="BH") + tm.assert_index_equal(idx4, expected4) + def test_bday_ignores_timedeltas(self): idx = date_range("2010/02/01", "2010/02/10", freq="12H") t1 = idx + BDay(offset=Timedelta(3, unit="H")) From 61ee4269402f62e3f9f855b4a41fdfbfac97ddc2 Mon Sep 17 00:00:00 2001 From: David Kleindienst Date: Mon, 2 Jan 2023 19:48:28 +0100 Subject: [PATCH 5/9] Whatsnew formatting --- doc/source/whatsnew/v1.5.3.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.5.3.rst b/doc/source/whatsnew/v1.5.3.rst index be0f75b7ef405..a69efa999f6f0 100644 --- a/doc/source/whatsnew/v1.5.3.rst +++ b/doc/source/whatsnew/v1.5.3.rst @@ -30,7 +30,7 @@ Bug fixes - Bug in :meth:`.Styler.to_excel` leading to error when unrecognized ``border-style`` (e.g. ``"hair"``) provided to Excel writers (:issue:`48649`) - Bug when chaining several :meth:`.Styler.concat` calls, only the last styler was concatenated (:issue:`49207`) - Fixed bug when instantiating a :class:`DataFrame` subclass inheriting from ``typing.Generic`` that triggered a ``UserWarning`` on python 3.11 (:issue:`49649`) -- Fixed bug in :class:`BusinessHour` that could cause creation of `DatetimeIndex` to fail (:issue:`#49835`) +- Fixed bug in :class:`BusinessHour` that could cause creation of ``DatetimeIndex`` to fail (:issue:`#49835`) .. --------------------------------------------------------------------------- .. _whatsnew_153.other: From ea6a308789e744db582b06cb084ed4f41502f1e0 Mon Sep 17 00:00:00 2001 From: David Kleindienst Date: Wed, 4 Jan 2023 08:52:13 +0100 Subject: [PATCH 6/9] Separate tests --- pandas/tests/tseries/offsets/test_business_hour.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pandas/tests/tseries/offsets/test_business_hour.py b/pandas/tests/tseries/offsets/test_business_hour.py index eb4a6897df017..319cc053d5d7d 100644 --- a/pandas/tests/tseries/offsets/test_business_hour.py +++ b/pandas/tests/tseries/offsets/test_business_hour.py @@ -231,9 +231,8 @@ def test_add_datetime( assert offset8 + dt == datetime(2014, 7, 1, 11) assert offset9 + dt == datetime(2014, 7, 1, 22) assert offset10 + dt == datetime(2014, 7, 1, 1) - assert dt + 0 * offset1 == dt - def test_sub(self, dt, offset1, offset2, _offset): + def test_sub(self, dt, offset2, _offset): off = offset2 msg = "Cannot subtract datetime from offset" with pytest.raises(TypeError, match=msg): @@ -242,7 +241,11 @@ def test_sub(self, dt, offset1, offset2, _offset): assert dt - offset2 == dt + _offset(-3) + def test_multiply_by_zero(self, dt, offset1, offset2): assert dt - 0 * offset1 == dt + assert dt + 0 * offset1 == dt + assert dt - 0 * offset2 == dt + assert dt + 0 * offset2 == dt def testRollback1( self, @@ -975,6 +978,8 @@ def test_datetimeindex(self): for idx in [idx1, idx2, idx3]: tm.assert_index_equal(idx, expected) + def test_short_datetimeindex_creation(self): + # gh-49835 idx4 = date_range(start="2014-07-01 10:00", freq="BH", periods=1) expected4 = DatetimeIndex(["2014-07-01 10:00"], freq="BH") tm.assert_index_equal(idx4, expected4) From 7c25c882984a86e4499643508a3f1265883ade39 Mon Sep 17 00:00:00 2001 From: David Kleindienst Date: Wed, 4 Jan 2023 09:02:54 +0100 Subject: [PATCH 7/9] Whatsnew changes --- doc/source/whatsnew/v1.5.3.rst | 2 +- doc/source/whatsnew/v2.0.0.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v1.5.3.rst b/doc/source/whatsnew/v1.5.3.rst index a69efa999f6f0..0cb8796e3fb5d 100644 --- a/doc/source/whatsnew/v1.5.3.rst +++ b/doc/source/whatsnew/v1.5.3.rst @@ -30,7 +30,7 @@ Bug fixes - Bug in :meth:`.Styler.to_excel` leading to error when unrecognized ``border-style`` (e.g. ``"hair"``) provided to Excel writers (:issue:`48649`) - Bug when chaining several :meth:`.Styler.concat` calls, only the last styler was concatenated (:issue:`49207`) - Fixed bug when instantiating a :class:`DataFrame` subclass inheriting from ``typing.Generic`` that triggered a ``UserWarning`` on python 3.11 (:issue:`49649`) -- Fixed bug in :class:`BusinessHour` that could cause creation of ``DatetimeIndex`` to fail (:issue:`#49835`) +- .. --------------------------------------------------------------------------- .. _whatsnew_153.other: diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index b1387e9717079..632a5a7cdc56f 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -876,7 +876,7 @@ Indexing - Bug in :meth:`DataFrame.iloc` raising ``IndexError`` when indexer is a :class:`Series` with numeric extension array dtype (:issue:`49521`) - Bug in :func:`~DataFrame.describe` when formatting percentiles in the resulting index showed more decimals than needed (:issue:`46362`) - Bug in :meth:`DataFrame.compare` does not recognize differences when comparing ``NA`` with value in nullable dtypes (:issue:`48939`) -- +- Bug in :class:`BusinessHour` would cause creation of ``DatetimeIndex`` to fail when no opening hour was included in the index (:issue:`#49835`) Missing ^^^^^^^ From 06e8e5b3fdadb0dc625960f9a59bd8aa4cbdff27 Mon Sep 17 00:00:00 2001 From: David Kleindienst Date: Wed, 4 Jan 2023 09:05:30 +0100 Subject: [PATCH 8/9] whatsnew added class reference --- doc/source/whatsnew/v2.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 632a5a7cdc56f..f9a176a3feb93 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -876,7 +876,7 @@ Indexing - Bug in :meth:`DataFrame.iloc` raising ``IndexError`` when indexer is a :class:`Series` with numeric extension array dtype (:issue:`49521`) - Bug in :func:`~DataFrame.describe` when formatting percentiles in the resulting index showed more decimals than needed (:issue:`46362`) - Bug in :meth:`DataFrame.compare` does not recognize differences when comparing ``NA`` with value in nullable dtypes (:issue:`48939`) -- Bug in :class:`BusinessHour` would cause creation of ``DatetimeIndex`` to fail when no opening hour was included in the index (:issue:`#49835`) +- Bug in :class:`BusinessHour` would cause creation of :class:`DatetimeIndex` to fail when no opening hour was included in the index (:issue:`#49835`) Missing ^^^^^^^ From 6727efe201f9a7f39bd679a7b49f8f133cbc570d Mon Sep 17 00:00:00 2001 From: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> Date: Wed, 4 Jan 2023 10:06:40 -0800 Subject: [PATCH 9/9] Update doc/source/whatsnew/v2.0.0.rst --- doc/source/whatsnew/v2.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index a8bda704946ef..c35a0abb3a389 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -881,7 +881,7 @@ Indexing - Bug in :func:`~DataFrame.describe` when formatting percentiles in the resulting index showed more decimals than needed (:issue:`46362`) - Bug in :meth:`DataFrame.compare` does not recognize differences when comparing ``NA`` with value in nullable dtypes (:issue:`48939`) - Bug in :meth:`DataFrame.isetitem` coercing extension array dtypes in :class:`DataFrame` to object (:issue:`49922`) -- Bug in :class:`BusinessHour` would cause creation of :class:`DatetimeIndex` to fail when no opening hour was included in the index (:issue:`#49835`) +- Bug in :class:`BusinessHour` would cause creation of :class:`DatetimeIndex` to fail when no opening hour was included in the index (:issue:`49835`) - Missing