]> granicus.if.org Git - python/commitdiff
allow ctime(), gmtime(), and localtime() to take None as equivalent to an omitted arg
authorFred Drake <fdrake@acm.org>
Tue, 3 Aug 2004 17:58:55 +0000 (17:58 +0000)
committerFred Drake <fdrake@acm.org>
Tue, 3 Aug 2004 17:58:55 +0000 (17:58 +0000)
(closes SF bug #658254, patch #663482)

Doc/lib/libtime.tex
Lib/test/test_time.py
Misc/NEWS
Modules/timemodule.c

index 04d02fbb76c53db50a6d1a8a24b328315cb4f2d8..f21f6a34aa8fcc23f049f39c18eb39f7cea7567b 100644 (file)
@@ -157,11 +157,14 @@ The resolution is typically better than one microsecond.
 
 \begin{funcdesc}{ctime}{\optional{secs}}
 Convert a time expressed in seconds since the epoch to a string
-representing local time. If \var{secs} is not provided, the current time
-as returned by \function{time()} is used.  \code{ctime(\var{secs})}
-is equivalent to \code{asctime(localtime(\var{secs}))}.
+representing local time. If \var{secs} is not provided or
+\constant{None}, the current time as returned by \function{time()} is
+used.  \code{ctime(\var{secs})} is equivalent to
+\code{asctime(localtime(\var{secs}))}.
 Locale information is not used by \function{ctime()}.
 \versionchanged[Allowed \var{secs} to be omitted]{2.1}
+\versionchanged[If \var{secs} is \constant{None}, the current time is
+                used]{2.3}
 \end{funcdesc}
 
 \begin{datadesc}{daylight}
@@ -171,16 +174,22 @@ Nonzero if a DST timezone is defined.
 \begin{funcdesc}{gmtime}{\optional{secs}}
 Convert a time expressed in seconds since the epoch to a \class{struct_time}
 in UTC in which the dst flag is always zero.  If \var{secs} is not
-provided, the current time as returned by \function{time()} is used.
-Fractions of a second are ignored.  See above for a description of the
-\class{struct_time} object.
+provided or \constant{None}, the current time as returned by
+\function{time()} is used.  Fractions of a second are ignored.  See
+above for a description of the \class{struct_time} object.
 \versionchanged[Allowed \var{secs} to be omitted]{2.1}
+\versionchanged[If \var{secs} is \constant{None}, the current time is
+                used]{2.3}
 \end{funcdesc}
 
 \begin{funcdesc}{localtime}{\optional{secs}}
-Like \function{gmtime()} but converts to local time.  The dst flag is
-set to \code{1} when DST applies to the given time.
+Like \function{gmtime()} but converts to local time.  If \var{secs} is
+not provided or \constant{None}, the current time as returned by
+\function{time()} is used.  The dst flag is set to \code{1} when DST
+applies to the given time.
 \versionchanged[Allowed \var{secs} to be omitted]{2.1}
+\versionchanged[If \var{secs} is \constant{None}, the current time is
+                used]{2.3}
 \end{funcdesc}
 
 \begin{funcdesc}{mktime}{t}
index 64f1f01d6e79dd3925885fd860aa4fdc88d4373b..768e7a09c9262e9b44661036e75c9b7daf3e0219 100644 (file)
@@ -185,6 +185,23 @@ class TimeTestCase(unittest.TestCase):
             for unreasonable in -1e200, 1e200:
                 self.assertRaises(ValueError, func, unreasonable)
 
+    def test_ctime_without_arg(self):
+        # Not sure how to check the values, since the clock could tick
+        # at any time.  Make sure these are at least accepted and
+        # don't raise errors.
+        time.ctime()
+        time.ctime(None)
+
+    def test_gmtime_without_arg(self):
+        t0 = time.mktime(time.gmtime())
+        t1 = time.mktime(time.gmtime(None))
+        self.assert_(0 <= (t1-t0) < 0.2)
+
+    def test_localtime_without_arg(self):
+        t0 = time.mktime(time.localtime())
+        t1 = time.mktime(time.localtime(None))
+        self.assert_(0 <= (t1-t0) < 0.2)
+
 def test_main():
     test_support.run_unittest(TimeTestCase)
 
index 2ea4cb1e24767ffe8b82862e925e97b2731c1b16..11e224b448f7eaf70f5bc269e6ae4c96ee421cdf 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -72,6 +72,11 @@ Extension modules
 Library
 -------
 
+- The following methods in time support passing of None: ctime(), gmtime(),
+  and localtime().  If None is provided, the current time is used (the
+  same as when the argument is omitted).
+  [SF bug 658254, patch 663482]
+
 - nntplib does now allow to ignore a .netrc file.
 
 - urllib2 now recognizes Basic authentication even if other authentication
index 21745e031d75d74acf4711b37040a0ccb8384f0b..2cd9a571f3dc1eab35d69fc75ddd495abd460585 100644 (file)
@@ -277,13 +277,33 @@ time_convert(double when, struct tm * (*function)(const time_t *))
        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 @@ static PyObject *
 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 @@ is used.");
 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())