summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/pytime.h12
-rw-r--r--Modules/_datetimemodule.c9
-rw-r--r--Python/pytime.c79
3 files changed, 77 insertions, 23 deletions
diff --git a/Include/pytime.h b/Include/pytime.h
index 5de756a..98612e1 100644
--- a/Include/pytime.h
+++ b/Include/pytime.h
@@ -120,6 +120,18 @@ PyAPI_FUNC(int) _PyTime_AsTimeval_noraise(_PyTime_t t,
struct timeval *tv,
_PyTime_round_t round);
+/* Convert a timestamp to a number of seconds (secs) and microseconds (us).
+ us is always positive. This function is similar to _PyTime_AsTimeval()
+ except that secs is always a time_t type, whereas the timeval structure
+ uses a C long for tv_sec on Windows.
+ Raise an exception and return -1 if the conversion overflowed,
+ return 0 on success. */
+PyAPI_FUNC(int) _PyTime_AsTimevalTime_t(
+ _PyTime_t t,
+ time_t *secs,
+ int *us,
+ _PyTime_round_t round);
+
#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
/* Convert a timestamp to a timespec structure (nanosecond resolution).
tv_nsec is always positive.
diff --git a/Modules/_datetimemodule.c b/Modules/_datetimemodule.c
index bbc51c6..5289222 100644
--- a/Modules/_datetimemodule.c
+++ b/Modules/_datetimemodule.c
@@ -4117,13 +4117,14 @@ static PyObject *
datetime_best_possible(PyObject *cls, TM_FUNC f, PyObject *tzinfo)
{
_PyTime_t ts = _PyTime_GetSystemClock();
- struct timeval tv;
+ time_t secs;
+ int us;
- if (_PyTime_AsTimeval(ts, &tv, _PyTime_ROUND_FLOOR) < 0)
+ if (_PyTime_AsTimevalTime_t(ts, &secs, &us, _PyTime_ROUND_FLOOR) < 0)
return NULL;
- assert(0 <= tv.tv_usec && tv.tv_usec <= 999999);
+ assert(0 <= us && us <= 999999);
- return datetime_from_timet_and_us(cls, f, tv.tv_sec, tv.tv_usec, tzinfo);
+ return datetime_from_timet_and_us(cls, f, secs, us, tzinfo);
}
/*[clinic input]
diff --git a/Python/pytime.c b/Python/pytime.c
index 9d0b0fa..9889a3b 100644
--- a/Python/pytime.c
+++ b/Python/pytime.c
@@ -417,54 +417,95 @@ _PyTime_AsMicroseconds(_PyTime_t t, _PyTime_round_t round)
}
static int
-_PyTime_AsTimeval_impl(_PyTime_t t, struct timeval *tv, _PyTime_round_t round,
- int raise)
+_PyTime_AsTimeval_impl(_PyTime_t t, _PyTime_t *p_secs, int *p_us,
+ _PyTime_round_t round)
{
_PyTime_t secs, ns;
- int res = 0;
int usec;
+ int res = 0;
secs = t / SEC_TO_NS;
ns = t % SEC_TO_NS;
-#ifdef MS_WINDOWS
- tv->tv_sec = (long)secs;
-#else
- tv->tv_sec = secs;
-#endif
- if ((_PyTime_t)tv->tv_sec != secs)
- res = -1;
-
usec = (int)_PyTime_Divide(ns, US_TO_NS, round);
if (usec < 0) {
usec += SEC_TO_US;
- tv->tv_sec -= 1;
+ if (secs != _PyTime_MIN)
+ secs -= 1;
+ else
+ res = -1;
}
else if (usec >= SEC_TO_US) {
usec -= SEC_TO_US;
- tv->tv_sec += 1;
+ if (secs != _PyTime_MAX)
+ secs += 1;
+ else
+ res = -1;
}
-
assert(0 <= usec && usec < SEC_TO_US);
- tv->tv_usec = usec;
- if (res && raise)
- error_time_t_overflow();
+ *p_secs = secs;
+ *p_us = usec;
+
return res;
}
+static int
+_PyTime_AsTimevalStruct_impl(_PyTime_t t, struct timeval *tv,
+ _PyTime_round_t round, int raise)
+{
+ _PyTime_t secs;
+ int us;
+ int res;
+
+ res = _PyTime_AsTimeval_impl(t, &secs, &us, round);
+
+#ifdef MS_WINDOWS
+ tv->tv_sec = (long)secs;
+#else
+ tv->tv_sec = secs;
+#endif
+ tv->tv_usec = us;
+
+ if (res < 0 || (_PyTime_t)tv->tv_sec != secs) {
+ if (raise)
+ error_time_t_overflow();
+ return -1;
+ }
+ return 0;
+}
+
int
_PyTime_AsTimeval(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
{
- return _PyTime_AsTimeval_impl(t, tv, round, 1);
+ return _PyTime_AsTimevalStruct_impl(t, tv, round, 1);
}
int
_PyTime_AsTimeval_noraise(_PyTime_t t, struct timeval *tv, _PyTime_round_t round)
{
- return _PyTime_AsTimeval_impl(t, tv, round, 0);
+ return _PyTime_AsTimevalStruct_impl(t, tv, round, 0);
}
+int
+_PyTime_AsTimevalTime_t(_PyTime_t t, time_t *p_secs, int *us,
+ _PyTime_round_t round)
+{
+ _PyTime_t secs;
+ int res;
+
+ res = _PyTime_AsTimeval_impl(t, &secs, us, round);
+
+ *p_secs = secs;
+
+ if (res < 0 || (_PyTime_t)*p_secs != secs) {
+ error_time_t_overflow();
+ return -1;
+ }
+ return 0;
+}
+
+
#if defined(HAVE_CLOCK_GETTIME) || defined(HAVE_KQUEUE)
int
_PyTime_AsTimespec(_PyTime_t t, struct timespec *ts)