Commit af529802 authored by Fred Drake's avatar Fred Drake

allow ctime(), gmtime(), and localtime() to take None as equivalent to an omitted arg

(closes SF bug #658254, patch #663482)
parent 291b9c3e
...@@ -157,11 +157,14 @@ The resolution is typically better than one microsecond. ...@@ -157,11 +157,14 @@ The resolution is typically better than one microsecond.
\begin{funcdesc}{ctime}{\optional{secs}} \begin{funcdesc}{ctime}{\optional{secs}}
Convert a time expressed in seconds since the epoch to a string Convert a time expressed in seconds since the epoch to a string
representing local time. If \var{secs} is not provided, the current time representing local time. If \var{secs} is not provided or
as returned by \function{time()} is used. \code{ctime(\var{secs})} \constant{None}, the current time as returned by \function{time()} is
is equivalent to \code{asctime(localtime(\var{secs}))}. used. \code{ctime(\var{secs})} is equivalent to
\code{asctime(localtime(\var{secs}))}.
Locale information is not used by \function{ctime()}. Locale information is not used by \function{ctime()}.
\versionchanged[Allowed \var{secs} to be omitted]{2.1} \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} \end{funcdesc}
\begin{datadesc}{daylight} \begin{datadesc}{daylight}
...@@ -171,16 +174,22 @@ Nonzero if a DST timezone is defined. ...@@ -171,16 +174,22 @@ Nonzero if a DST timezone is defined.
\begin{funcdesc}{gmtime}{\optional{secs}} \begin{funcdesc}{gmtime}{\optional{secs}}
Convert a time expressed in seconds since the epoch to a \class{struct_time} 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 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. provided or \constant{None}, the current time as returned by
Fractions of a second are ignored. See above for a description of the \function{time()} is used. Fractions of a second are ignored. See
\class{struct_time} object. above for a description of the \class{struct_time} object.
\versionchanged[Allowed \var{secs} to be omitted]{2.1} \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} \end{funcdesc}
\begin{funcdesc}{localtime}{\optional{secs}} \begin{funcdesc}{localtime}{\optional{secs}}
Like \function{gmtime()} but converts to local time. The dst flag is Like \function{gmtime()} but converts to local time. If \var{secs} is
set to \code{1} when DST applies to the given time. 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[Allowed \var{secs} to be omitted]{2.1}
\versionchanged[If \var{secs} is \constant{None}, the current time is
used]{2.3}
\end{funcdesc} \end{funcdesc}
\begin{funcdesc}{mktime}{t} \begin{funcdesc}{mktime}{t}
......
...@@ -185,6 +185,23 @@ class TimeTestCase(unittest.TestCase): ...@@ -185,6 +185,23 @@ class TimeTestCase(unittest.TestCase):
for unreasonable in -1e200, 1e200: for unreasonable in -1e200, 1e200:
self.assertRaises(ValueError, func, unreasonable) 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(): def test_main():
test_support.run_unittest(TimeTestCase) test_support.run_unittest(TimeTestCase)
......
...@@ -72,6 +72,11 @@ Extension modules ...@@ -72,6 +72,11 @@ Extension modules
Library 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. - nntplib does now allow to ignore a .netrc file.
- urllib2 now recognizes Basic authentication even if other authentication - urllib2 now recognizes Basic authentication even if other authentication
......
...@@ -277,13 +277,33 @@ time_convert(double when, struct tm * (*function)(const time_t *)) ...@@ -277,13 +277,33 @@ time_convert(double when, struct tm * (*function)(const time_t *))
return tmtotuple(p); 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 * static PyObject *
time_gmtime(PyObject *self, PyObject *args) time_gmtime(PyObject *self, PyObject *args)
{ {
double when; double when;
if (PyTuple_Size(args) == 0) if (!parse_time_double_args(args, "|O:gmtime", &when))
when = floattime();
if (!PyArg_ParseTuple(args, "|d:gmtime", &when))
return NULL; return NULL;
return time_convert(when, gmtime); return time_convert(when, gmtime);
} }
...@@ -299,9 +319,7 @@ static PyObject * ...@@ -299,9 +319,7 @@ static PyObject *
time_localtime(PyObject *self, PyObject *args) time_localtime(PyObject *self, PyObject *args)
{ {
double when; double when;
if (PyTuple_Size(args) == 0) if (!parse_time_double_args(args, "|O:localtime", &when))
when = floattime();
if (!PyArg_ParseTuple(args, "|d:localtime", &when))
return NULL; return NULL;
return time_convert(when, localtime); return time_convert(when, localtime);
} }
...@@ -502,14 +520,17 @@ is used."); ...@@ -502,14 +520,17 @@ is used.");
static PyObject * static PyObject *
time_ctime(PyObject *self, PyObject *args) time_ctime(PyObject *self, PyObject *args)
{ {
double dt; PyObject *ot = NULL;
time_t tt; time_t tt;
char *p; 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); tt = time(NULL);
else { else {
if (!PyArg_ParseTuple(args, "|d:ctime", &dt)) double dt = PyFloat_AsDouble(ot);
if (PyErr_Occurred())
return NULL; return NULL;
tt = _PyTime_DoubleToTimet(dt); tt = _PyTime_DoubleToTimet(dt);
if (tt == (time_t)-1 && PyErr_Occurred()) if (tt == (time_t)-1 && PyErr_Occurred())
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment