Fixed microsecond rounding in python version of utcfromtimestamp

This commit is contained in:
Alexander Belopolsky 2010-09-21 16:30:56 +00:00
parent b3bfc3d88b
commit 3e62f78c4e
2 changed files with 14 additions and 9 deletions

View File

@ -1379,12 +1379,17 @@ class datetime(date):
@classmethod @classmethod
def utcfromtimestamp(cls, t): def utcfromtimestamp(cls, t):
"Construct a UTC datetime from a POSIX timestamp (like time.time())." "Construct a UTC datetime from a POSIX timestamp (like time.time())."
if 1 - (t % 1.0) < 0.000001: t, frac = divmod(t, 1.0)
t = float(int(t)) + 1 us = round(frac * 1e6)
if t < 0:
t -= 1 # 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) y, m, d, hh, mm, ss, weekday, jday, dst = _time.gmtime(t)
us = int((t % 1.0) * 1000000)
ss = min(ss, 59) # clamp out leap seconds if the platform has them ss = min(ss, 59) # clamp out leap seconds if the platform has them
return cls(y, m, d, hh, mm, ss, us) return cls(y, m, d, hh, mm, ss, us)

View File

@ -1729,10 +1729,10 @@ class TestDateTime(TestDate):
def test_microsecond_rounding(self): def test_microsecond_rounding(self):
# Test whether fromtimestamp "rounds up" floats that are less # Test whether fromtimestamp "rounds up" floats that are less
# than 1/2 microsecond smaller than an integer. # than 1/2 microsecond smaller than an integer.
self.assertEqual(self.theclass.fromtimestamp(0.9999999), for fts in [self.theclass.fromtimestamp,
self.theclass.fromtimestamp(1)) self.theclass.utcfromtimestamp]:
self.assertEqual(self.theclass.fromtimestamp(0.99999949).microsecond, self.assertEqual(fts(0.9999999), fts(1))
999999) self.assertEqual(fts(0.99999949).microsecond, 999999)
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,