diff -r e9cecb612ff7 Lib/test/datetimetester.py --- a/Lib/test/datetimetester.py Sat Aug 03 21:19:10 2013 +0300 +++ b/Lib/test/datetimetester.py Sat Aug 03 17:58:10 2013 -0400 @@ -619,6 +619,10 @@ eq(td(hours=-.2/us_per_hour), td(0)) eq(td(days=-.4/us_per_day, hours=-.2/us_per_hour), td(microseconds=-1)) + # Test for a patch in Issue 8860 + eq(td(microseconds=0.5), 0.5*td(microseconds=1.0)) + eq(td(microseconds=0.5)//td.resolution, 0.5*td.resolution//td.resolution) + def test_massive_normalization(self): td = timedelta(microseconds=-1) self.assertEqual((td.days, td.seconds, td.microseconds), diff -r e9cecb612ff7 Modules/_datetimemodule.c --- a/Modules/_datetimemodule.c Sat Aug 03 21:19:10 2013 +0300 +++ b/Modules/_datetimemodule.c Sat Aug 03 17:58:10 2013 -0400 @@ -140,19 +140,6 @@ return quo; } -/* Round a double to the nearest long. |x| must be small enough to fit - * in a C long; this is not checked. - */ -static long -round_to_long(double x) -{ - if (x >= 0.0) - x = floor(x + 0.5); - else - x = ceil(x - 0.5); - return (long)x; -} - /* Nearest integer to m / n for integers m and n. Half-integer results * are rounded to even. */ @@ -2148,7 +2135,30 @@ } if (leftover_us) { /* Round to nearest whole # of us, and add into x. */ - PyObject *temp = PyLong_FromLong(round_to_long(leftover_us)); + double whole_us = round(leftover_us); + int x_is_odd; + PyObject *temp; + + whole_us = round(leftover_us); + if (fabs(whole_us - leftover_us) == 0.5) { + /* We're exactly halfway between two integers. In order to do + * round-half-to-even, we must determine whether x is odd. */ + temp = PyNumber_And(x, us_per_us); + if (temp == NULL) { + Py_DECREF(x); + goto Done; + } + x_is_odd = PyObject_IsTrue(temp); + Py_DECREF(temp); + if (x_is_odd == -1) { + Py_DECREF(x); + goto Done; + } + whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd; + } + + temp = PyLong_FromLong(whole_us); + if (temp == NULL) { Py_DECREF(x); goto Done;