SF patch 876130:  add C API to datetime module, from Anthony Tuininga.
The LaTeX is untested (well, so is the new API, for that matter).
Note that I also changed NULL to get spelled consistently in concrete.tex.
If that was a wrong thing to do, Fred should yell at me.
diff --git a/Doc/api/concrete.tex b/Doc/api/concrete.tex
index 63f9667..176d786 100644
--- a/Doc/api/concrete.tex
+++ b/Doc/api/concrete.tex
@@ -137,7 +137,7 @@
                                                int base}
   Return a new \ctype{PyIntObject} or \ctype{PyLongObject} based on the
   string value in \var{str}, which is interpreted according to the radix in
-  \var{base}.  If \var{pend} is non-\NULL, \code{*\var{pend}} will point to
+  \var{base}.  If \var{pend} is non-\NULL{}, \code{*\var{pend}} will point to
   the first character in \var{str} which follows the representation of the
   number.  If \var{base} is \code{0}, the radix will be determined based on
   the leading characters of \var{str}: if \var{str} starts with \code{'0x'}
@@ -248,7 +248,7 @@
                                                 int base}
   Return a new \ctype{PyLongObject} based on the string value in
   \var{str}, which is interpreted according to the radix in
-  \var{base}.  If \var{pend} is non-\NULL, \code{*\var{pend}} will
+  \var{base}.  If \var{pend} is non-\NULL{}, \code{*\var{pend}} will
   point to the first character in \var{str} which follows the
   representation of the number.  If \var{base} is \code{0}, the radix
   will be determined based on the leading characters of \var{str}: if
@@ -538,7 +538,7 @@
 
 \begin{cfuncdesc}{PyObject*}{PyString_FromString}{const char *v}
   Returns a new string object with the value \var{v} on success, and
-  \NULL{} on failure.  The parameter \var{v} must not be \NULL; it
+  \NULL{} on failure.  The parameter \var{v} must not be \NULL{}; it
   will not be checked.
 \end{cfuncdesc}
 
@@ -546,7 +546,7 @@
                                                          int len}
   Returns a new string object with the value \var{v} and length
   \var{len} on success, and \NULL{} on failure.  If \var{v} is
-  \NULL, the contents of the string are uninitialized.
+  \NULL{}, the contents of the string are uninitialized.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{PyObject*}{PyString_FromFormat}{const char *format, ...}
@@ -615,7 +615,7 @@
 
   The function accepts both string and Unicode objects as input. For
   Unicode objects it returns the default encoded version of the
-  object.  If \var{length} is \NULL, the resulting buffer may not
+  object.  If \var{length} is \NULL{}, the resulting buffer may not
   contain NUL characters; if it does, the function returns \code{-1}
   and a \exception{TypeError} is raised.
 
@@ -636,7 +636,7 @@
   new reference.  The reference to the old value of \var{string} will
   be stolen.  If the new string cannot be created, the old reference
   to \var{string} will still be discarded and the value of
-  \var{*string} will be set to \NULL; the appropriate exception will
+  \var{*string} will be set to \NULL{}; the appropriate exception will
   be set.
 \end{cfuncdesc}
 
@@ -898,9 +898,9 @@
   given size. \var{u} may be \NULL{} which causes the contents to be
   undefined. It is the user's responsibility to fill in the needed
   data.  The buffer is copied into the new object. If the buffer is
-  not \NULL, the return value might be a shared object. Therefore,
+  not \NULL{}, the return value might be a shared object. Therefore,
   modification of the resulting Unicode object is only allowed when
-  \var{u} is \NULL.
+  \var{u} is \NULL{}.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{Py_UNICODE*}{PyUnicode_AsUnicode}{PyObject *unicode}
@@ -1070,9 +1070,9 @@
                                                int *byteorder}
   Decodes \var{length} bytes from a UTF-16 encoded buffer string and
   returns the corresponding Unicode object.  \var{errors} (if
-  non-\NULL) defines the error handling. It defaults to ``strict''.
+  non-\NULL{}) defines the error handling. It defaults to ``strict''.
 
-  If \var{byteorder} is non-\NULL, the decoder starts decoding using
+  If \var{byteorder} is non-\NULL{}, the decoder starts decoding using
   the given byte order:
 
 \begin{verbatim}
@@ -1086,7 +1086,7 @@
   string.  After completion, \var{*byteorder} is set to the current
   byte order at the end of input data.
 
-  If \var{byteorder} is \NULL, the codec starts in native order mode.
+  If \var{byteorder} is \NULL{}, the codec starts in native order mode.
 
   Returns \NULL{} if an exception was raised by the codec.
 \end{cfuncdesc}
@@ -1351,7 +1351,7 @@
 \begin{cfuncdesc}{PyObject*}{PyUnicode_Split}{PyObject *s,
                                               PyObject *sep,
                                               int maxsplit}
-  Split a string giving a list of Unicode strings.  If sep is \NULL,
+  Split a string giving a list of Unicode strings.  If sep is \NULL{},
   splitting will be done at all whitespace substrings.  Otherwise,
   splits occur at the given separator.  At most \var{maxsplit} splits
   will be done.  If negative, no limit is set.  Separators are not
@@ -1605,7 +1605,7 @@
   The tuple values are initialized to the subsequent \var{n} C arguments
   pointing to Python objects.  \samp{PyTuple_Pack(2, \var{a}, \var{b})}
   is equivalent to \samp{Py_BuildValue("(OO)", \var{a}, \var{b})}.
-  \versionadded{2.4}			 
+  \versionadded{2.4}
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{int}{PyTuple_Size}{PyObject *p}
@@ -1661,7 +1661,7 @@
   \code{*\var{p}} will be the same as before calling this function.
   If the object referenced by \code{*\var{p}} is replaced, the
   original \code{*\var{p}} is destroyed.  On failure, returns
-  \code{-1} and sets \code{*\var{p}} to \NULL, and raises
+  \code{-1} and sets \code{*\var{p}} to \NULL{}, and raises
   \exception{MemoryError} or
   \exception{SystemError}.
   \versionchanged[Removed unused third parameter, \var{last_is_sticky}]{2.2}
@@ -1841,7 +1841,7 @@
   in \var{p} is matches \var{key}, return \code{1}, otherwise return
   \code{0}.  On error, return \code{-1}.  This is equivalent to the
   Python expression \samp{\var{key} in \var{p}}.
-  \versionadded{2.4}			 
+  \versionadded{2.4}
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{PyObject*}{PyDict_Copy}{PyObject *p}
@@ -1923,7 +1923,7 @@
   dictionary, and false once all pairs have been reported.  The
   parameters \var{pkey} and \var{pvalue} should either point to
   \ctype{PyObject*} variables that will be filled in with each key and
-  value, respectively, or may be \NULL.  Any references returned through
+  value, respectively, or may be \NULL{}.  Any references returned through
   them are borrowed.  \var{ppos} should not be altered during iteration.
   Its value represents offsets within the internal dictionary structure,
   and since the structure is sparse, the offsets are not consecutive.
@@ -2040,7 +2040,7 @@
   On success, returns a new file object that is opened on the file
   given by \var{filename}, with a file mode given by \var{mode}, where
   \var{mode} has the same semantics as the standard C routine
-  \cfunction{fopen()}\ttindex{fopen()}.  On failure, returns \NULL.
+  \cfunction{fopen()}\ttindex{fopen()}.  On failure, returns \NULL{}.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{PyObject*}{PyFile_FromFile}{FILE *fp,
@@ -2143,7 +2143,7 @@
   Create a new instance of a specific class without calling it's
   constructor.  \var{class} is the class of new object.  The
   \var{dict} parameter will be used as the object's \member{__dict__};
-  if \NULL, a new dictionary will be created for the instance.
+  if \NULL{}, a new dictionary will be created for the instance.
 \end{cfuncdesc}
 
 
@@ -2161,7 +2161,7 @@
 
 \begin{cfuncdesc}{int}{PyMethod_Check}{PyObject *o}
   Return true if \var{o} is a method object (has type
-  \cdata{PyMethod_Type}).  The parameter must not be \NULL.
+  \cdata{PyMethod_Type}).  The parameter must not be \NULL{}.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{PyObject*}{PyMethod_New}{PyObject *func.
@@ -2196,7 +2196,7 @@
 
 \begin{cfuncdesc}{PyObject*}{PyMethod_Self}{PyObject *meth}
   Return the instance associated with the method \var{meth} if it is
-  bound, otherwise return \NULL.
+  bound, otherwise return \NULL{}.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{PyObject*}{PyMethod_GET_SELF}{PyObject *meth}
@@ -2260,7 +2260,7 @@
   Return the name of the file from which \var{module} was loaded using
   \var{module}'s \member{__file__} attribute.  If this is not defined,
   or if it is not a string, raise \exception{SystemError} and return
-  \NULL.
+  \NULL{}.
   \withsubitem{(module attribute)}{\ttindex{__file__}}
   \withsubitem{(built-in exception)}{\ttindex{SystemError}}
 \end{cfuncdesc}
@@ -2401,7 +2401,7 @@
 
 \begin{cfuncdesc}{int}{PySlice_Check}{PyObject *ob}
   Returns true if \var{ob} is a slice object; \var{ob} must not be
-  \NULL.
+  \NULL{}.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{PyObject*}{PySlice_New}{PyObject *start, PyObject *stop,
@@ -2409,7 +2409,7 @@
   Return a new slice object with the given values.  The \var{start},
   \var{stop}, and \var{step} parameters are used as the values of the
   slice object attributes of the same names.  Any of the values may be
-  \NULL, in which case the \code{None} will be used for the
+  \NULL{}, in which case the \code{None} will be used for the
   corresponding attribute.  Returns \NULL{} if the new object could
   not be allocated.
 \end{cfuncdesc}
@@ -2431,7 +2431,7 @@
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{int}{PySlice_GetIndicesEx}{PySliceObject *slice, int length,
-                                             int *start, int *stop, int *step, 
+                                             int *start, int *stop, int *step,
                                              int *slicelength}
 Usable replacement for \cfunction{PySlice_GetIndices}.  Retrieve the
 start, stop, and step indices from the slice object \var{slice}
@@ -2475,9 +2475,9 @@
   parameter, \var{callback}, can be a callable object that receives
   notification when \var{ob} is garbage collected; it should accept a
   single parameter, which will be the weak reference object itself.
-  \var{callback} may also be \code{None} or \NULL.  If \var{ob}
+  \var{callback} may also be \code{None} or \NULL{}.  If \var{ob}
   is not a weakly-referencable object, or if \var{callback} is not
-  callable, \code{None}, or \NULL, this will return \NULL{} and
+  callable, \code{None}, or \NULL{}, this will return \NULL{} and
   raise \exception{TypeError}.
   \versionadded{2.2}
 \end{cfuncdesc}
@@ -2490,9 +2490,9 @@
   parameter, \var{callback}, can be a callable object that receives
   notification when \var{ob} is garbage collected; it should accept a
   single parameter, which will be the weak reference object itself.
-  \var{callback} may also be \code{None} or \NULL.  If \var{ob} is not
+  \var{callback} may also be \code{None} or \NULL{}.  If \var{ob} is not
   a weakly-referencable object, or if \var{callback} is not callable,
-  \code{None}, or \NULL, this will return \NULL{} and raise
+  \code{None}, or \NULL{}, this will return \NULL{} and raise
   \exception{TypeError}.
   \versionadded{2.2}
 \end{cfuncdesc}
@@ -2535,7 +2535,7 @@
                                                     void (*destr)(void *)}
   Create a \ctype{PyCObject} from the \code{void *}\var{cobj}.  The
   \var{destr} function will be called when the object is reclaimed,
-  unless it is \NULL.
+  unless it is \NULL{}.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{PyObject*}{PyCObject_FromVoidPtrAndDesc}{void* cobj,
@@ -2557,7 +2557,7 @@
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{int}{PyCObject_SetVoidPtr}{PyObject* self, void* cobj}
-  Set the void pointer inside \var{self} to \var{cobj}. 
+  Set the void pointer inside \var{self} to \var{cobj}.
   The \ctype{PyCObject} must not have an associated destructor.
   Return true on success, false on failure.
 \end{cfuncdesc}
@@ -2585,12 +2585,12 @@
 
 \begin{cfuncdesc}{int}{PyCell_Check}{ob}
   Return true if \var{ob} is a cell object; \var{ob} must not be
-  \NULL.
+  \NULL{}.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{PyObject*}{PyCell_New}{PyObject *ob}
   Create and return a new cell object containing the value \var{ob}.
-  The parameter may be \NULL.
+  The parameter may be \NULL{}.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{PyObject*}{PyCell_Get}{PyObject *cell}
@@ -2605,7 +2605,7 @@
 \begin{cfuncdesc}{int}{PyCell_Set}{PyObject *cell, PyObject *value}
   Set the contents of the cell object \var{cell} to \var{value}.  This
   releases the reference to any current content of the cell.
-  \var{value} may be \NULL.  \var{cell} must be non-\NULL; if it is
+  \var{value} may be \NULL{}.  \var{cell} must be non-\NULL{}; if it is
   not a cell object, \code{-1} will be returned.  On success, \code{0}
   will be returned.
 \end{cfuncdesc}
@@ -2633,16 +2633,137 @@
 
 \begin{cfuncdesc}{int}{PyGen_Check}{ob}
   Return true if \var{ob} is a generator object; \var{ob} must not be
-  \NULL.
+  \NULL{}.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{int}{PyGen_CheckExact}{ob}
   Return true if \var{ob}'s type is \var{PyGen_Type}
   is a generator object; \var{ob} must not be
-  \NULL.
+  \NULL{}.
 \end{cfuncdesc}
 
 \begin{cfuncdesc}{PyObject*}{PyGen_New}{PyFrameObject *frame}
   Create and return a new generator object based on the \var{frame} object.
-  The parameter must not be \NULL.
+  The parameter must not be \NULL{}.
+\end{cfuncdesc}
+
+
+\subsection{DateTime Objects \label{datetime-objects}}
+
+Various date and time objects are supplied by the \module{datetime}
+module.  Before using any of these functions, the header file
+\file{datetime.h} must be included in your source (note that this is
+not include by \file{Python.h}), and macro \cfunction{PyDateTime_IMPORT()}
+must be invoked.  The macro arranges to put a pointer to a C structure
+in a static variable \code{PyDateTimeAPI}, which is used by the following
+macros:
+
+\begin{cfuncdesc}{int}{PyDate_Check}{ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_DateType} or
+  a subtype of \cdata{PyDateTime_DateType}.  \var{ob} must not be
+  \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDate_CheckExact}{ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_DateType}.
+  \var{ob} must not be \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDateTime_Check}{ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_DateTimeType} or
+  a subtype of \cdata{PyDateTime_DateTimeType}.  \var{ob} must not be
+  \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDateTime_CheckExact}{ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_DateTimeType}.
+  \var{ob} must not be \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyTime_Check}{ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_TimeType} or
+  a subtype of \cdata{PyDateTime_TimeType}.  \var{ob} must not be
+  \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyTime_CheckExact}{ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_TimeType}.
+  \var{ob} must not be \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDelta_Check}{ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_DeltaType} or
+  a subtype of \cdata{PyDateTime_DeltaType}.  \var{ob} must not be
+  \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyDelta_CheckExact}{ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_DeltaType}.
+  \var{ob} must not be \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyTZInfo_Check}{ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_TZInfoType} or
+  a subtype of \cdata{PyDateTime_TZInfoType}.  \var{ob} must not be
+  \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{int}{PyTZInfo_CheckExact}{ob}
+  Return true if \var{ob} is of type \cdata{PyDateTime_TZInfoType}.
+  \var{ob} must not be \NULL{}.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDate_FromDate}{int year, int month, int day}
+  Return a \code{datetime.date} object with the specified year, month
+  and day.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDate_FromDateAndTime}{int year, int month,
+        int day, int hour, int minute, int second, int usecond}
+  Return a \code{datetime.datetime} object with the specified year, month,
+  day, hour, minute, second and microsecond.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyTime_FromTime}{int hour, int minute,
+        int second, int usecond}
+  Return a \code{datetime.time} object with the specified hour, minute,
+  second and microsecond.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDelta_FromDSU}{int days, int seconds,
+        int useconds}
+  Return a \code{datetime.timedelta} object representing the given number
+  of days, seconds and microseconds.  Normalization is performed so that
+  the resulting number of microseconds and seconds lie in the ranges
+  documented for \code{datetime.timedelta} objects.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDateTime_FromTimestamp}{PyObject *args}
+  Create and return a new \code{datetime.datetime} object given an argument
+  tuple suitable for passing to \code{datetime.datetime.fromtimestamp()}.
+  This macro is included for the convenience of modules implementing the
+  DB API.
+  \versionadded{2.4}
+\end{cfuncdesc}
+
+\begin{cfuncdesc}{PyObject*}{PyDate_FromTimestamp}{PyObject *args}
+  Create and return a new \code{datetime.date} object given an argument
+  tuple suitable for passing to \code{datetime.date.fromtimestamp()}.
+  This macro is included for the convenience of modules implementing the
+  DB API.
+  \versionadded{2.4}
 \end{cfuncdesc}
diff --git a/Include/datetime.h b/Include/datetime.h
index 9364e24..1b8ebb9 100644
--- a/Include/datetime.h
+++ b/Include/datetime.h
@@ -3,6 +3,9 @@
 
 #ifndef DATETIME_H
 #define DATETIME_H
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /* Fields are packed into successive bytes, each viewed as unsigned and
  * big-endian, unless otherwise noted:
@@ -132,6 +135,36 @@
          (((PyDateTime_Time*)o)->data[4] << 8)  |	\
           ((PyDateTime_Time*)o)->data[5])
 
+
+/* Define structure for C API. */
+typedef struct {
+    /* type objects */
+    PyTypeObject *DateType;
+    PyTypeObject *DateTimeType;
+    PyTypeObject *TimeType;
+    PyTypeObject *DeltaType;
+    PyTypeObject *TZInfoType;
+
+    /* constructors */
+    PyObject *(*Date_FromDate)(int, int, int, PyTypeObject*);
+    PyObject *(*DateTime_FromDateAndTime)(int, int, int, int, int, int, int,
+            PyObject*, PyTypeObject*);
+    PyObject *(*Time_FromTime)(int, int, int, int, PyObject*, PyTypeObject*);
+    PyObject *(*Delta_FromDelta)(int, int, int, int, PyTypeObject*);
+
+    /* constructors for the DB API */
+    PyObject *(*DateTime_FromTimestamp)(PyObject*, PyObject*, PyObject*);
+    PyObject *(*Date_FromTimestamp)(PyObject*, PyObject*);
+
+} PyDateTime_CAPI;
+
+
+/* "magic" constant used to partially protect against developer mistakes. */
+#define DATETIME_API_MAGIC 0x414548d5
+
+#ifdef Py_BUILD_CORE
+
+/* Macros for type checking when building the Python core. */
 #define PyDate_Check(op) PyObject_TypeCheck(op, &PyDateTime_DateType)
 #define PyDate_CheckExact(op) ((op)->ob_type == &PyDateTime_DateType)
 
@@ -147,4 +180,66 @@
 #define PyTZInfo_Check(op) PyObject_TypeCheck(op, &PyDateTime_TZInfoType)
 #define PyTZInfo_CheckExact(op) ((op)->ob_type == &PyDateTime_TZInfoType)
 
+#else
+
+/* Define global variable for the C API and a macro for setting it. */
+static PyDateTime_CAPI *PyDateTimeAPI;
+
+#define PyDateTime_IMPORT \
+        PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_Import("datetime", \
+                                                            "datetime_CAPI")
+
+/* This macro would be used if PyCObject_ImportEx() was created.
+#define PyDateTime_IMPORT \
+        PyDateTimeAPI = (PyDateTime_CAPI*) PyCObject_ImportEx("datetime", \
+                                                            "datetime_CAPI", \
+                                                            DATETIME_API_MAGIC)
+*/
+
+/* Macros for type checking when not building the Python core. */
+#define PyDate_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateType)
+#define PyDate_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DateType)
+
+#define PyDateTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DateTimeType)
+#define PyDateTime_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DateTimeType)
+
+#define PyTime_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TimeType)
+#define PyTime_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->TimeType)
+
+#define PyDelta_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->DeltaType)
+#define PyDelta_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->DeltaType)
+
+#define PyTZInfo_Check(op) PyObject_TypeCheck(op, PyDateTimeAPI->TZInfoType)
+#define PyTZInfo_CheckExact(op) ((op)->ob_type == PyDateTimeAPI->TZInfoType)
+
+/* Macros for accessing constructors in a simplified fashion. */
+#define PyDate_FromDate(year, month, day) \
+	PyDateTimeAPI->Date_FromDate(year, month, day, PyDateTimeAPI->DateType)
+
+#define PyDateTime_FromDateAndTime(year, month, day, hour, min, sec, usec) \
+	PyDateTimeAPI->DateTime_FromDateAndTime(year, month, day, hour, \
+		min, sec, usec, Py_None, PyDateTimeAPI->DateTimeType)
+
+#define PyTime_FromTime(hour, minute, second, usecond) \
+	PyDateTimeAPI->Time_FromTime(hour, minute, second, usecond, \
+		Py_None, PyDateTimeAPI->TimeType)
+
+#define PyDelta_FromDSU(days, seconds, useconds) \
+	PyDateTimeAPI->Delta_FromDelta(days, seconds, useconds, 1,
+		PyDateTimeAPI->DeltaType)
+
+/* Macros supporting the DB API. */
+#define PyDateTime_FromTimestamp(args) \
+	PyDateTimeAPI->DateTime_FromTimestamp( \
+		(PyObject*) (PyDateTimeAPI->DateTimeType), args, NULL)
+
+#define PyDate_FromTimestamp(args) \
+	PyDateTimeAPI->Date_FromTimestamp( \
+		(PyObject*) (PyDateTimeAPI->DateType), args)
+
+#endif	/* Py_BUILD_CORE */
+
+#ifdef __cplusplus
+}
+#endif
 #endif
diff --git a/Misc/ACKS b/Misc/ACKS
index 3347c6f..4465970 100644
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -569,6 +569,7 @@
 Laurence Tratt
 John Tromp
 Jason Trowbridge
+Anthony Tuininga
 Stephen Turner
 Bill Tutt
 Doobee R. Tzeck
diff --git a/Misc/NEWS b/Misc/NEWS
index f2b65e6..b5038f7 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -559,6 +559,10 @@
 C API
 -----
 
+- Thanks to Anthony Tuininga, the datetime module now supplies a C API
+  containing type-check macros and constructors.  See new docs in the
+  Python/C API Reference Manual for details.
+
 - Private function _PyTime_DoubleToTimet added, to convert a Python
   timestamp (C double) to platform time_t with some out-of-bounds
   checking.  Declared in new header file timefuncs.h.  It would be
diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c
index d9cf604..ee7387c 100644
--- a/Modules/datetimemodule.c
+++ b/Modules/datetimemodule.c
@@ -9,7 +9,13 @@
 #include <time.h>
 
 #include "timefuncs.h"
+
+/* Differentiate between building the core module and building extension
+ * modules.
+ */
+#define Py_BUILD_CORE
 #include "datetime.h"
+#undef Py_BUILD_CORE
 
 /* We require that C int be at least 32 bits, and use int virtually
  * everywhere.  In just a few cases we use a temp long, where a Python
@@ -4520,6 +4526,24 @@
 	{NULL, NULL}
 };
 
+/* C API.  Clients get at this via PyDateTime_IMPORT, defined in
+ * datetime.h.
+ */
+static PyDateTime_CAPI CAPI = {
+        &PyDateTime_DateType,
+        &PyDateTime_DateTimeType,
+        &PyDateTime_TimeType,
+        &PyDateTime_DeltaType,
+        &PyDateTime_TZInfoType,
+        new_date_ex,
+        new_datetime_ex,
+        new_time_ex,
+        new_delta_ex,
+        datetime_fromtimestamp,
+        date_fromtimestamp
+};
+
+
 PyMODINIT_FUNC
 initdatetime(void)
 {
@@ -4633,6 +4657,12 @@
 	Py_INCREF(&PyDateTime_TZInfoType);
 	PyModule_AddObject(m, "tzinfo", (PyObject *) &PyDateTime_TZInfoType);
 
+        x = PyCObject_FromVoidPtrAndDesc(&CAPI, (void*) DATETIME_API_MAGIC,
+                NULL);
+        if (x == NULL)
+            return;
+        PyModule_AddObject(m, "datetime_CAPI", x);
+
 	/* A 4-year cycle has an extra leap day over what we'd get from
 	 * pasting together 4 single years.
 	 */