Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/whatsnew/v3.1.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ Datetimelike
^^^^^^^^^^^^
- Bug in :class:`Timestamp` constructor where passing ``np.str_`` objects would fail in Cython string parsing (:issue:`48974`)
- Bug in :class:`Timestamp` constructor, :class:`Timedelta` constructor, :func:`to_datetime`, and :func:`to_timedelta` with non-round ``float`` input and ``unit`` failing to raise when the value is just outside the representable bounds (:issue:`57366`)
- Bug in :func:`date_range` where ``inclusive`` parameter failed to filter endpoints when only ``start`` and ``periods`` or ``end`` and ``periods`` were specified (:issue:`46331`)
- Bug in :func:`to_datetime` and :func:`to_timedelta` on ARM platforms where round ``float`` values outside the int64 domain (e.g. ``float(2**63)``) could silently produce incorrect results instead of raising (:issue:`64619`)
- Bug in :func:`to_datetime` and :func:`to_timedelta` where ``uint64`` values greater than ``int64`` max silently overflowed instead of raising :class:`OutOfBoundsDatetime` or :class:`OutOfBoundsTimedelta` (:issue:`60677`)
- Bug in :meth:`DatetimeArray.isin` and :meth:`TimedeltaArray.isin` where mismatched resolutions could silently truncate finer-resolution values, leading to false matches (:issue:`64545`)
Expand Down
16 changes: 14 additions & 2 deletions pandas/core/arrays/datetimes.py
Original file line number Diff line number Diff line change
Expand Up @@ -553,8 +553,20 @@ def _generate_range(
if not left_inclusive and not right_inclusive:
i8values = i8values[1:-1]
else:
start_i8 = Timestamp(start)._value
end_i8 = Timestamp(end)._value
start_i8 = (
Timestamp(start)._value
if start is not None
else i8values[0]
if len(i8values)
else 0
)
end_i8 = (
Timestamp(end)._value
if end is not None
else i8values[-1]
if len(i8values)
else 0
)
if not left_inclusive or not right_inclusive:
if not left_inclusive and len(i8values) and i8values[0] == start_i8:
i8values = i8values[1:]
Expand Down
32 changes: 32 additions & 0 deletions pandas/tests/indexes/datetimes/test_date_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,38 @@ def test_range_where_start_equal_end(self, inclusive_endpoints_fixture):

tm.assert_index_equal(result, expected)

@pytest.mark.parametrize(
"inclusive, expected_values",
[
("both", ["2020-06-01", "2020-06-02", "2020-06-03", "2020-06-04"]),
("left", ["2020-06-01", "2020-06-02", "2020-06-03"]),
("right", ["2020-06-02", "2020-06-03", "2020-06-04"]),
("neither", ["2020-06-02", "2020-06-03"]),
],
)
def test_inclusive_with_periods_and_start(self, inclusive, expected_values):
# GH#46331 - inclusive should filter endpoints even when
# only start+periods is provided (end is not specified)
result = date_range(start="2020-06-01", periods=4, inclusive=inclusive)
expected = DatetimeIndex(expected_values, freq="D")
tm.assert_index_equal(result, expected)

@pytest.mark.parametrize(
"inclusive, expected_values",
[
("both", ["2020-06-01", "2020-06-02", "2020-06-03", "2020-06-04"]),
("left", ["2020-06-01", "2020-06-02", "2020-06-03"]),
("right", ["2020-06-02", "2020-06-03", "2020-06-04"]),
("neither", ["2020-06-02", "2020-06-03"]),
],
)
def test_inclusive_with_periods_and_end(self, inclusive, expected_values):
# GH#46331 - inclusive should filter endpoints even when
# only end+periods is provided (start is not specified)
result = date_range(end="2020-06-04", periods=4, inclusive=inclusive)
expected = DatetimeIndex(expected_values, freq="D")
tm.assert_index_equal(result, expected)

def test_freq_dateoffset_with_relateivedelta_nanos(self):
# GH 46877
freq = DateOffset(hours=10, days=57, nanoseconds=3)
Expand Down
Loading