Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(97)

## Unified Diff: Lib/datetime.py

Issue 23517: datetime.utcfromtimestamp rounds results incorrectly
Patch Set: Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
« no previous file with comments | « no previous file | Lib/test/datetimetester.py » ('j') | Lib/test/datetimetester.py » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Hide Comments ('s')
 --- a/Lib/datetime.py Tue Sep 08 09:59:02 2015 +0300 +++ b/Lib/datetime.py Wed Sep 09 01:59:39 2015 +0200 @@ -1362,49 +1362,42 @@ class datetime(date): return self._tzinfo @classmethod + def _fromtimestamp(cls, t, utc, tz): + """Construct a datetime from a POSIX timestamp (like time.time()). + + A timezone info object may be passed in as well. + """ + frac, t = _math.modf(t) sasha 2015/09/10 21:14:58 You may find it easier to use t, frac = divmod(t, You may find it easier to use t, frac = divmod(t, 1) here. This will always give you 0 <= frac < 1. storchaka 2015/09/10 22:30:27 See also issue23607. divmod(t, 1) allowed to suppo Show quoted text On 2015/09/10 21:14:58, sasha wrote: > You may find it easier to use t, frac = divmod(t, 1) here. This will always > give you 0 <= frac < 1. See also issue23607. divmod(t, 1) allowed to support Decimals in Python 2. + us = round(frac * 1e6) + if us >= 1000000: + t += 1 + us -= 1000000 + elif us < 0: + t -= 1 + us += 1000000 + + converter = _time.gmtime if utc else _time.localtime + y, m, d, hh, mm, ss, weekday, jday, dst = converter(t) + ss = min(ss, 59) # clamp out leap seconds if the platform has them + return cls(y, m, d, hh, mm, ss, us, tz) + + @classmethod def fromtimestamp(cls, t, tz=None): """Construct a datetime from a POSIX timestamp (like time.time()). A timezone info object may be passed in as well. """ - _check_tzinfo_arg(tz) - converter = _time.localtime if tz is None else _time.gmtime - - t, frac = divmod(t, 1.0) - us = int(frac * 1e6) - - # If timestamp is less than one microsecond smaller than a - # full second, us can be rounded up to 1000000. In this case, - # roll over to seconds, otherwise, ValueError is raised - # by the constructor. - if us == 1000000: - t += 1 - us = 0 - y, m, d, hh, mm, ss, weekday, jday, dst = converter(t) - ss = min(ss, 59) # clamp out leap seconds if the platform has them - result = cls(y, m, d, hh, mm, ss, us, tz) + result = cls._fromtimestamp(t, tz is not None, tz) if tz is not None: result = tz.fromutc(result) return result @classmethod def utcfromtimestamp(cls, t): - "Construct a UTC datetime from a POSIX timestamp (like time.time())." - t, frac = divmod(t, 1.0) - us = int(frac * 1e6) - - # If timestamp is less than one microsecond smaller than a - # full second, us can be rounded up to 1000000. In this case, - # roll over to seconds, otherwise, ValueError is raised - # by the constructor. - if us == 1000000: - t += 1 - us = 0 - y, m, d, hh, mm, ss, weekday, jday, dst = _time.gmtime(t) - ss = min(ss, 59) # clamp out leap seconds if the platform has them - return cls(y, m, d, hh, mm, ss, us) + """Construct a naive UTC datetime from a POSIX timestamp.""" + return cls._fromtimestamp(t, True, None) # XXX This is supposed to do better than we *can* do by using time.time(), # XXX if the platform supports a more accurate way. The C implementation
« no previous file with comments | « no previous file | Lib/test/datetimetester.py » ('j') | Lib/test/datetimetester.py » ('J')

This is Rietveld 894c83f36cb7+