Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit b6f5ec7

Browse files
committed
Issue #11576: Fixed timedelta subtraction glitch on big timedelta values
1 parent 04026cf commit b6f5ec7

3 files changed

Lines changed: 19 additions & 8 deletions

File tree

Lib/datetime.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -485,7 +485,11 @@ def __add__(self, other):
485485

486486
def __sub__(self, other):
487487
if isinstance(other, timedelta):
488-
return self + -other
488+
# for CPython compatibility, we cannot use
489+
# our __class__ here, but need a real timedelta
490+
return timedelta(self._days - other._days,
491+
self._seconds - other._seconds,
492+
self._microseconds - other._microseconds)
489493
return NotImplemented
490494

491495
def __rsub__(self, other):

Lib/test/datetimetester.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,12 @@ def test_computations(self):
383383
for i in range(-10, 10):
384384
eq((i*us/-3)//us, round(i/-3))
385385

386+
# Issue #11576
387+
eq(td(999999999, 86399, 999999) - td(999999999, 86399, 999998),
388+
td(0, 0, 1))
389+
eq(td(999999999, 1, 1) - td(999999999, 1, 0),
390+
td(0, 0, 1))
391+
386392
def test_disallowed_computations(self):
387393
a = timedelta(42)
388394

Modules/_datetimemodule.c

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1801,13 +1801,14 @@ delta_subtract(PyObject *left, PyObject *right)
18011801

18021802
if (PyDelta_Check(left) && PyDelta_Check(right)) {
18031803
/* delta - delta */
1804-
PyObject *minus_right = PyNumber_Negative(right);
1805-
if (minus_right) {
1806-
result = delta_add(left, minus_right);
1807-
Py_DECREF(minus_right);
1808-
}
1809-
else
1810-
result = NULL;
1804+
/* The C-level additions can't overflow because of the
1805+
* invariant bounds.
1806+
*/
1807+
int days = GET_TD_DAYS(left) - GET_TD_DAYS(right);
1808+
int seconds = GET_TD_SECONDS(left) - GET_TD_SECONDS(right);
1809+
int microseconds = GET_TD_MICROSECONDS(left) -
1810+
GET_TD_MICROSECONDS(right);
1811+
result = new_delta(days, seconds, microseconds, 1);
18111812
}
18121813

18131814
if (result == Py_NotImplemented)

0 commit comments

Comments
 (0)