Visitar URL original
fix:Signed integer overflow in datetime.c (#31688) · numpy/numpy@67cb4a8 · GitHub
Skip to content

Commit 67cb4a8

Browse files
AnkitAhlawat7742charris
authored andcommitted
fix:Signed integer overflow in datetime.c (#31688)
1 parent a007a20 commit 67cb4a8

2 files changed

Lines changed: 23 additions & 2 deletions

File tree

‎numpy/_core/src/multiarray/datetime.c‎

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,12 +167,23 @@ static npy_int64
167167
days_to_yearsdays(npy_int64 *days_)
168168
{
169169
const npy_int64 days_per_400years = (400*365 + 100 - 4 + 1);
170+
const npy_int64 days_offset = (365*30 + 7);
170171
/* Adjust so it's relative to the year 2000 (divisible by 400) */
171-
npy_int64 days = (*days_) - (365*30 + 7);
172+
npy_int64 days;
172173
npy_int64 year;
173174

175+
if (*days_ < NPY_MIN_INT64 + days_offset) {
176+
/* Extract 400-year cycles first to reduce magnitude */
177+
days = *days_ + (days_per_400years - days_offset);
178+
year = 400 * extract_unit_64(&days, days_per_400years);
179+
year -= 400;
180+
}
181+
else {
182+
days = (*days_) - days_offset;
183+
year = 400 * extract_unit_64(&days, days_per_400years);
184+
}
185+
174186
/* Break down the 400 year cycle to get the year and day within the year */
175-
year = 400 * extract_unit_64(&days, days_per_400years);
176187

177188
/* Work out the year/day within the 400 year cycle */
178189
if (days >= 366) {

‎numpy/_core/tests/test_datetime.py‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1265,6 +1265,16 @@ def test_arithmetic_valid_boundary(self):
12651265
assert small * np.int64(7) == np.timedelta64(21, "s")
12661266
assert np.int64(7) * small == np.timedelta64(21, "s")
12671267

1268+
def test_datetime64_item_int64_min_edge_case(self):
1269+
info = np.iinfo(np.int64)
1270+
1271+
for offset in [1, 2, 100, 1000, 10000]:
1272+
dt64 = np.datetime64(info.min + offset, "D")
1273+
result = dt64.item()
1274+
# expected integer value
1275+
assert result == info.min + offset
1276+
assert isinstance(result, int)
1277+
12681278
def test_pyobject_roundtrip(self):
12691279
# All datetime types should be able to roundtrip through object
12701280
a = np.array([0, 0, 0, 0, 0, 0, 0, 0, 0,

0 commit comments

Comments
 (0)