diff options
author | Victor Stinner <victor.stinner@haypocalc.com> | 2012-02-08 22:03:19 (GMT) |
---|---|---|
committer | Victor Stinner <victor.stinner@haypocalc.com> | 2012-02-08 22:03:19 (GMT) |
commit | 4195b5caea0fe1446160e78d69420732ead7e78b (patch) | |
tree | 5c01264aed26942fcb932f9aab73856dd65af684 /Python/pytime.c | |
parent | 72476eae5fe4d7bc4d4c4e30471cd83a501707de (diff) | |
download | cpython-4195b5caea0fe1446160e78d69420732ead7e78b.zip cpython-4195b5caea0fe1446160e78d69420732ead7e78b.tar.gz cpython-4195b5caea0fe1446160e78d69420732ead7e78b.tar.bz2 |
Backout f8409b3d6449: the PEP 410 is not accepted yet
Diffstat (limited to 'Python/pytime.c')
-rw-r--r-- | Python/pytime.c | 343 |
1 files changed, 18 insertions, 325 deletions
diff --git a/Python/pytime.c b/Python/pytime.c index 8679bcc..bec1c71 100644 --- a/Python/pytime.c +++ b/Python/pytime.c @@ -18,36 +18,24 @@ extern int ftime(struct timeb *); #endif -#define MICROSECONDS 1000000 - void -_PyTime_get(_PyTime_t *ts) +_PyTime_gettimeofday(_PyTime_timeval *tp) { #ifdef MS_WINDOWS FILETIME system_time; ULARGE_INTEGER large; - ULONGLONG value; + ULONGLONG microseconds; GetSystemTimeAsFileTime(&system_time); large.u.LowPart = system_time.dwLowDateTime; large.u.HighPart = system_time.dwHighDateTime; - /* 116,444,736,000,000,000: number of 100 ns between + /* 11,644,473,600,000,000: number of microseconds between the 1st january 1601 and the 1st january 1970 (369 years + 89 leap days). */ - value = large.QuadPart - 116444736000000000; - ts->seconds = 0; - ts->numerator = value; - ts->denominator = (_PyTime_fraction_t)10000000; + microseconds = large.QuadPart / 10 - 11644473600000000; + tp->tv_sec = microseconds / 1000000; + tp->tv_usec = microseconds % 1000000; #else - -#ifdef HAVE_GETTIMEOFDAY - struct timeval tv; - int err; -#endif -#if defined(HAVE_FTIME) - struct timeb t; -#endif - /* There are three ways to get the time: (1) gettimeofday() -- resolution in microseconds (2) ftime() -- resolution in milliseconds @@ -59,325 +47,30 @@ _PyTime_get(_PyTime_t *ts) #ifdef HAVE_GETTIMEOFDAY #ifdef GETTIMEOFDAY_NO_TZ - err = gettimeofday(&tv); + if (gettimeofday(tp) == 0) + return; #else /* !GETTIMEOFDAY_NO_TZ */ - err = gettimeofday(&tv, (struct timezone *)NULL); -#endif /* !GETTIMEOFDAY_NO_TZ */ - if (err == 0) - { - ts->seconds = tv.tv_sec; - ts->numerator = tv.tv_usec; - ts->denominator = MICROSECONDS; + if (gettimeofday(tp, (struct timezone *)NULL) == 0) return; - } +#endif /* !GETTIMEOFDAY_NO_TZ */ #endif /* !HAVE_GETTIMEOFDAY */ #if defined(HAVE_FTIME) - ftime(&t); - ts->seconds = t.time; - ts->numerator = t.millitm; - ts->denominator = 1000; + { + struct timeb t; + ftime(&t); + tp->tv_sec = t.time; + tp->tv_usec = t.millitm * 1000; + } #else /* !HAVE_FTIME */ - ts->seconds = time(NULL); - ts->numerator = 0; - ts->denominator = 1; + tp->tv_sec = time(NULL); + tp->tv_usec = 0; #endif /* !HAVE_FTIME */ #endif /* MS_WINDOWS */ } void -_PyTime_gettimeofday(_PyTime_timeval *tv) -{ - _PyTime_t ts; - _PyTime_fraction_t k; - time_t sec; - - _PyTime_get(&ts); - tv->tv_sec = ts.seconds; - if (ts.numerator) { - if (ts.numerator > ts.denominator) { - sec = Py_SAFE_DOWNCAST(ts.numerator / ts.denominator, - _PyTime_fraction_t, time_t); - /* ignore integer overflow because _PyTime_gettimeofday() has - no return value */ - tv->tv_sec += sec; - ts.numerator = ts.numerator % ts.denominator; - } - if (MICROSECONDS >= ts.denominator) { - k = (_PyTime_fraction_t)MICROSECONDS / ts.denominator; - tv->tv_usec = (long)(ts.numerator * k); - } - else { - k = ts.denominator / (_PyTime_fraction_t)MICROSECONDS; - tv->tv_usec = (long)(ts.numerator / k); - } - } - else { - tv->tv_usec = 0; - } -} - -static PyObject* -_PyLong_FromTime_t(time_t value) -{ -#if SIZEOF_TIME_T <= SIZEOF_LONG - return PyLong_FromLong(value); -#else - assert(sizeof(time_t) <= sizeof(PY_LONG_LONG)); - return PyLong_FromLongLong(value); -#endif -} - -#if defined(HAVE_LONG_LONG) -# define _PyLong_FromTimeFraction_t PyLong_FromLongLong -#else -# define _PyLong_FromTimeFraction_t PyLong_FromSize_t -#endif - -/* Convert a timestamp to a PyFloat object */ -static PyObject* -_PyTime_AsFloat(_PyTime_t *ts) -{ - double d; - d = (double)ts->seconds; - d += (double)ts->numerator / (double)ts->denominator; - return PyFloat_FromDouble(d); -} - -/* Convert a timestamp to a PyLong object */ -static PyObject* -_PyTime_AsLong(_PyTime_t *ts) -{ - PyObject *a, *b, *c; - - a = _PyLong_FromTime_t(ts->seconds); - if (a == NULL) - return NULL; - b = _PyLong_FromTimeFraction_t(ts->numerator / ts->denominator); - if (b == NULL) - { - Py_DECREF(a); - return NULL; - } - c = PyNumber_Add(a, b); - Py_DECREF(a); - Py_DECREF(b); - return c; -} - -/* Convert a timestamp to a decimal.Decimal object */ -static PyObject* -_PyTime_AsDecimal(_PyTime_t *ts) -{ - static PyObject* module = NULL; - static PyObject* decimal = NULL; - static PyObject* exponent_context = NULL; - static PyObject* context = NULL; - /* exponent cache, dictionary of: - int (denominator) => Decimal (1/denominator) */ - static PyObject* exponent_cache = NULL; - PyObject *t = NULL; - PyObject *key, *exponent, *quantized; - _Py_IDENTIFIER(quantize); - _Py_IDENTIFIER(__truediv__); - - if (!module) { - module = PyImport_ImportModuleNoBlock("decimal"); - if (module == NULL) - return NULL; - } - - if (!decimal) { - decimal = PyObject_GetAttrString(module, "Decimal"); - if (decimal == NULL) - return NULL; - } - - if (context == NULL) - { - /* Use 12 decimal digits to store 10,000 years in seconds + 9 - decimal digits for the floating part in nanoseconds + 1 decimal - digit to round correctly. - - context = decimal.Context(22, rounding=decimal.ROUND_HALF_EVEN) - exponent_context = decimal.Context(1, rounding=decimal.ROUND_HALF_EVEN) - */ - PyObject *context_class, *rounding; - context_class = PyObject_GetAttrString(module, "Context"); - if (context_class == NULL) - return NULL; - rounding = PyObject_GetAttrString(module, "ROUND_HALF_EVEN"); - if (rounding == NULL) - { - Py_DECREF(context_class); - return NULL; - } - context = PyObject_CallFunction(context_class, "iO", 22, rounding); - if (context == NULL) - { - Py_DECREF(context_class); - Py_DECREF(rounding); - return NULL; - } - - exponent_context = PyObject_CallFunction(context_class, "iO", 1, rounding); - Py_DECREF(context_class); - Py_DECREF(rounding); - if (exponent_context == NULL) - { - Py_CLEAR(context); - return NULL; - } - } - - /* t = decimal.Decimal(value) */ - if (ts->seconds) { - PyObject *f = _PyLong_FromTime_t(ts->seconds); - t = PyObject_CallFunction(decimal, "O", f); - Py_CLEAR(f); - } - else { - t = PyObject_CallFunction(decimal, "iO", 0, context); - } - if (t == NULL) - return NULL; - - if (ts->numerator) - { - /* t += decimal.Decimal(numerator, ctx) / decimal.Decimal(denominator, ctx) */ - PyObject *a, *b, *c, *d, *x; - - x = _PyLong_FromTimeFraction_t(ts->numerator); - if (x == NULL) - goto error; - a = PyObject_CallFunction(decimal, "OO", x, context); - Py_CLEAR(x); - if (a == NULL) - goto error; - - x = _PyLong_FromTimeFraction_t(ts->denominator); - if (x == NULL) - { - Py_DECREF(a); - goto error; - } - b = PyObject_CallFunction(decimal, "OO", x, context); - Py_CLEAR(x); - if (b == NULL) - { - Py_DECREF(a); - goto error; - } - - c = _PyObject_CallMethodId(a, &PyId___truediv__, "OO", - b, context); - Py_DECREF(a); - Py_DECREF(b); - if (c == NULL) - goto error; - - d = PyNumber_Add(t, c); - Py_DECREF(c); - if (d == NULL) - goto error; - Py_DECREF(t); - t = d; - } - - if (exponent_cache == NULL) { - exponent_cache = PyDict_New(); - if (exponent_cache == NULL) - goto error; - } - - key = _PyLong_FromTimeFraction_t(ts->denominator); - if (key == NULL) - goto error; - exponent = PyDict_GetItem(exponent_cache, key); - if (exponent == NULL) { - /* exponent = decimal.Decimal(1) / decimal.Decimal(resolution) */ - PyObject *one, *denominator; - - one = PyObject_CallFunction(decimal, "i", 1); - if (one == NULL) { - Py_DECREF(key); - goto error; - } - - denominator = PyObject_CallFunction(decimal, "O", key); - if (denominator == NULL) { - Py_DECREF(key); - Py_DECREF(one); - goto error; - } - - exponent = _PyObject_CallMethodId(one, &PyId___truediv__, "OO", - denominator, exponent_context); - Py_DECREF(one); - Py_DECREF(denominator); - if (exponent == NULL) { - Py_DECREF(key); - goto error; - } - - if (PyDict_SetItem(exponent_cache, key, exponent) < 0) { - Py_DECREF(key); - Py_DECREF(exponent); - goto error; - } - Py_DECREF(key); - } - - /* t = t.quantize(exponent, None, context) */ - quantized = _PyObject_CallMethodId(t, &PyId_quantize, "OOO", - exponent, Py_None, context); - if (quantized == NULL) - goto error; - Py_DECREF(t); - t = quantized; - - return t; - -error: - Py_XDECREF(t); - return NULL; -} - -PyObject* -_PyTime_Convert(_PyTime_t *ts, PyObject *format) -{ - assert(ts->denominator != 0); - - if (format == NULL || (PyTypeObject *)format == &PyFloat_Type) - return _PyTime_AsFloat(ts); - if ((PyTypeObject *)format == &PyLong_Type) - return _PyTime_AsLong(ts); - - if (PyType_Check(format)) - { - PyObject *module, *name; - _Py_IDENTIFIER(__name__); - _Py_IDENTIFIER(__module__); - - module = _PyObject_GetAttrId(format, &PyId___module__); - name = _PyObject_GetAttrId(format, &PyId___name__); - if (module != NULL && PyUnicode_Check(module) - && name != NULL && PyUnicode_Check(name)) - { - if (PyUnicode_CompareWithASCIIString(module, "decimal") == 0 - && PyUnicode_CompareWithASCIIString(name, "Decimal") == 0) - return _PyTime_AsDecimal(ts); - } - else - PyErr_Clear(); - } - - PyErr_Format(PyExc_ValueError, "Unknown timestamp format: %R", format); - return NULL; -} - -void _PyTime_Init() { /* Do nothing. Needed to force linking. */ |