]> granicus.if.org Git - python/commitdiff
Issue #23517: fromtimestamp() and utcfromtimestamp() methods of
authorVictor Stinner <victor.stinner@gmail.com>
Thu, 3 Sep 2015 07:06:44 +0000 (09:06 +0200)
committerVictor Stinner <victor.stinner@gmail.com>
Thu, 3 Sep 2015 07:06:44 +0000 (09:06 +0200)
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).

Lib/datetime.py
Lib/test/datetimetester.py
Misc/NEWS
Modules/_datetimemodule.c

index d661460fa8514433410d2ab154acece2a7e894c9..5ba2ddb7ab3ff3e609ec782a7f881e0e0ef7fbe1 100644 (file)
@@ -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,
index 62f55272d9d530f9b095e70f11612ae7f32eac10..f516434bd6a7a14dc4f991559ed74fb10008e5f1 100644 (file)
@@ -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,
index c9b925a001632fae2e2d35cd9a59ce2118660064..9af32ad175891d9dbbc4f1b27e5872bd62000465 100644 (file)
--- 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
index 6cab1e2d2421cdbe0ca7ee3159119343bdf857b3..ae459df8a98376205d590f745a8d6243f2ccc5aa 100644 (file)
@@ -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);