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

Side by Side Diff: Lib/datetime.py

Issue 23517: datetime.utcfromtimestamp rounds results incorrectly
Patch Set: Created 4 years, 7 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | Lib/test/datetimetester.py » ('j') | Lib/test/datetimetester.py » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 """Concrete date/time and related types. 1 """Concrete date/time and related types.
2 2
3 See http://www.iana.org/time-zones/repository/tz-link.html for 3 See http://www.iana.org/time-zones/repository/tz-link.html for
4 time zone and DST data sources. 4 time zone and DST data sources.
5 """ 5 """
6 6
7 import time as _time 7 import time as _time
8 import math as _math 8 import math as _math
9 9
10 def _cmp(x, y): 10 def _cmp(x, y):
(...skipping 1342 matching lines...) Expand 10 before | Expand all | Expand 10 after
1353 1353
1354 @property 1354 @property
1355 def microsecond(self): 1355 def microsecond(self):
1356 """microsecond (0-999999)""" 1356 """microsecond (0-999999)"""
1357 return self._microsecond 1357 return self._microsecond
1358 1358
1359 @property 1359 @property
1360 def tzinfo(self): 1360 def tzinfo(self):
1361 """timezone info object""" 1361 """timezone info object"""
1362 return self._tzinfo 1362 return self._tzinfo
1363
1364 @classmethod
1365 def _fromtimestamp(cls, t, utc, tz):
1366 """Construct a datetime from a POSIX timestamp (like time.time()).
1367
1368 A timezone info object may be passed in as well.
1369 """
1370 frac, t = _math.modf(t)
sasha 2015/09/10 21:14:58 You may find it easier to use t, frac = divmod(t,
storchaka 2015/09/10 22:30:27 See also issue23607. divmod(t, 1) allowed to suppo
1371 us = round(frac * 1e6)
1372 if us >= 1000000:
1373 t += 1
1374 us -= 1000000
1375 elif us < 0:
1376 t -= 1
1377 us += 1000000
1378
1379 converter = _time.gmtime if utc else _time.localtime
1380 y, m, d, hh, mm, ss, weekday, jday, dst = converter(t)
1381 ss = min(ss, 59) # clamp out leap seconds if the platform has them
1382 return cls(y, m, d, hh, mm, ss, us, tz)
1363 1383
1364 @classmethod 1384 @classmethod
1365 def fromtimestamp(cls, t, tz=None): 1385 def fromtimestamp(cls, t, tz=None):
1366 """Construct a datetime from a POSIX timestamp (like time.time()). 1386 """Construct a datetime from a POSIX timestamp (like time.time()).
1367 1387
1368 A timezone info object may be passed in as well. 1388 A timezone info object may be passed in as well.
1369 """ 1389 """
1370
1371 _check_tzinfo_arg(tz) 1390 _check_tzinfo_arg(tz)
1372 1391
1373 converter = _time.localtime if tz is None else _time.gmtime 1392 result = cls._fromtimestamp(t, tz is not None, tz)
1374
1375 t, frac = divmod(t, 1.0)
1376 us = int(frac * 1e6)
1377
1378 # If timestamp is less than one microsecond smaller than a
1379 # full second, us can be rounded up to 1000000. In this case,
1380 # roll over to seconds, otherwise, ValueError is raised
1381 # by the constructor.
1382 if us == 1000000:
1383 t += 1
1384 us = 0
1385 y, m, d, hh, mm, ss, weekday, jday, dst = converter(t)
1386 ss = min(ss, 59) # clamp out leap seconds if the platform has them
1387 result = cls(y, m, d, hh, mm, ss, us, tz)
1388 if tz is not None: 1393 if tz is not None:
1389 result = tz.fromutc(result) 1394 result = tz.fromutc(result)
1390 return result 1395 return result
1391 1396
1392 @classmethod 1397 @classmethod
1393 def utcfromtimestamp(cls, t): 1398 def utcfromtimestamp(cls, t):
1394 "Construct a UTC datetime from a POSIX timestamp (like time.time())." 1399 """Construct a naive UTC datetime from a POSIX timestamp."""
1395 t, frac = divmod(t, 1.0) 1400 return cls._fromtimestamp(t, True, None)
1396 us = int(frac * 1e6)
1397
1398 # If timestamp is less than one microsecond smaller than a
1399 # full second, us can be rounded up to 1000000. In this case,
1400 # roll over to seconds, otherwise, ValueError is raised
1401 # by the constructor.
1402 if us == 1000000:
1403 t += 1
1404 us = 0
1405 y, m, d, hh, mm, ss, weekday, jday, dst = _time.gmtime(t)
1406 ss = min(ss, 59) # clamp out leap seconds if the platform has them
1407 return cls(y, m, d, hh, mm, ss, us)
1408 1401
1409 # XXX This is supposed to do better than we *can* do by using time.time(), 1402 # XXX This is supposed to do better than we *can* do by using time.time(),
1410 # XXX if the platform supports a more accurate way. The C implementation 1403 # XXX if the platform supports a more accurate way. The C implementation
1411 # XXX uses gettimeofday on platforms that have it, but that isn't 1404 # XXX uses gettimeofday on platforms that have it, but that isn't
1412 # XXX available from Python. So now() may return different results 1405 # XXX available from Python. So now() may return different results
1413 # XXX across the implementations. 1406 # XXX across the implementations.
1414 @classmethod 1407 @classmethod
1415 def now(cls, tz=None): 1408 def now(cls, tz=None):
1416 "Construct a datetime from time.time() and optional time zone info." 1409 "Construct a datetime from time.time() and optional time zone info."
1417 t = _time.time() 1410 t = _time.time()
(...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after
2148 _check_time_fields, _check_tzinfo_arg, _check_tzname, 2141 _check_time_fields, _check_tzinfo_arg, _check_tzname,
2149 _check_utc_offset, _cmp, _cmperror, _date_class, _days_before_month, 2142 _check_utc_offset, _cmp, _cmperror, _date_class, _days_before_month,
2150 _days_before_year, _days_in_month, _format_time, _is_leap, 2143 _days_before_year, _days_in_month, _format_time, _is_leap,
2151 _isoweek1monday, _math, _ord2ymd, _time, _time_class, _tzinfo_class, 2144 _isoweek1monday, _math, _ord2ymd, _time, _time_class, _tzinfo_class,
2152 _wrap_strftime, _ymd2ord) 2145 _wrap_strftime, _ymd2ord)
2153 # XXX Since import * above excludes names that start with _, 2146 # XXX Since import * above excludes names that start with _,
2154 # docstring does not get overwritten. In the future, it may be 2147 # docstring does not get overwritten. In the future, it may be
2155 # appropriate to maintain a single module level docstring and 2148 # appropriate to maintain a single module level docstring and
2156 # remove the following line. 2149 # remove the following line.
2157 from _datetime import __doc__ 2150 from _datetime import __doc__
OLDNEW
« no previous file with comments | « no previous file | Lib/test/datetimetester.py » ('j') | Lib/test/datetimetester.py » ('J')

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+