Skip to content

Commit 7667f58

Browse files
committed
Issue #23517: fromtimestamp() and utcfromtimestamp() methods of
datetime.datetime now round microseconds to nearest with ties going to nearest even integer (ROUND_HALF_EVEN), as round(float), instead of rounding towards -Infinity (ROUND_FLOOR). pytime API: replace _PyTime_ROUND_HALF_UP with _PyTime_ROUND_HALF_EVEN. Fix also _PyTime_Divide() for negative numbers. _PyTime_AsTimeval_impl() now reuses _PyTime_Divide() instead of reimplementing rounding modes.
1 parent 69cc487 commit 7667f58

File tree

8 files changed

+152
-189
lines changed

8 files changed

+152
-189
lines changed

Include/pytime.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ typedef enum {
3131
/* Round towards infinity (+inf).
3232
For example, used for timeout to wait "at least" N seconds. */
3333
_PyTime_ROUND_CEILING=1,
34-
/* Round to nearest with ties going away from zero.
34+
/* Round to nearest with ties going to nearest even integer.
3535
For example, used to round from a Python float. */
36-
_PyTime_ROUND_HALF_UP
36+
_PyTime_ROUND_HALF_EVEN
3737
} _PyTime_round_t;
3838

3939
/* Convert a time_t to a PyLong. */
@@ -44,8 +44,9 @@ PyAPI_FUNC(PyObject *) _PyLong_FromTime_t(
4444
PyAPI_FUNC(time_t) _PyLong_AsTime_t(
4545
PyObject *obj);
4646

47-
/* Round to nearest with ties going away from zero (_PyTime_ROUND_HALF_UP). */
48-
PyAPI_FUNC(double) _PyTime_RoundHalfUp(
47+
/* Round to nearest with ties going to nearest even integer
48+
(_PyTime_ROUND_HALF_EVEN) */
49+
PyAPI_FUNC(double) _PyTime_RoundHalfEven(
4950
double x);
5051

5152
/* Convert a number of seconds, int or float, to time_t. */

Lib/datetime.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1380,7 +1380,7 @@ def _fromtimestamp(cls, t, utc, tz):
13801380
A timezone info object may be passed in as well.
13811381
"""
13821382
frac, t = _math.modf(t)
1383-
us = _round_half_up(frac * 1e6)
1383+
us = round(frac * 1e6)
13841384
if us >= 1000000:
13851385
t += 1
13861386
us -= 1000000

Lib/test/datetimetester.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1874,7 +1874,7 @@ def test_microsecond_rounding(self):
18741874
self.assertEqual(t, zero)
18751875
t = fts(-1/2**7)
18761876
self.assertEqual(t.second, 59)
1877-
self.assertEqual(t.microsecond, 992187)
1877+
self.assertEqual(t.microsecond, 992188)
18781878

18791879
t = fts(1e-7)
18801880
self.assertEqual(t, zero)
@@ -1888,7 +1888,7 @@ def test_microsecond_rounding(self):
18881888
self.assertEqual(t.microsecond, 0)
18891889
t = fts(1/2**7)
18901890
self.assertEqual(t.second, 0)
1891-
self.assertEqual(t.microsecond, 7813)
1891+
self.assertEqual(t.microsecond, 7812)
18921892

18931893
def test_insane_fromtimestamp(self):
18941894
# It's possible that some platform maps time_t to double,

0 commit comments

Comments
 (0)