Reimplemented datetime.now() to be useful.
This commit is contained in:
parent
250684ddd8
commit
10cadce41e
|
@ -525,19 +525,25 @@ Other constructors, all class methods:
|
|||
See also \method{now()}, \method{fromtimestamp()}.
|
||||
\end{methoddesc}
|
||||
|
||||
\begin{methoddesc}{now}{}
|
||||
Return the current local datetime. This is like \method{today()},
|
||||
but, if possible, supplies more precision than can be gotten from
|
||||
going through a \function{time.time()} timestamp (for example,
|
||||
this may be possible on platforms that supply the C
|
||||
\begin{methoddesc}{now(tz=None)}{}
|
||||
Return the current local date and time. If optional argument
|
||||
\var{tz} is \code{None} or not specified, this is like
|
||||
\method{today()}, but, if possible, supplies more precision than can
|
||||
be gotten from going through a \function{time.time()} timestamp (for
|
||||
example, this may be possible on platforms supplying the C
|
||||
\cfunction{gettimeofday()} function).
|
||||
|
||||
Else \var{tz} must be an instance of a class \class{tzinfo} subclass,
|
||||
and the current date and time are translated to \var{tz}'s time
|
||||
zone. In this case the result is equivalent to
|
||||
\code{\var{tz}.fromutc(datetime.utcnow().replace(tzinfo=\var{tz})}.
|
||||
See also \method{today()}, \method{utcnow()}.
|
||||
\end{methoddesc}
|
||||
|
||||
\begin{methoddesc}{utcnow}{}
|
||||
Return the current UTC datetime, with \member{tzinfo} \code{None}.
|
||||
This is like \method{now()}, but
|
||||
returns the current UTC date and time.
|
||||
Return the current UTC date and time, with \member{tzinfo} \code{None}.
|
||||
This is like \method{now()}, but returns the current UTC date and time,
|
||||
as a naive \class{datetime} object.
|
||||
See also \method{now()}.
|
||||
\end{methoddesc}
|
||||
|
||||
|
|
|
@ -2228,7 +2228,7 @@ class TestDateTimeTZ(TestDateTime, TZInfoBase):
|
|||
# Try with and without naming the keyword.
|
||||
off42 = FixedOffset(42, "42")
|
||||
another = meth(off42)
|
||||
again = meth(tzinfo=off42)
|
||||
again = meth(tz=off42)
|
||||
self.failUnless(another.tzinfo is again.tzinfo)
|
||||
self.assertEqual(another.utcoffset(), timedelta(minutes=42))
|
||||
# Bad argument with and w/o naming the keyword.
|
||||
|
@ -2239,6 +2239,24 @@ class TestDateTimeTZ(TestDateTime, TZInfoBase):
|
|||
# Too many args.
|
||||
self.assertRaises(TypeError, meth, off42, off42)
|
||||
|
||||
# We don't know which time zone we're in, and don't have a tzinfo
|
||||
# class to represent it, so seeing whether a tz argument actually
|
||||
# does a conversion is tricky.
|
||||
weirdtz = FixedOffset(timedelta(hours=15, minutes=58), "weirdtz", 0)
|
||||
utc = FixedOffset(0, "utc", 0)
|
||||
for dummy in range(3):
|
||||
now = datetime.now(weirdtz)
|
||||
self.failUnless(now.tzinfo is weirdtz)
|
||||
utcnow = datetime.utcnow().replace(tzinfo=utc)
|
||||
now2 = utcnow.astimezone(weirdtz)
|
||||
if abs(now - now2) < timedelta(seconds=30):
|
||||
break
|
||||
# Else the code is broken, or more than 30 seconds passed between
|
||||
# calls; assuming the latter, just try again.
|
||||
else:
|
||||
# Three strikes and we're out.
|
||||
self.fail("utcnow(), now(tz), or astimezone() may be broken")
|
||||
|
||||
def test_tzinfo_fromtimestamp(self):
|
||||
import time
|
||||
meth = self.theclass.fromtimestamp
|
||||
|
@ -2448,7 +2466,7 @@ class TestDateTimeTZ(TestDateTime, TZInfoBase):
|
|||
f44m = FixedOffset(44, "44")
|
||||
fm5h = FixedOffset(-timedelta(hours=5), "m300")
|
||||
|
||||
dt = self.theclass.now(tzinfo=f44m)
|
||||
dt = self.theclass.now(tz=f44m)
|
||||
self.failUnless(dt.tzinfo is f44m)
|
||||
# Replacing with degenerate tzinfo raises an exception.
|
||||
self.assertRaises(ValueError, dt.astimezone, fnone)
|
||||
|
|
11
Misc/NEWS
11
Misc/NEWS
|
@ -82,6 +82,17 @@ Extension modules
|
|||
creativity of political time zone fiddling appears unbounded -- fromutc()
|
||||
allows the highly motivated to emulate any scheme expressible in Python.
|
||||
|
||||
datetime.now(): The optional tzinfo argument was undocumented (that's
|
||||
repaired), and its name was changed to tz ("tzinfo" is overloaded enough
|
||||
already). With a tz argument, now(tz) used to return the local date
|
||||
and time, and attach tz to it, without any conversion of date and time
|
||||
members. This was less than useful. Now now(tz) returns the current
|
||||
date and time as local time in tz's time zone, akin to
|
||||
tz.fromutc(datetime.utcnow().replace(tzinfo=utc))
|
||||
where "utc" is an instance of a tzinfo subclass modeling UTC. Without
|
||||
a tz argument, now() continues to return the current local date and time,
|
||||
as a naive datetime object.
|
||||
|
||||
The constructors building a datetime from a timestamp could raise
|
||||
ValueError if the platform C localtime()/gmtime() inserted "leap
|
||||
seconds". Leap seconds are ignored now. On such platforms, it's
|
||||
|
|
|
@ -3666,15 +3666,25 @@ datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
|
|||
static PyObject *
|
||||
datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
|
||||
{
|
||||
PyObject *self = NULL;
|
||||
PyObject *self;
|
||||
PyObject *tzinfo = Py_None;
|
||||
static char *keywords[] = {"tzinfo", NULL};
|
||||
static char *keywords[] = {"tz", NULL};
|
||||
|
||||
if (PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
|
||||
&tzinfo)) {
|
||||
if (check_tzinfo_subclass(tzinfo) < 0)
|
||||
return NULL;
|
||||
self = datetime_best_possible(cls, localtime, tzinfo);
|
||||
if (! PyArg_ParseTupleAndKeywords(args, kw, "|O:now", keywords,
|
||||
&tzinfo))
|
||||
return NULL;
|
||||
if (check_tzinfo_subclass(tzinfo) < 0)
|
||||
return NULL;
|
||||
|
||||
self = datetime_best_possible(cls,
|
||||
tzinfo == Py_None ? localtime : gmtime,
|
||||
tzinfo);
|
||||
if (self != NULL && tzinfo != Py_None) {
|
||||
/* Convert UTC to tzinfo's zone. */
|
||||
PyObject *temp = self;
|
||||
self = PyObject_CallMethod(tzinfo, "fromutc",
|
||||
"O", self);
|
||||
Py_DECREF(temp);
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue