summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVictor Stinner <victor.stinner@gmail.com>2015-09-03 07:06:44 (GMT)
committerVictor Stinner <victor.stinner@gmail.com>2015-09-03 07:06:44 (GMT)
commit2ec5bd6fb22ff71ffbe5987f55a31bc4177e39a6 (patch)
treebc90e17fecec5aa9476146d19ecc02bb59f5e895
parent0fa5ef72b731c6884f58c0aa38f648b57004c4db (diff)
downloadcpython-2ec5bd6fb22ff71ffbe5987f55a31bc4177e39a6.zip
cpython-2ec5bd6fb22ff71ffbe5987f55a31bc4177e39a6.tar.gz
cpython-2ec5bd6fb22ff71ffbe5987f55a31bc4177e39a6.tar.bz2
Issue #23517: fromtimestamp() and utcfromtimestamp() methods of
datetime.datetime now round microseconds to nearest with ties going away from zero (ROUND_HALF_UP), as Python 2 and Python older than 3.3, instead of rounding towards -Infinity (ROUND_FLOOR).
-rw-r--r--Lib/datetime.py4
-rw-r--r--Lib/test/datetimetester.py11
-rw-r--r--Misc/NEWS5
-rw-r--r--Modules/_datetimemodule.c2
4 files changed, 14 insertions, 8 deletions
diff --git a/Lib/datetime.py b/Lib/datetime.py
index d661460..5ba2ddb 100644
--- a/Lib/datetime.py
+++ b/Lib/datetime.py
@@ -1384,7 +1384,7 @@ class datetime(date):
converter = _time.localtime if tz is None else _time.gmtime
t, frac = divmod(t, 1.0)
- us = int(frac * 1e6)
+ us = _round_half_up(frac * 1e6)
# If timestamp is less than one microsecond smaller than a
# full second, us can be rounded up to 1000000. In this case,
@@ -1404,7 +1404,7 @@ class datetime(date):
def utcfromtimestamp(cls, t):
"""Construct a naive UTC datetime from a POSIX timestamp."""
t, frac = divmod(t, 1.0)
- us = int(frac * 1e6)
+ us = _round_half_up(frac * 1e6)
# If timestamp is less than one microsecond smaller than a
# full second, us can be rounded up to 1000000. In this case,
diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py
index 62f5527..f516434 100644
--- a/Lib/test/datetimetester.py
+++ b/Lib/test/datetimetester.py
@@ -1847,6 +1847,7 @@ class TestDateTime(TestDate):
zero = fts(0)
self.assertEqual(zero.second, 0)
self.assertEqual(zero.microsecond, 0)
+ one = fts(1e-6)
try:
minus_one = fts(-1e-6)
except OSError:
@@ -1857,22 +1858,22 @@ class TestDateTime(TestDate):
self.assertEqual(minus_one.microsecond, 999999)
t = fts(-1e-8)
- self.assertEqual(t, minus_one)
+ self.assertEqual(t, zero)
t = fts(-9e-7)
self.assertEqual(t, minus_one)
t = fts(-1e-7)
- self.assertEqual(t, minus_one)
+ self.assertEqual(t, zero)
t = fts(1e-7)
self.assertEqual(t, zero)
t = fts(9e-7)
- self.assertEqual(t, zero)
+ self.assertEqual(t, one)
t = fts(0.99999949)
self.assertEqual(t.second, 0)
self.assertEqual(t.microsecond, 999999)
t = fts(0.9999999)
- self.assertEqual(t.second, 0)
- self.assertEqual(t.microsecond, 999999)
+ self.assertEqual(t.second, 1)
+ self.assertEqual(t.microsecond, 0)
def test_insane_fromtimestamp(self):
# It's possible that some platform maps time_t to double,
diff --git a/Misc/NEWS b/Misc/NEWS
index c9b925a..9af32ad 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -17,6 +17,11 @@ Core and Builtins
Library
-------
+- Issue #23517: fromtimestamp() and utcfromtimestamp() methods of
+ datetime.datetime now round microseconds to nearest with ties going away from
+ zero (ROUND_HALF_UP), as Python 2 and Python older than 3.3, instead of
+ rounding towards -Infinity (ROUND_FLOOR).
+
- 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
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index 6cab1e2..ae459df 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -4078,7 +4078,7 @@ datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp,
long us;
if (_PyTime_ObjectToTimeval(timestamp,
- &timet, &us, _PyTime_ROUND_FLOOR) == -1)
+ &timet, &us, _PyTime_ROUND_HALF_UP) == -1)
return NULL;
return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo);