allow ctime(), gmtime(), and localtime() to take None as equivalent to an omitted arg
(closes SF bug #658254, patch #663482)
diff --git a/Modules/timemodule.c b/Modules/timemodule.c
index 21745e0..2cd9a57 100644
--- a/Modules/timemodule.c
+++ b/Modules/timemodule.c
@@ -277,13 +277,33 @@
 	return tmtotuple(p);
 }
 
+/* Parse arg tuple that can contain an optional float-or-None value;
+   format needs to be "|O:name".
+   Returns non-zero on success (parallels PyArg_ParseTuple).
+*/
+static int
+parse_time_double_args(PyObject *args, char *format, double *pwhen)
+{
+	PyObject *ot = NULL;
+
+	if (!PyArg_ParseTuple(args, format, &ot))
+		return 0;
+	if (ot == NULL || ot == Py_None)
+		*pwhen = floattime();
+	else {
+		double when = PyFloat_AsDouble(ot);
+		if (PyErr_Occurred())
+			return 0;
+		*pwhen = when;
+	}
+	return 1;
+}
+
 static PyObject *
 time_gmtime(PyObject *self, PyObject *args)
 {
 	double when;
-	if (PyTuple_Size(args) == 0)
-		when = floattime();
-	if (!PyArg_ParseTuple(args, "|d:gmtime", &when))
+	if (!parse_time_double_args(args, "|O:gmtime", &when))
 		return NULL;
 	return time_convert(when, gmtime);
 }
@@ -299,9 +319,7 @@
 time_localtime(PyObject *self, PyObject *args)
 {
 	double when;
-	if (PyTuple_Size(args) == 0)
-		when = floattime();
-	if (!PyArg_ParseTuple(args, "|d:localtime", &when))
+	if (!parse_time_double_args(args, "|O:localtime", &when))
 		return NULL;
 	return time_convert(when, localtime);
 }
@@ -502,14 +520,17 @@
 static PyObject *
 time_ctime(PyObject *self, PyObject *args)
 {
-	double dt;
+	PyObject *ot = NULL;
 	time_t tt;
 	char *p;
 
-	if (PyTuple_Size(args) == 0)
+	if (!PyArg_ParseTuple(args, "|O:ctime", &ot))
+		return NULL;
+	if (ot == NULL || ot == Py_None)
 		tt = time(NULL);
 	else {
-		if (!PyArg_ParseTuple(args, "|d:ctime", &dt))
+		double dt = PyFloat_AsDouble(ot);
+		if (PyErr_Occurred())
 			return NULL;
 		tt = _PyTime_DoubleToTimet(dt);
 		if (tt == (time_t)-1 && PyErr_Occurred())