summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/lib/libdatetime.tex22
-rw-r--r--Lib/test/test_datetime.py22
-rw-r--r--Misc/NEWS11
-rw-r--r--Modules/datetimemodule.c24
4 files changed, 62 insertions, 17 deletions
diff --git a/Doc/lib/libdatetime.tex b/Doc/lib/libdatetime.tex
index 9133f1e..b890024 100644
--- a/Doc/lib/libdatetime.tex
+++ b/Doc/lib/libdatetime.tex
@@ -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}
diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py
index 8878386..7d503e0 100644
--- a/Lib/test/test_datetime.py
+++ b/Lib/test/test_datetime.py
@@ -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)
diff --git a/Misc/NEWS b/Misc/NEWS
index 780bf5a..39ebd93 100644
--- a/Misc/NEWS
+++ b/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
diff --git a/Modules/datetimemodule.c b/Modules/datetimemodule.c
index f615f68..d81d563 100644
--- a/Modules/datetimemodule.c
+++ b/Modules/datetimemodule.c
@@ -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;
}