summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Doc/lib/libdatetime.tex29
-rw-r--r--Lib/test/test_datetime.py16
-rw-r--r--Misc/NEWS4
-rw-r--r--Modules/datetimemodule.c32
4 files changed, 58 insertions, 23 deletions
diff --git a/Doc/lib/libdatetime.tex b/Doc/lib/libdatetime.tex
index b890024..058d6d5 100644
--- a/Doc/lib/libdatetime.tex
+++ b/Doc/lib/libdatetime.tex
@@ -534,26 +534,35 @@ Other constructors, all class methods:
\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
+ and the current date and time are converted to \var{tz}'s time
zone. In this case the result is equivalent to
- \code{\var{tz}.fromutc(datetime.utcnow().replace(tzinfo=\var{tz})}.
+ \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 date and time, with \member{tzinfo} \code{None}.
- This is like \method{now()}, but returns the current UTC date and time,
+ 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}
-\begin{methoddesc}{fromtimestamp}{timestamp}
- Return the local \class{datetime} corresponding to the \POSIX{}
- timestamp, such as is returned by \function{time.time()}. This
- may raise \exception{ValueError}, if the timestamp is out of the
- range of values supported by the platform C
- \cfunction{localtime()} function. It's common for this to be
- restricted to years in 1970 through 2038.
+\begin{methoddesc}{fromtimestamp}{timestamp, tz=None}
+ Return the local date and time corresponding to the \POSIX{}
+ timestamp, such as is returned by \function{time.time()}.
+ If optional argument \var{tz} is \code{None} or not specified, the
+ timestamp is converted to the platform's local date and time, and
+ the returned \class{datetime} object is naive.
+
+ Else \var{tz} must be an instance of a class \class{tzinfo} subclass,
+ and the timestamp is converted to \var{tz}'s time zone. In this case
+ the result is equivalent to
+ \code{\var{tz}.fromutc(datetime.utcfromtimestamp(\var{timestamp}).replace(tzinfo=\var{tz}))}.
+
+ \method{fromtimestamp()} may raise \exception{ValueError}, if the
+ timestamp is out of the range of values supported by the platform C
+ \cfunction{localtime()} or \cfunction(gmtime()} functions. It's common
+ for this to be restricted to years in 1970 through 2038.
Note that on non-POSIX systems that include leap seconds in their
notion of a timestamp, leap seconds are ignored by
\method{fromtimestamp()}, and then it's possible to have two timestamps
diff --git a/Lib/test/test_datetime.py b/Lib/test/test_datetime.py
index 7d503e0..0b9597a 100644
--- a/Lib/test/test_datetime.py
+++ b/Lib/test/test_datetime.py
@@ -2266,7 +2266,7 @@ class TestDateTimeTZ(TestDateTime, TZInfoBase):
# Try with and without naming the keyword.
off42 = FixedOffset(42, "42")
another = meth(ts, off42)
- again = meth(ts, tzinfo=off42)
+ again = meth(ts, 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.
@@ -2279,6 +2279,20 @@ class TestDateTimeTZ(TestDateTime, TZInfoBase):
# Too few args.
self.assertRaises(TypeError, meth)
+ # Try to make sure tz= actually does some conversion.
+ timestamp = 1000000000 # 2001-09-09 01:46:40 UTC, give or take
+ utc = FixedOffset(0, "utc", 0)
+ expected = datetime(2001, 9, 9, 1, 46, 40)
+ got = datetime.utcfromtimestamp(timestamp)
+ # We don't support leap seconds, but maybe the platfrom insists
+ # on using them, so don't demand exact equality).
+ self.failUnless(abs(got - expected) < timedelta(minutes=1))
+
+ est = FixedOffset(-5*60, "est", 0)
+ expected -= timedelta(hours=5)
+ got = datetime.fromtimestamp(timestamp, est).replace(tzinfo=None)
+ self.failUnless(abs(got - expected) < timedelta(minutes=1))
+
def test_tzinfo_utcnow(self):
meth = self.theclass.utcnow
# Ensure it doesn't require tzinfo (i.e., that this doesn't blow up).
diff --git a/Misc/NEWS b/Misc/NEWS
index 39ebd93..bfcddd9 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -93,6 +93,10 @@ Extension modules
a tz argument, now() continues to return the current local date and time,
as a naive datetime object.
+ datetime.fromtimestamp(): Like datetime.now() above, this had less than
+ useful behavior when the optional tinzo argument was specified. See
+ also SF bug report <http://www.python.org/sf/660872>.
+
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 d81d563..aeccfda 100644
--- a/Modules/datetimemodule.c
+++ b/Modules/datetimemodule.c
@@ -3682,8 +3682,7 @@ datetime_now(PyObject *cls, PyObject *args, PyObject *kw)
if (self != NULL && tzinfo != Py_None) {
/* Convert UTC to tzinfo's zone. */
PyObject *temp = self;
- self = PyObject_CallMethod(tzinfo, "fromutc",
- "O", self);
+ self = PyObject_CallMethod(tzinfo, "fromutc", "O", self);
Py_DECREF(temp);
}
return self;
@@ -3702,17 +3701,26 @@ datetime_utcnow(PyObject *cls, PyObject *dummy)
static PyObject *
datetime_fromtimestamp(PyObject *cls, PyObject *args, PyObject *kw)
{
- PyObject *self = NULL;
+ PyObject *self;
double timestamp;
PyObject *tzinfo = Py_None;
- static char *keywords[] = {"timestamp", "tzinfo", NULL};
+ static char *keywords[] = {"timestamp", "tz", NULL};
- if (PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
- keywords, &timestamp, &tzinfo)) {
- if (check_tzinfo_subclass(tzinfo) < 0)
- return NULL;
- self = datetime_from_timestamp(cls, localtime, timestamp,
- tzinfo);
+ if (! PyArg_ParseTupleAndKeywords(args, kw, "d|O:fromtimestamp",
+ keywords, &timestamp, &tzinfo))
+ return NULL;
+ if (check_tzinfo_subclass(tzinfo) < 0)
+ return NULL;
+
+ self = datetime_from_timestamp(cls,
+ tzinfo == Py_None ? localtime : gmtime,
+ timestamp,
+ 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;
}
@@ -4404,7 +4412,7 @@ static PyMethodDef datetime_methods[] = {
{"now", (PyCFunction)datetime_now,
METH_KEYWORDS | METH_CLASS,
- PyDoc_STR("[tzinfo] -> new datetime with local day and time.")},
+ PyDoc_STR("[tz] -> new datetime with tz's locl day and time.")},
{"utcnow", (PyCFunction)datetime_utcnow,
METH_NOARGS | METH_CLASS,
@@ -4412,7 +4420,7 @@ static PyMethodDef datetime_methods[] = {
{"fromtimestamp", (PyCFunction)datetime_fromtimestamp,
METH_KEYWORDS | METH_CLASS,
- PyDoc_STR("timestamp[, tzinfo] -> local time from POSIX timestamp.")},
+ PyDoc_STR("timestamp[, tz] -> tz's local time from POSIX timestamp.")},
{"utcfromtimestamp", (PyCFunction)datetime_utcfromtimestamp,
METH_VARARGS | METH_CLASS,