mirror of
				https://github.com/python/cpython.git
				synced 2025-10-25 10:44:55 +00:00 
			
		
		
		
	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).
This commit is contained in:
		
							parent
							
								
									0fa5ef72b7
								
							
						
					
					
						commit
						2ec5bd6fb2
					
				
					 4 changed files with 14 additions and 8 deletions
				
			
		|  | @ -1384,7 +1384,7 @@ def fromtimestamp(cls, t, tz=None): | ||||||
|         converter = _time.localtime if tz is None else _time.gmtime |         converter = _time.localtime if tz is None else _time.gmtime | ||||||
| 
 | 
 | ||||||
|         t, frac = divmod(t, 1.0) |         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 |         # If timestamp is less than one microsecond smaller than a | ||||||
|         # full second, us can be rounded up to 1000000.  In this case, |         # full second, us can be rounded up to 1000000.  In this case, | ||||||
|  | @ -1404,7 +1404,7 @@ def fromtimestamp(cls, t, tz=None): | ||||||
|     def utcfromtimestamp(cls, t): |     def utcfromtimestamp(cls, t): | ||||||
|         """Construct a naive UTC datetime from a POSIX timestamp.""" |         """Construct a naive UTC datetime from a POSIX timestamp.""" | ||||||
|         t, frac = divmod(t, 1.0) |         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 |         # If timestamp is less than one microsecond smaller than a | ||||||
|         # full second, us can be rounded up to 1000000.  In this case, |         # full second, us can be rounded up to 1000000.  In this case, | ||||||
|  |  | ||||||
|  | @ -1847,6 +1847,7 @@ def test_microsecond_rounding(self): | ||||||
|             zero = fts(0) |             zero = fts(0) | ||||||
|             self.assertEqual(zero.second, 0) |             self.assertEqual(zero.second, 0) | ||||||
|             self.assertEqual(zero.microsecond, 0) |             self.assertEqual(zero.microsecond, 0) | ||||||
|  |             one = fts(1e-6) | ||||||
|             try: |             try: | ||||||
|                 minus_one = fts(-1e-6) |                 minus_one = fts(-1e-6) | ||||||
|             except OSError: |             except OSError: | ||||||
|  | @ -1857,22 +1858,22 @@ def test_microsecond_rounding(self): | ||||||
|                 self.assertEqual(minus_one.microsecond, 999999) |                 self.assertEqual(minus_one.microsecond, 999999) | ||||||
| 
 | 
 | ||||||
|                 t = fts(-1e-8) |                 t = fts(-1e-8) | ||||||
|                 self.assertEqual(t, minus_one) |                 self.assertEqual(t, zero) | ||||||
|                 t = fts(-9e-7) |                 t = fts(-9e-7) | ||||||
|                 self.assertEqual(t, minus_one) |                 self.assertEqual(t, minus_one) | ||||||
|                 t = fts(-1e-7) |                 t = fts(-1e-7) | ||||||
|                 self.assertEqual(t, minus_one) |                 self.assertEqual(t, zero) | ||||||
| 
 | 
 | ||||||
|             t = fts(1e-7) |             t = fts(1e-7) | ||||||
|             self.assertEqual(t, zero) |             self.assertEqual(t, zero) | ||||||
|             t = fts(9e-7) |             t = fts(9e-7) | ||||||
|             self.assertEqual(t, zero) |             self.assertEqual(t, one) | ||||||
|             t = fts(0.99999949) |             t = fts(0.99999949) | ||||||
|             self.assertEqual(t.second, 0) |             self.assertEqual(t.second, 0) | ||||||
|             self.assertEqual(t.microsecond, 999999) |             self.assertEqual(t.microsecond, 999999) | ||||||
|             t = fts(0.9999999) |             t = fts(0.9999999) | ||||||
|             self.assertEqual(t.second, 0) |             self.assertEqual(t.second, 1) | ||||||
|             self.assertEqual(t.microsecond, 999999) |             self.assertEqual(t.microsecond, 0) | ||||||
| 
 | 
 | ||||||
|     def test_insane_fromtimestamp(self): |     def test_insane_fromtimestamp(self): | ||||||
|         # It's possible that some platform maps time_t to double, |         # It's possible that some platform maps time_t to double, | ||||||
|  |  | ||||||
|  | @ -17,6 +17,11 @@ Core and Builtins | ||||||
| Library | 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 | - Issue #23517: datetime.timedelta constructor now rounds microseconds to | ||||||
|   nearest with ties going away from zero (ROUND_HALF_UP), as Python 2 and |   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 |   Python older than 3.3, instead of rounding to nearest with ties going to | ||||||
|  |  | ||||||
|  | @ -4078,7 +4078,7 @@ datetime_from_timestamp(PyObject *cls, TM_FUNC f, PyObject *timestamp, | ||||||
|     long us; |     long us; | ||||||
| 
 | 
 | ||||||
|     if (_PyTime_ObjectToTimeval(timestamp, |     if (_PyTime_ObjectToTimeval(timestamp, | ||||||
|                                 &timet, &us, _PyTime_ROUND_FLOOR) == -1) |                                 &timet, &us, _PyTime_ROUND_HALF_UP) == -1) | ||||||
|         return NULL; |         return NULL; | ||||||
| 
 | 
 | ||||||
|     return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo); |     return datetime_from_timet_and_us(cls, f, timet, (int)us, tzinfo); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Victor Stinner
						Victor Stinner