Index: Doc/library/datetime.rst =================================================================== --- Doc/library/datetime.rst (révision 67177) +++ Doc/library/datetime.rst (copie de travail) @@ -221,9 +221,17 @@ | | In general, *t1* \* i == *t1* \* (i-1) + *t1* | | | is true. (1) | +--------------------------------+-----------------------------------------------+ +| ``t1 = t2 / i`` | True division (3) when using | +| | ``from __future__ import division``, | +| | otherwise works as ``t1 = t2 // i``. | ++--------------------------------+-----------------------------------------------+ | ``t1 = t2 // i`` | The floor is computed and the remainder (if | | | any) is thrown away. (3) | +--------------------------------+-----------------------------------------------+ +| ``q, r = divmod(t1, t2)`` | Computes the quotient and the remainder: | +| | ``q = t1 // t2`` (3) and ``r = t1 - q * t2``. | +| | q is an integer and r is a timedelta object. | ++--------------------------------+-----------------------------------------------+ | ``+t1`` | Returns a :class:`timedelta` object with the | | | same value. (2) | +--------------------------------+-----------------------------------------------+ Index: Modules/datetimemodule.c =================================================================== --- Modules/datetimemodule.c (révision 67177) +++ Modules/datetimemodule.c (copie de travail) @@ -1664,6 +1664,54 @@ } static PyObject * +divide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right) +{ + PyObject *pyus_left; + PyObject *pyus_right; + PyObject *result; + + pyus_left = delta_to_microseconds(left); + if (pyus_left == NULL) + return NULL; + + pyus_right = delta_to_microseconds(right); + if (pyus_right == NULL) + { + Py_DECREF(pyus_left); + return NULL; + } + + result = PyNumber_Divide(pyus_left, pyus_right); + Py_DECREF(pyus_left); + Py_DECREF(pyus_right); + return result; +} + +static PyObject * +truedivide_timedelta_timedelta(PyDateTime_Delta *left, PyDateTime_Delta *right) +{ + PyObject *pyus_left; + PyObject *pyus_right; + PyObject *result; + + pyus_left = delta_to_microseconds(left); + if (pyus_left == NULL) + return NULL; + + pyus_right = delta_to_microseconds(right); + if (pyus_right == NULL) + { + Py_DECREF(pyus_left); + return NULL; + } + + result = PyNumber_TrueDivide(pyus_left, pyus_right); + Py_DECREF(pyus_left); + Py_DECREF(pyus_right); + return result; +} + +static PyObject * delta_add(PyObject *left, PyObject *right) { PyObject *result = Py_NotImplemented; @@ -1816,6 +1864,27 @@ result = divide_timedelta_int( (PyDateTime_Delta *)left, right); + if (PyDelta_Check(right)) + result = divide_timedelta_timedelta( + (PyDateTime_Delta *)left, + (PyDateTime_Delta *)right); + } + + if (result == Py_NotImplemented) + Py_INCREF(result); + return result; +} + +static PyObject * +delta_truedivide(PyObject *left, PyObject *right) +{ + PyObject *result = Py_NotImplemented; + + if (PyDelta_Check(left)) { + if (PyDelta_Check(right)) + result = truedivide_timedelta_timedelta( + (PyDateTime_Delta *)left, + (PyDateTime_Delta *)right); } if (result == Py_NotImplemented) @@ -1823,6 +1892,46 @@ return result; } +static PyObject * +delta_divmod(PyObject *left, PyObject *right) +{ + PyObject *pyus_left; + PyObject *pyus_right; + PyObject *divmod; + PyObject *microseconds, *delta; + + if (!PyDelta_Check(left) || !PyDelta_Check(right)) { + Py_INCREF(Py_NotImplemented); + return Py_NotImplemented; + } + + pyus_left = delta_to_microseconds((PyDateTime_Delta *)left); + if (pyus_left == NULL) + return NULL; + + pyus_right = delta_to_microseconds((PyDateTime_Delta *)right); + if (pyus_right == NULL) + { + Py_DECREF(pyus_left); + return NULL; + } + + divmod = PyNumber_Divmod(pyus_left, pyus_right); + Py_DECREF(pyus_left); + Py_DECREF(pyus_right); + if (divmod == NULL) + return NULL; + + microseconds = PyTuple_GetItem(divmod, 1); + delta = microseconds_to_delta(microseconds); + if (delta == NULL) { + Py_DECREF(divmod); + return NULL; + } + PyTuple_SetItem(divmod, 1, delta); + return divmod; +} + /* Fold in the value of the tag ("seconds", "weeks", etc) component of a * timedelta constructor. sofar is the # of microseconds accounted for * so far, and there are factor microseconds per current unit, the number @@ -2125,7 +2234,7 @@ delta_multiply, /* nb_multiply */ delta_divide, /* nb_divide */ 0, /* nb_remainder */ - 0, /* nb_divmod */ + delta_divmod, /* nb_divmod */ 0, /* nb_power */ (unaryfunc)delta_negative, /* nb_negative */ (unaryfunc)delta_positive, /* nb_positive */ @@ -2155,7 +2264,7 @@ 0, /*nb_inplace_xor*/ 0, /*nb_inplace_or*/ delta_divide, /* nb_floor_divide */ - 0, /* nb_true_divide */ + delta_truedivide, /* nb_true_divide */ 0, /* nb_inplace_floor_divide */ 0, /* nb_inplace_true_divide */ }; Index: Lib/test/test_datetime.py =================================================================== --- Lib/test/test_datetime.py (révision 67177) +++ Lib/test/test_datetime.py (copie de travail) @@ -2,7 +2,7 @@ See http://www.zope.org/Members/fdrake/DateTimeWiki/TestCases """ - +from __future__ import division import os import pickle import cPickle @@ -474,6 +474,33 @@ self.assertEqual(str(t3), str(t4)) self.assertEqual(t4.as_hours(), -1) + def test_division(self): + t = timedelta(hours=1, minutes=24, seconds=19) + second = timedelta(seconds=1) + self.assertEqual(t / second, 5059.0) + self.assertEqual(t // second, 5059) + + # These tests require "from __future__ import division" + t = timedelta(minutes=2, seconds=30) + minute = timedelta(minutes=1) + self.assertEqual(t / minute, 2.5) + self.assertEqual(t // minute, 2) + + def test_divmod(self): + t = timedelta(minutes=2, seconds=30) + minute = timedelta(minutes=1) + q, r = divmod(t, minute) + self.assertEqual(q, 2) + self.assertEqual(r, timedelta(seconds=30)) + + t = timedelta(minutes=-2, seconds=30) + q, r = divmod(t, minute) + self.assertEqual(q, -2) + self.assertEqual(r, timedelta(seconds=30)) + + self.assertRaises(TypeError, divmod, t, 10) + + ############################################################################# # date tests