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

Skip to content

Commit 69cc487

Browse files
committed
Revert change 0eb8c182131e:
"""Issue #23517: datetime.timedelta constructor now rounds microseconds to nearest with ties going away from zero (ROUND_HALF_UP), as Python 2 and Python older than 3.3, instead of rounding to nearest with ties going to nearest even integer (ROUND_HALF_EVEN).""" datetime.timedelta uses rounding mode ROUND_HALF_EVEN again.
1 parent 1638bdf commit 69cc487

4 files changed

Lines changed: 36 additions & 15 deletions

File tree

Lib/datetime.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ def __new__(cls, days=0, seconds=0, microseconds=0,
407407
# secondsfrac isn't referenced again
408408

409409
if isinstance(microseconds, float):
410-
microseconds = _round_half_up(microseconds + usdouble)
410+
microseconds = round(microseconds + usdouble)
411411
seconds, microseconds = divmod(microseconds, 1000000)
412412
days, seconds = divmod(seconds, 24*3600)
413413
d += days
@@ -418,7 +418,7 @@ def __new__(cls, days=0, seconds=0, microseconds=0,
418418
days, seconds = divmod(seconds, 24*3600)
419419
d += days
420420
s += seconds
421-
microseconds = _round_half_up(microseconds + usdouble)
421+
microseconds = round(microseconds + usdouble)
422422
assert isinstance(s, int)
423423
assert isinstance(microseconds, int)
424424
assert abs(s) <= 3 * 24 * 3600

Lib/test/datetimetester.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -663,14 +663,16 @@ def test_microsecond_rounding(self):
663663
# Single-field rounding.
664664
eq(td(milliseconds=0.4/1000), td(0)) # rounds to 0
665665
eq(td(milliseconds=-0.4/1000), td(0)) # rounds to 0
666-
eq(td(milliseconds=0.5/1000), td(microseconds=1))
667-
eq(td(milliseconds=-0.5/1000), td(microseconds=-1))
666+
eq(td(milliseconds=0.5/1000), td(microseconds=0))
667+
eq(td(milliseconds=-0.5/1000), td(microseconds=-0))
668668
eq(td(milliseconds=0.6/1000), td(microseconds=1))
669669
eq(td(milliseconds=-0.6/1000), td(microseconds=-1))
670-
eq(td(seconds=0.5/10**6), td(microseconds=1))
671-
eq(td(seconds=-0.5/10**6), td(microseconds=-1))
672-
eq(td(seconds=1/2**7), td(microseconds=7813))
673-
eq(td(seconds=-1/2**7), td(microseconds=-7813))
670+
eq(td(milliseconds=1.5/1000), td(microseconds=2))
671+
eq(td(milliseconds=-1.5/1000), td(microseconds=-2))
672+
eq(td(seconds=0.5/10**6), td(microseconds=0))
673+
eq(td(seconds=-0.5/10**6), td(microseconds=-0))
674+
eq(td(seconds=1/2**7), td(microseconds=7812))
675+
eq(td(seconds=-1/2**7), td(microseconds=-7812))
674676

675677
# Rounding due to contributions from more than one field.
676678
us_per_hour = 3600e6
@@ -683,6 +685,10 @@ def test_microsecond_rounding(self):
683685
eq(td(hours=-.2/us_per_hour), td(0))
684686
eq(td(days=-.4/us_per_day, hours=-.2/us_per_hour), td(microseconds=-1))
685687

688+
# Test for a patch in Issue 8860
689+
eq(td(microseconds=0.5), 0.5*td(microseconds=1.0))
690+
eq(td(microseconds=0.5)//td.resolution, 0.5*td.resolution//td.resolution)
691+
686692
def test_massive_normalization(self):
687693
td = timedelta(microseconds=-1)
688694
self.assertEqual((td.days, td.seconds, td.microseconds),

Misc/NEWS

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,13 @@ Core and Builtins
1717
Library
1818
-------
1919

20-
- Issue #22241: timezone.utc name is now plain 'UTC', not 'UTC-00:00'.
20+
- Issue #22241: timezone.utc name is now plain 'UTC', not 'UTC-00:00'.
2121

2222
- Issue #23517: fromtimestamp() and utcfromtimestamp() methods of
2323
datetime.datetime now round microseconds to nearest with ties going away from
2424
zero (ROUND_HALF_UP), as Python 2 and Python older than 3.3, instead of
2525
rounding towards -Infinity (ROUND_FLOOR).
2626

27-
- Issue #23517: datetime.timedelta constructor now rounds microseconds to
28-
nearest with ties going away from zero (ROUND_HALF_UP), as Python 2 and
29-
Python older than 3.3, instead of rounding to nearest with ties going to
30-
nearest even integer (ROUND_HALF_EVEN).
31-
3227
- Issue #23552: Timeit now warns when there is substantial (4x) variance
3328
between best and worst times. Patch from Serhiy Storchaka.
3429

Modules/_datetimemodule.c

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2149,9 +2149,29 @@ delta_new(PyTypeObject *type, PyObject *args, PyObject *kw)
21492149
if (leftover_us) {
21502150
/* Round to nearest whole # of us, and add into x. */
21512151
double whole_us = round(leftover_us);
2152+
int x_is_odd;
21522153
PyObject *temp;
21532154

2154-
whole_us = _PyTime_RoundHalfUp(leftover_us);
2155+
whole_us = round(leftover_us);
2156+
if (fabs(whole_us - leftover_us) == 0.5) {
2157+
/* We're exactly halfway between two integers. In order
2158+
* to do round-half-to-even, we must determine whether x
2159+
* is odd. Note that x is odd when it's last bit is 1. The
2160+
* code below uses bitwise and operation to check the last
2161+
* bit. */
2162+
temp = PyNumber_And(x, one); /* temp <- x & 1 */
2163+
if (temp == NULL) {
2164+
Py_DECREF(x);
2165+
goto Done;
2166+
}
2167+
x_is_odd = PyObject_IsTrue(temp);
2168+
Py_DECREF(temp);
2169+
if (x_is_odd == -1) {
2170+
Py_DECREF(x);
2171+
goto Done;
2172+
}
2173+
whole_us = 2.0 * round((leftover_us + x_is_odd) * 0.5) - x_is_odd;
2174+
}
21552175

21562176
temp = PyLong_FromLong((long)whole_us);
21572177

0 commit comments

Comments
 (0)