Index: Misc/NEWS =================================================================== --- Misc/NEWS (revision 80840) +++ Misc/NEWS (working copy) @@ -348,6 +348,8 @@ Library ------- +- Issue #8644: td.total_seconds() is now equivalent to td / timedelta(seconds=1). + - Issue #4265: shutil.copyfile() was leaking file descriptors when disk fills. Patch by Tres Seaver. Index: Doc/library/datetime.rst =================================================================== --- Doc/library/datetime.rst (revision 80840) +++ Doc/library/datetime.rst (working copy) @@ -287,8 +287,11 @@ .. method:: timedelta.total_seconds() Return the total number of seconds contained in the duration. Equivalent to - ``td.microseconds / 1000000 + td.seconds + td.days * 24 * 3600``. + ``td / timedelta(seconds=1)``. + Note that for very large time intervals (greater than 280 years on + most platforms) this method will lose microsecond accuracy. + .. versionadded:: 3.2 Index: Lib/test/test_datetime.py =================================================================== --- Lib/test/test_datetime.py (revision 80840) +++ Lib/test/test_datetime.py (working copy) @@ -264,6 +264,11 @@ for total_seconds in [123456.789012, -123456.789012, 0.123456, 0, 1e6]: td = timedelta(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(), td / timedelta(seconds=1)) def test_carries(self): t1 = timedelta(days=100, Index: Modules/datetimemodule.c =================================================================== --- Modules/datetimemodule.c (revision 80840) +++ Modules/datetimemodule.c (working copy) @@ -2211,9 +2211,25 @@ static PyObject * delta_total_seconds(PyObject *self) { - return PyFloat_FromDouble(GET_TD_MICROSECONDS(self) / 1000000.0 + - GET_TD_SECONDS(self) + - GET_TD_DAYS(self) * 24.0 * 3600.0); + PyObject *total_seconds; + PyObject *total_microseconds; + 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 *