changeset: 97605:bf634dfe076f user: Victor Stinner date: Thu Sep 03 09:06:44 2015 +0200 files: Lib/datetime.py Lib/test/datetimetester.py Misc/NEWS Modules/_datetimemodule.c description: 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). diff -r e3167e358ee1 -r bf634dfe076f Lib/datetime.py --- a/Lib/datetime.py Wed Sep 02 22:08:21 2015 -0400 +++ b/Lib/datetime.py Thu Sep 03 09:06:44 2015 +0200 @@ -1384,7 +1384,7 @@ 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 @@ 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 -r e3167e358ee1 -r bf634dfe076f Lib/test/datetimetester.py --- a/Lib/test/datetimetester.py Wed Sep 02 22:08:21 2015 -0400 +++ b/Lib/test/datetimetester.py Thu Sep 03 09:06:44 2015 +0200 @@ -1847,6 +1847,7 @@ 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 @@ 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 -r e3167e358ee1 -r bf634dfe076f Misc/NEWS --- a/Misc/NEWS Wed Sep 02 22:08:21 2015 -0400 +++ b/Misc/NEWS Thu Sep 03 09:06:44 2015 +0200 @@ -17,6 +17,11 @@ 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 -r e3167e358ee1 -r bf634dfe076f Modules/_datetimemodule.c --- a/Modules/_datetimemodule.c Wed Sep 02 22:08:21 2015 -0400 +++ b/Modules/_datetimemodule.c Thu Sep 03 09:06:44 2015 +0200 @@ -4078,7 +4078,7 @@ 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);