diff options
author | Alexander Belopolsky <alexander.belopolsky@gmail.com> | 2010-07-26 02:36:41 (GMT) |
---|---|---|
committer | Alexander Belopolsky <alexander.belopolsky@gmail.com> | 2010-07-26 02:36:41 (GMT) |
commit | aeb039863d2962dcffa60823d9afab2c39c8d8fc (patch) | |
tree | 5844b8d3c9245c4bc365d39e9454c78944305f4f | |
parent | 0f0c3320ee82a16d57f76ac96a781379e61e3296 (diff) | |
download | cpython-aeb039863d2962dcffa60823d9afab2c39c8d8fc.zip cpython-aeb039863d2962dcffa60823d9afab2c39c8d8fc.tar.gz cpython-aeb039863d2962dcffa60823d9afab2c39c8d8fc.tar.bz2 |
Make python version of fromtimestamp behave more like C.
-rw-r--r-- | Lib/datetime.py | 22 | ||||
-rw-r--r-- | Lib/test/datetimetester.py | 8 |
2 files changed, 20 insertions, 10 deletions
diff --git a/Lib/datetime.py b/Lib/datetime.py index 19f20e7..23ded3e 100644 --- a/Lib/datetime.py +++ b/Lib/datetime.py @@ -1356,16 +1356,20 @@ class datetime(date): """ _check_tzinfo_arg(tz) - if tz is None: - converter = _time.localtime - else: - converter = _time.gmtime - if 1 - (t % 1.0) < 0.000001: - t = float(int(t)) + 1 - if t < 0: - t -= 1 + + converter = _time.localtime if tz is None else _time.gmtime + + 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 = converter(t) - us = int((t % 1.0) * 1000000) ss = min(ss, 59) # clamp out leap seconds if the platform has them result = cls(y, m, d, hh, mm, ss, us, tz) if tz is not None: diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py index 8be72a4..8dd0326 100644 --- a/Lib/test/datetimetester.py +++ b/Lib/test/datetimetester.py @@ -1728,9 +1728,15 @@ class TestDateTime(TestDate): def test_microsecond_rounding(self): # Test whether fromtimestamp "rounds up" floats that are less - # than one microsecond smaller than an integer. + # 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) + # XXX Arguably incorrect behavior. Since round(0.6112295, 6) + # returns 0.611229, we should see 611229 us below, not 611230 + self.assertEqual(self.theclass.fromtimestamp(0.6112295).microsecond, + 611230) def test_insane_fromtimestamp(self): # It's possible that some platform maps time_t to double, |