Kaydet (Commit) 7000e9e0 authored tarafından Mark Dickinson's avatar Mark Dickinson

Issue #8644: Improve accuracy of timedelta.total_seconds method.

(Backport of r80979 to py3k.)  Thanks Alexander Belopolsky.
üst 860852fd
...@@ -270,8 +270,12 @@ Instance methods: ...@@ -270,8 +270,12 @@ Instance methods:
.. method:: timedelta.total_seconds() .. method:: timedelta.total_seconds()
Return the total number of seconds contained in the duration. Equivalent to Return the total number of seconds contained in the duration.
``td.microseconds / 1000000 + td.seconds + td.days * 24 * 3600``. Equivalent to ``(td.microseconds + (td.seconds + td.days * 24 *
3600) * 10**6) / 10**6`` computed with true division enabled.
Note that for very large time intervals (greater than 270 years on
most platforms) this method will lose microsecond accuracy.
.. versionadded:: 2.7 .. versionadded:: 2.7
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases
""" """
from __future__ import division
import os import os
import pickle import pickle
import cPickle import cPickle
...@@ -269,6 +269,13 @@ class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase): ...@@ -269,6 +269,13 @@ class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase):
for total_seconds in [123456.789012, -123456.789012, 0.123456, 0, 1e6]: for total_seconds in [123456.789012, -123456.789012, 0.123456, 0, 1e6]:
td = timedelta(seconds=total_seconds) td = timedelta(seconds=total_seconds)
self.assertEqual(td.total_seconds(), total_seconds) self.assertEqual(td.total_seconds(), total_seconds)
# Issue8644: Test that td.total_seconds() has the same
# accuracy as td / timedelta(seconds=1).
for ms in [-1, -2, -123]:
td = timedelta(microseconds=ms)
self.assertEqual(td.total_seconds(),
((24*3600*td.days + td.seconds)*10**6
+ td.microseconds)/10**6)
def test_carries(self): def test_carries(self):
t1 = timedelta(days=100, t1 = timedelta(days=100,
......
...@@ -200,6 +200,8 @@ Library ...@@ -200,6 +200,8 @@ Library
Extension Modules Extension Modules
----------------- -----------------
- Issue #8644: Improved accuracy of timedelta.total_seconds().
- Use Clang 2.7's static analyzer to find places to clean up some code. - Use Clang 2.7's static analyzer to find places to clean up some code.
- Build the ossaudio extension on GNU/kFreeBSD. - Build the ossaudio extension on GNU/kFreeBSD.
......
...@@ -2096,9 +2096,25 @@ delta_getstate(PyDateTime_Delta *self) ...@@ -2096,9 +2096,25 @@ delta_getstate(PyDateTime_Delta *self)
static PyObject * static PyObject *
delta_total_seconds(PyObject *self) delta_total_seconds(PyObject *self)
{ {
return PyFloat_FromDouble(GET_TD_MICROSECONDS(self) / 1000000.0 + PyObject *total_seconds;
GET_TD_SECONDS(self) + PyObject *total_microseconds;
GET_TD_DAYS(self) * 24.0 * 3600.0); PyObject *one_million;
total_microseconds = delta_to_microseconds((PyDateTime_Delta *)self);
if (total_microseconds == NULL)
return NULL;
one_million = PyLong_FromLong(1000000L);
if (one_million == NULL) {
Py_DECREF(total_microseconds);
return NULL;
}
total_seconds = PyNumber_TrueDivide(total_microseconds, one_million);
Py_DECREF(total_microseconds);
Py_DECREF(one_million);
return total_seconds;
} }
static PyObject * static PyObject *
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment