]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Fixed microsecond rounding in python version of utcfromtimestamp
authorAlexander Belopolsky <alexander.belopolsky@gmail.com>
Tue, 21 Sep 2010 16:30:56 +0000 (16:30 +0000)
committerAlexander Belopolsky <alexander.belopolsky@gmail.com>
Tue, 21 Sep 2010 16:30:56 +0000 (16:30 +0000)
Lib/datetime.py
Lib/test/datetimetester.py

index 23ded3ec7e1c20a1386faa6f32c1bdfea9132f7c..d640f75616b0bf4c65adb1966a5c7c890d420cd9 100644 (file)
@@ -1379,12 +1379,17 @@ class datetime(date):
     @classmethod
     def utcfromtimestamp(cls, t):
         "Construct a UTC datetime from a POSIX timestamp (like time.time())."
-        if 1 - (t % 1.0) < 0.000001:
-            t = float(int(t)) + 1
-        if t < 0:
-            t -= 1
+        t, frac = divmod(t, 1.0)
+        us = round(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)
-        us = int((t % 1.0) * 1000000)
         ss = min(ss, 59)    # clamp out leap seconds if the platform has them
         return cls(y, m, d, hh, mm, ss, us)
 
index 7adf54cf88192bd55e6af9d32be3c7c568c640fd..0ee544b1b75c3bfe6f84b8fa6d1119183c75985e 100644 (file)
@@ -1729,10 +1729,10 @@ class TestDateTime(TestDate):
     def test_microsecond_rounding(self):
         # Test whether fromtimestamp "rounds up" floats that are less
         # than 1/2 microsecond smaller than an integer.
-        self.assertEqual(self.theclass.fromtimestamp(0.9999999),
-                         self.theclass.fromtimestamp(1))
-        self.assertEqual(self.theclass.fromtimestamp(0.99999949).microsecond,
-                         999999)
+        for fts in [self.theclass.fromtimestamp,
+                    self.theclass.utcfromtimestamp]:
+            self.assertEqual(fts(0.9999999), fts(1))
+            self.assertEqual(fts(0.99999949).microsecond, 999999)
 
     def test_insane_fromtimestamp(self):
         # It's possible that some platform maps time_t to double,