Skip to content

Commit e533947

Browse files
committed
BUG: DatetimeIndex with nanosecond frequency does not include end
- [x] closes #13672 - [x] tests added / passed - [x] passes ``git diff upstream/master | flake8 --diff`` - [x] whatsnew entry Author: sinhrks <[email protected]> Closes #13762 from sinhrks/date_range_nano and squashes the following commits: 0e63d70 [sinhrks] BUG: DatetimeIndex with nanosecond frequency does not include end
1 parent 9f94e6a commit e533947

File tree

4 files changed

+77
-1
lines changed

4 files changed

+77
-1
lines changed

doc/source/whatsnew/v0.19.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -746,6 +746,7 @@ Bug Fixes
746746
- Bug in invalid ``Timedelta`` arithmetic and comparison may raise ``ValueError`` rather than ``TypeError`` (:issue:`13624`)
747747
- Bug in invalid datetime parsing in ``to_datetime`` and ``DatetimeIndex`` may raise ``TypeError`` rather than ``ValueError`` (:issue:`11169`, :issue:`11287`)
748748
- Bug in ``Index`` created with tz-aware ``Timestamp`` and mismatched ``tz`` option incorrectly coerces timezone (:issue:`13692`)
749+
- Bug in ``DatetimeIndex`` with nanosecond frequency does not include timestamp specified with ``end`` (:issue:`13672`)
749750

750751
- Bug in ``Categorical.remove_unused_categories()`` changes ``.codes`` dtype to platform int (:issue:`13261`)
751752
- Bug in ``groupby`` with ``as_index=False`` returns all NaN's when grouping on multiple columns including a categorical one (:issue:`13204`)

pandas/tseries/index.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1964,7 +1964,8 @@ def _generate_regular_range(start, end, periods, offset):
19641964
b = Timestamp(start).value
19651965
# cannot just use e = Timestamp(end) + 1 because arange breaks when
19661966
# stride is too large, see GH10887
1967-
e = b + (Timestamp(end).value - b) // stride * stride + stride // 2
1967+
e = (b + (Timestamp(end).value - b) // stride * stride +
1968+
stride // 2 + 1)
19681969
# end.tz == start.tz by this point due to _generate implementation
19691970
tz = start.tz
19701971
elif start is not None:

pandas/tseries/tests/test_period.py

+9
Original file line numberDiff line numberDiff line change
@@ -1573,6 +1573,15 @@ def test_constructor_U(self):
15731573
self.assertRaises(ValueError, period_range, '2007-1-1', periods=500,
15741574
freq='X')
15751575

1576+
def test_constructor_nano(self):
1577+
idx = period_range(start=Period(ordinal=1, freq='N'),
1578+
end=Period(ordinal=4, freq='N'), freq='N')
1579+
exp = PeriodIndex([Period(ordinal=1, freq='N'),
1580+
Period(ordinal=2, freq='N'),
1581+
Period(ordinal=3, freq='N'),
1582+
Period(ordinal=4, freq='N')], freq='N')
1583+
tm.assert_index_equal(idx, exp)
1584+
15761585
def test_constructor_arrays_negative_year(self):
15771586
years = np.arange(1960, 2000, dtype=np.int64).repeat(4)
15781587
quarters = np.tile(np.array([1, 2, 3, 4], dtype=np.int64), 40)

pandas/tseries/tests/test_timeseries.py

+65
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,71 @@ def test_to_datetime_freq(self):
10751075
self.assertEqual(xp.freq, rs.freq)
10761076
self.assertEqual(xp.tzinfo, rs.tzinfo)
10771077

1078+
def test_range_edges(self):
1079+
# GH 13672
1080+
idx = DatetimeIndex(start=Timestamp('1970-01-01 00:00:00.000000001'),
1081+
end=Timestamp('1970-01-01 00:00:00.000000004'),
1082+
freq='N')
1083+
exp = DatetimeIndex(['1970-01-01 00:00:00.000000001',
1084+
'1970-01-01 00:00:00.000000002',
1085+
'1970-01-01 00:00:00.000000003',
1086+
'1970-01-01 00:00:00.000000004'])
1087+
tm.assert_index_equal(idx, exp)
1088+
1089+
idx = DatetimeIndex(start=Timestamp('1970-01-01 00:00:00.000000004'),
1090+
end=Timestamp('1970-01-01 00:00:00.000000001'),
1091+
freq='N')
1092+
exp = DatetimeIndex([])
1093+
tm.assert_index_equal(idx, exp)
1094+
1095+
idx = DatetimeIndex(start=Timestamp('1970-01-01 00:00:00.000000001'),
1096+
end=Timestamp('1970-01-01 00:00:00.000000001'),
1097+
freq='N')
1098+
exp = DatetimeIndex(['1970-01-01 00:00:00.000000001'])
1099+
tm.assert_index_equal(idx, exp)
1100+
1101+
idx = DatetimeIndex(start=Timestamp('1970-01-01 00:00:00.000001'),
1102+
end=Timestamp('1970-01-01 00:00:00.000004'),
1103+
freq='U')
1104+
exp = DatetimeIndex(['1970-01-01 00:00:00.000001',
1105+
'1970-01-01 00:00:00.000002',
1106+
'1970-01-01 00:00:00.000003',
1107+
'1970-01-01 00:00:00.000004'])
1108+
tm.assert_index_equal(idx, exp)
1109+
1110+
idx = DatetimeIndex(start=Timestamp('1970-01-01 00:00:00.001'),
1111+
end=Timestamp('1970-01-01 00:00:00.004'),
1112+
freq='L')
1113+
exp = DatetimeIndex(['1970-01-01 00:00:00.001',
1114+
'1970-01-01 00:00:00.002',
1115+
'1970-01-01 00:00:00.003',
1116+
'1970-01-01 00:00:00.004'])
1117+
tm.assert_index_equal(idx, exp)
1118+
1119+
idx = DatetimeIndex(start=Timestamp('1970-01-01 00:00:01'),
1120+
end=Timestamp('1970-01-01 00:00:04'), freq='S')
1121+
exp = DatetimeIndex(['1970-01-01 00:00:01', '1970-01-01 00:00:02',
1122+
'1970-01-01 00:00:03', '1970-01-01 00:00:04'])
1123+
tm.assert_index_equal(idx, exp)
1124+
1125+
idx = DatetimeIndex(start=Timestamp('1970-01-01 00:01'),
1126+
end=Timestamp('1970-01-01 00:04'), freq='T')
1127+
exp = DatetimeIndex(['1970-01-01 00:01', '1970-01-01 00:02',
1128+
'1970-01-01 00:03', '1970-01-01 00:04'])
1129+
tm.assert_index_equal(idx, exp)
1130+
1131+
idx = DatetimeIndex(start=Timestamp('1970-01-01 01:00'),
1132+
end=Timestamp('1970-01-01 04:00'), freq='H')
1133+
exp = DatetimeIndex(['1970-01-01 01:00', '1970-01-01 02:00',
1134+
'1970-01-01 03:00', '1970-01-01 04:00'])
1135+
tm.assert_index_equal(idx, exp)
1136+
1137+
idx = DatetimeIndex(start=Timestamp('1970-01-01'),
1138+
end=Timestamp('1970-01-04'), freq='D')
1139+
exp = DatetimeIndex(['1970-01-01', '1970-01-02',
1140+
'1970-01-03', '1970-01-04'])
1141+
tm.assert_index_equal(idx, exp)
1142+
10781143
def test_range_misspecified(self):
10791144
# GH #1095
10801145

0 commit comments

Comments
 (0)