[Python-checkins] python/nondist/sandbox/datetime datetime.py,1.82,1.83 doc.txt,1.29,1.30 obj_datetime.c,1.38,1.39
tim_one@users.sourceforge.net
tim_one@users.sourceforge.net
Sun, 08 Dec 2002 11:02:33 -0800
Update of /cvsroot/python/python/nondist/sandbox/datetime
In directory sc8-pr-cvs1:/tmp/cvs-serv10604
Modified Files:
datetime.py doc.txt obj_datetime.c
Log Message:
Use gettimeofday() for datetime.now() and datetime.utcnow(), on platforms
that have it. NEEDS TESTING! Windows doesn't have this function, so I
haven't even compiled the new code. Somebody please try this on Linux.
Index: datetime.py
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/datetime.py,v
retrieving revision 1.82
retrieving revision 1.83
diff -C2 -d -r1.82 -r1.83
*** datetime.py 7 Dec 2002 21:06:38 -0000 1.82
--- datetime.py 8 Dec 2002 19:02:29 -0000 1.83
***************
*** 1112,1115 ****
--- 1112,1120 ----
fromtimestamp = classmethod(fromtimestamp)
+ # XXX This is supposed to do better than we *can* do by using time.time(),
+ # XXX if the platform supports a more accurate way. The C implementation
+ # XXX uses gettimeofday on platforms that have it, but that isn't
+ # XXX available from Python. So now() may return different results
+ # XXX across the implementations.
def now(cls):
"Construct a datetime from time.time()."
Index: doc.txt
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/doc.txt,v
retrieving revision 1.29
retrieving revision 1.30
diff -C2 -d -r1.29 -r1.30
*** doc.txt 7 Dec 2002 21:06:38 -0000 1.29
--- doc.txt 8 Dec 2002 19:02:30 -0000 1.30
***************
*** 362,367 ****
Return the current local datetime. This is like today(), but, if
possible, supplies more precision than can be gotten from going
! through a time.time() timestamp.
! XXX It currently doesn't. To the contrary, it's currently worse.
See also today(), utcnow().
--- 362,367 ----
Return the current local datetime. This is like today(), but, if
possible, supplies more precision than can be gotten from going
! through a time.time() timestamp (for example, this may be possible
! on platforms that supply the C gettimeofday() function).
See also today(), utcnow().
Index: obj_datetime.c
===================================================================
RCS file: /cvsroot/python/python/nondist/sandbox/datetime/obj_datetime.c,v
retrieving revision 1.38
retrieving revision 1.39
diff -C2 -d -r1.38 -r1.39
*** obj_datetime.c 7 Dec 2002 22:29:45 -0000 1.38
--- obj_datetime.c 8 Dec 2002 19:02:31 -0000 1.39
***************
*** 104,113 ****
typedef struct tm *(*TM_FUNC)(const time_t *timer);
static PyObject *
! datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp)
{
struct tm *tm;
- time_t timet = (time_t)timestamp;
- long us = (long)((timestamp - (double)timet) * 1e6);
PyObject *result = NULL;
--- 104,115 ----
typedef struct tm *(*TM_FUNC)(const time_t *timer);
+ /* Internal helper.
+ * Build datetime from a time_t and a distinct count of microseconds.
+ * Pass localtime or gmtime for f, to control the interpretation of timet.
+ */
static PyObject *
! datetime_from_timet_and_us(PyObject *cls, TM_FUNC f, time_t timet, long us)
{
struct tm *tm;
PyObject *result = NULL;
***************
*** 129,132 ****
--- 131,195 ----
}
+ /* Internal helper.
+ * Build datetime from a Python timestamp. Pass localtime or gmtime for f,
+ * to control the interpretation of the timestamp. Since a double doesn't
+ * have enough bits to cover a datetime's full range of precision, it's
+ * better to call datetime_from_timet_and_us provided you have a way
+ * to get that much precision (e.g., C time() isn't good enough).
+ */
+ static PyObject *
+ datetime_from_timestamp(PyObject *cls, TM_FUNC f, double timestamp)
+ {
+ time_t timet = (time_t)timestamp;
+ long us = (long)((timestamp - (double)timet) * 1e6);
+
+ return datetime_from_timet_and_us(cls, f, timet, us);
+ }
+
+ /* Internal helper.
+ * Build most accurate possible datetime for current time. Pass localtime or
+ * gmtime for f as appropriate.
+ */
+ static PyObject *
+ datetime_best_possible(PyObject *cls, TM_FUNC f)
+ {
+ #ifdef HAVE_GETTIMEOFDAY
+ struct timeval t;
+
+ #ifdef GETTIMEOFDAY_NO_TZ
+ gettimeofday(&t);
+ #else
+ gettimeofday(&t, (struct timezone *)NULL);
+ #endif
+ return datetime_from_timet_and_us(cls, f, t.tv_sec, t.tv_usec);
+
+ #else /* ! HAVE_GETTIMEOFDAY */
+ /* No flavor of gettimeofday exists on this platform. Python's
+ * time.time() does a lot of other platform tricks to get the
+ * best time it can on the platform, and we're not going to do
+ * better than that (if we could, the better code would belong
+ * in time.time()!) We're limited by the precision of a double,
+ * though.
+ */
+ PyObject *time_time; /* time.time() */
+ double dtime;
+ PyObject *time = PyImport_ImportModule("time");
+
+ if (time == NULL)
+ return NULL;
+
+ time_time = PyObject_CallMethod(time, "time", "()");
+ Py_DECREF(time);
+ if (time_time == NULL)
+ return NULL;
+
+ dtime = PyFloat_AsDouble(time_time);
+ Py_DECREF(time_time);
+ if (dtime == -1.0 && PyErr_Occurred())
+ return NULL;
+ return datetime_from_timestamp(cls, f, dtime);
+ #endif /* ! HAVE_GETTIMEOFDAY */
+ }
+
/* Return new local datetime from timestamp (Python timestamp -- a double). */
static PyObject *
***************
*** 155,199 ****
}
static PyObject *
datetime_now(PyObject *self, PyObject *cls)
{
! /* XXX MAJOR: This needs to get some notion of current time
! * XXX to better than 1-second resolution. Doing this in a x-
! * XXX platform way is mondo painful. Maybe floattime() from
! * XXX timemodule.c is good enough? We're running out of bits
! * XXX in a typical time_t, though, and gettimeofday() should do
! * XXX better than floattime() -- but gettimeofday isn't portable.
! */
! #if 0
! /* XXX need to create the instance by calling cls(y,mon,d,h,min,s,u) */
! struct timeval t;
! struct tm *tm;
! time_t timet;
!
! #ifdef GETTIMEOFDAY_NO_TZ
! gettimeofday(&t);
! #else /* !GETTIMEOFDAY_NO_TZ */
! gettimeofday(&t, (struct timezone *)NULL);
! #endif /* !GETTIMEOFDAY_NO_TZ */
! timet = t.tv_sec;
! tm = localtime(&timet);
!
! return PyObject_CallFunction(cls, "iiiiiil",
! tm->tm_year + 1900, tm->tm_mon + 1,
! tm->tm_mday, tm->tm_hour, tm->tm_min,
! tm->tm_sec, t.tv_usec);
! #else
! /* XXX need to create the instance by calling cls(y,mon,d,h,min,s,u) */
! struct tm *tm;
! time_t timet;
!
! time(&timet);
! tm = localtime(&timet);
! return PyObject_CallFunction(cls, "iiiiii",
! tm->tm_year + 1900, tm->tm_mon + 1,
! tm->tm_mday, tm->tm_hour, tm->tm_min,
! tm->tm_sec);
! #endif
}
--- 218,237 ----
}
+ /* Return best possible local time -- this isn't constrained by the
+ * precision of a timestamp.
+ */
static PyObject *
datetime_now(PyObject *self, PyObject *cls)
{
! return datetime_best_possible(cls, localtime);
! }
! /* Return best possible UTC time -- this isn't constrained by the
! * precision of a timestamp.
! */
! static PyObject *
! datetime_utcnow(PyObject *self, PyObject *cls)
! {
! return datetime_best_possible(cls, gmtime);
}
***************
*** 226,247 ****
TIME_GET_MICROSECOND(time));
return result;
- }
-
- static PyObject *
- datetime_utcnow(PyObject *self, PyObject *cls)
- {
- /* XXX Like datetime_now, this would like to do better than
- * XXX 1-second resolution.
- */
- struct tm *tm;
- time_t timet;
-
- time(&timet);
- tm = gmtime(&timet);
-
- return PyObject_CallFunction(cls, "iiiiii",
- tm->tm_year + 1900, tm->tm_mon + 1,
- tm->tm_mday, tm->tm_hour, tm->tm_min,
- tm->tm_sec);
}
--- 264,267 ----