Index: Doc/library/datetime.rst =================================================================== --- Doc/library/datetime.rst (révision 67710) +++ Doc/library/datetime.rst (copie de travail) @@ -925,6 +925,13 @@ boundary. +.. method:: datetime.totimestamp() + + Return timestamp of the datetime as (seconds, microseconds): POSIX + timesteamp (seconds) and microseconds since the epoch. The same as + ``(time.mktime(self.timetuple()), self.microsecond)``. + + .. method:: datetime.toordinal() Return the proleptic Gregorian ordinal of the date. The same as Index: Lib/test/test_datetime.py =================================================================== --- Lib/test/test_datetime.py (révision 67710) +++ Lib/test/test_datetime.py (copie de travail) @@ -1458,6 +1458,17 @@ got = self.theclass.utcfromtimestamp(ts) self.verify_field_equality(expected, got) + def test_totimestamp(self): + import time + now = self.theclass.now() + timestamp1 = now.totimestamp() + timestamp2 = (time.mktime(now.timetuple()), now.microsecond) + self.assertEquals(timestamp1, timestamp2) + + for seconds in xrange(-1, 2): + epoch = self.theclass.fromtimestamp(seconds) + self.assertEquals(epoch.totimestamp(), (seconds, 0)) + def test_microsecond_rounding(self): # Test whether fromtimestamp "rounds up" floats that are less # than one microsecond smaller than an integer. Index: Modules/datetimemodule.c =================================================================== --- Modules/datetimemodule.c (révision 67710) +++ Modules/datetimemodule.c (copie de travail) @@ -4527,6 +4527,54 @@ return build_struct_time(y, m, d, hh, mm, ss, 0); } +#ifdef HAVE_MKTIME + +/* datetime_totimestamp will fail if time.mktime(...) is not defined. */ +static PyObject * +datetime_totimestamp(PyDateTime_DateTime *self) +{ + struct tm buf; + time_t tt; + int dstflag; + int none; + + if (HASTZINFO(self) && self->tzinfo != Py_None) { + dstflag = call_dst(self->tzinfo, (PyObject *)self, &none); + if (dstflag == -1 && PyErr_Occurred()) + return NULL; + if (none) + dstflag = -1; + else if (dstflag != 0) + dstflag = 1; + } else { + dstflag = -1; + } + + buf.tm_year = GET_YEAR(self) - 1900; + buf.tm_mon = GET_MONTH(self) - 1; + buf.tm_mday = GET_DAY(self); + buf.tm_hour = DATE_GET_HOUR(self); + buf.tm_min = DATE_GET_MINUTE(self); + buf.tm_sec = DATE_GET_SECOND(self); + buf.tm_isdst = dstflag; + buf.tm_wday = -1; + buf.tm_yday = -1; + + /* create the time tuple */ + tt = mktime(&buf); + if (tt == (time_t)(-1) && buf.tm_wday == -1) { + PyErr_SetString(PyExc_OverflowError, + "mktime argument out of range"); + return NULL; + } + + return Py_BuildValue("(lI)", + (long)tt, + DATE_GET_MICROSECOND(self)); +} + +#endif + /* Pickle support, a simple use of __reduce__. */ /* Let basestate be the non-tzinfo data string. @@ -4579,6 +4627,12 @@ PyDoc_STR("timestamp -> UTC datetime from a POSIX timestamp " "(like time.time()).")}, +#ifdef HAVE_MKTIME + {"totimestamp", (PyCFunction)datetime_totimestamp, + METH_NOARGS, + PyDoc_STR("Return (timestamp, us): POSIX timestamp and microseconds since epoch.")}, +#endif + {"strptime", (PyCFunction)datetime_strptime, METH_VARARGS | METH_CLASS, PyDoc_STR("string, format -> new datetime parsed from a string " Index: Modules/timemodule.c =================================================================== --- Modules/timemodule.c (révision 67710) +++ Modules/timemodule.c (copie de travail) @@ -602,8 +602,9 @@ time_t tt; if (!gettmarg(tup, &buf)) return NULL; + buf.tm_wday = -1; tt = mktime(&buf); - if (tt == (time_t)(-1)) { + if (tt == (time_t)(-1) && buf.tm_wday == 1) { PyErr_SetString(PyExc_OverflowError, "mktime argument out of range"); return NULL;