Index: Modules/datetimemodule.c =================================================================== --- Modules/datetimemodule.c (revision 43263) +++ Modules/datetimemodule.c (working copy) @@ -922,6 +922,29 @@ return call_utc_tzinfo_method(tzinfo, "dst", tzinfoarg, none); } +/* Get the appropriate dstflag value from a datetime object. + * Caller should check PyErr_Occurred() when the return value is -1 */ +static int +get_dstflag(PyDateTime_DateTime *self) +{ + int dstflag = -1; + + if (HASTZINFO(self) && self->tzinfo != Py_None) { + int none; + + dstflag = call_dst(self->tzinfo, (PyObject *)self, &none); + if (dstflag == -1 && PyErr_Occurred()) + return -1; + + if (none) + dstflag = -1; + else if (dstflag != 0) + dstflag = 1; + } + return dstflag; +} + + /* Call tzinfo.tzname(tzinfoarg), and return the result. tzinfo must be * an instance of the tzinfo class or None. If tzinfo isn't None, and * tzname() doesn't return None or a string, TypeError is raised and this @@ -4320,21 +4343,11 @@ static PyObject * datetime_timetuple(PyDateTime_DateTime *self) { - int dstflag = -1; + int dstflag = get_dstflag(self); + if (dstflag == -1 && PyErr_Occurred()) { + return NULL; + } - if (HASTZINFO(self) && self->tzinfo != Py_None) { - int 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; - - } return build_struct_time(GET_YEAR(self), GET_MONTH(self), GET_DAY(self), @@ -4439,6 +4452,34 @@ } static PyObject * +datetime_timestamp(PyDateTime_DateTime *self) +{ + PyObject *time; + PyObject *result = NULL; + + int dstflag = get_dstflag(self); + if (dstflag == -1 && PyErr_Occurred()) { + return NULL; + } + + time = PyImport_ImportModule("time"); + if (time != NULL) { + result = PyObject_CallMethod(time, "mktime", "((iiiiiiiii))", + GET_YEAR(self), + GET_MONTH(self), + GET_DAY(self), + DATE_GET_HOUR(self), + DATE_GET_MINUTE(self), + DATE_GET_SECOND(self), + 0, + 0, + dstflag); + Py_DECREF(time); + } + return result; +} + +static PyObject * datetime_reduce(PyDateTime_DateTime *self, PyObject *arg) { return Py_BuildValue("(ON)", self->ob_type, datetime_getstate(self)); @@ -4515,6 +4556,9 @@ {"astimezone", (PyCFunction)datetime_astimezone, METH_KEYWORDS, PyDoc_STR("tz -> convert to local time in new timezone tz\n")}, + {"timestamp", (PyCFunction)datetime_timestamp, METH_NOARGS, + PyDoc_STR("Return a timestamp.")}, + {"__reduce__", (PyCFunction)datetime_reduce, METH_NOARGS, PyDoc_STR("__reduce__() -> (cls, state)")}, Index: Lib/test/test_datetime.py =================================================================== --- Lib/test/test_datetime.py (revision 43263) +++ Lib/test/test_datetime.py (working copy) @@ -1570,6 +1570,11 @@ self.assertEqual(dt2.newmeth(-7), dt1.year + dt1.month + dt1.second - 7) + def test_timestamp(self): + import time + d = self.theclass.now() + self.assertEqual(time.mktime(d.timetuple()), d.timestamp()) + class SubclassTime(time): sub_var = 1 Index: Doc/lib/libdatetime.tex =================================================================== --- Doc/lib/libdatetime.tex (revision 43263) +++ Doc/lib/libdatetime.tex (working copy) @@ -887,6 +887,11 @@ else \code{tm_isdst} is set to \code{0}. \end{methoddesc} +\begin{methoddesc}{timestamp}{} + Return a POSIX timestamp. This is equivalent to + \code{time.mktime(\var{d}.timetuple())} +\end{methoddesc} + \begin{methoddesc}{utctimetuple}{} If \class{datetime} instance \var{d} is naive, this is the same as \code{\var{d}.timetuple()} except that \member{tm_isdst} is forced to 0