blob: 8679bcc2cdeb0ab8dc7f5a2c2e1ab60a0e52fef9 [file] [log] [blame]
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00001#include "Python.h"
Victor Stinner09225b72012-02-07 23:41:01 +01002#ifdef MS_WINDOWS
3#include <windows.h>
4#endif
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00005
Victor Stinner09225b72012-02-07 23:41:01 +01006#if defined(__APPLE__) && defined(HAVE_GETTIMEOFDAY) && defined(HAVE_FTIME)
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +00007 /*
8 * _PyTime_gettimeofday falls back to ftime when getttimeofday fails because the latter
9 * might fail on some platforms. This fallback is unwanted on MacOSX because
10 * that makes it impossible to use a binary build on OSX 10.4 on earlier
11 * releases of the OS. Therefore claim we don't support ftime.
12 */
13# undef HAVE_FTIME
14#endif
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000015
Victor Stinner09225b72012-02-07 23:41:01 +010016#if defined(HAVE_FTIME) && !defined(MS_WINDOWS)
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000017#include <sys/timeb.h>
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000018extern int ftime(struct timeb *);
Victor Stinner09225b72012-02-07 23:41:01 +010019#endif
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000020
Victor Stinnerccd57152012-02-08 14:31:50 +010021#define MICROSECONDS 1000000
22
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000023void
Victor Stinnerccd57152012-02-08 14:31:50 +010024_PyTime_get(_PyTime_t *ts)
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000025{
Victor Stinner09225b72012-02-07 23:41:01 +010026#ifdef MS_WINDOWS
27 FILETIME system_time;
28 ULARGE_INTEGER large;
Victor Stinnerccd57152012-02-08 14:31:50 +010029 ULONGLONG value;
Victor Stinner09225b72012-02-07 23:41:01 +010030
31 GetSystemTimeAsFileTime(&system_time);
32 large.u.LowPart = system_time.dwLowDateTime;
33 large.u.HighPart = system_time.dwHighDateTime;
Victor Stinnerccd57152012-02-08 14:31:50 +010034 /* 116,444,736,000,000,000: number of 100 ns between
Victor Stinner09225b72012-02-07 23:41:01 +010035 the 1st january 1601 and the 1st january 1970 (369 years + 89 leap
36 days). */
Victor Stinnerccd57152012-02-08 14:31:50 +010037 value = large.QuadPart - 116444736000000000;
38 ts->seconds = 0;
39 ts->numerator = value;
40 ts->denominator = (_PyTime_fraction_t)10000000;
Victor Stinner09225b72012-02-07 23:41:01 +010041#else
Victor Stinnerccd57152012-02-08 14:31:50 +010042
43#ifdef HAVE_GETTIMEOFDAY
44 struct timeval tv;
45 int err;
46#endif
47#if defined(HAVE_FTIME)
48 struct timeb t;
49#endif
50
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000051 /* There are three ways to get the time:
52 (1) gettimeofday() -- resolution in microseconds
53 (2) ftime() -- resolution in milliseconds
54 (3) time() -- resolution in seconds
55 In all cases the return value in a timeval struct.
56 Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
57 fail, so we fall back on ftime() or time().
58 Note: clock resolution does not imply clock accuracy! */
Victor Stinner09225b72012-02-07 23:41:01 +010059
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000060#ifdef HAVE_GETTIMEOFDAY
61#ifdef GETTIMEOFDAY_NO_TZ
Victor Stinnerccd57152012-02-08 14:31:50 +010062 err = gettimeofday(&tv);
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000063#else /* !GETTIMEOFDAY_NO_TZ */
Victor Stinnerccd57152012-02-08 14:31:50 +010064 err = gettimeofday(&tv, (struct timezone *)NULL);
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000065#endif /* !GETTIMEOFDAY_NO_TZ */
Victor Stinnerccd57152012-02-08 14:31:50 +010066 if (err == 0)
67 {
68 ts->seconds = tv.tv_sec;
69 ts->numerator = tv.tv_usec;
70 ts->denominator = MICROSECONDS;
71 return;
72 }
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000073#endif /* !HAVE_GETTIMEOFDAY */
Victor Stinner09225b72012-02-07 23:41:01 +010074
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000075#if defined(HAVE_FTIME)
Victor Stinnerccd57152012-02-08 14:31:50 +010076 ftime(&t);
77 ts->seconds = t.time;
78 ts->numerator = t.millitm;
79 ts->denominator = 1000;
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000080#else /* !HAVE_FTIME */
Victor Stinnerccd57152012-02-08 14:31:50 +010081 ts->seconds = time(NULL);
82 ts->numerator = 0;
83 ts->denominator = 1;
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000084#endif /* !HAVE_FTIME */
Victor Stinner09225b72012-02-07 23:41:01 +010085
86#endif /* MS_WINDOWS */
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +000087}
88
89void
Victor Stinnerccd57152012-02-08 14:31:50 +010090_PyTime_gettimeofday(_PyTime_timeval *tv)
91{
92 _PyTime_t ts;
93 _PyTime_fraction_t k;
94 time_t sec;
95
96 _PyTime_get(&ts);
97 tv->tv_sec = ts.seconds;
98 if (ts.numerator) {
99 if (ts.numerator > ts.denominator) {
100 sec = Py_SAFE_DOWNCAST(ts.numerator / ts.denominator,
101 _PyTime_fraction_t, time_t);
102 /* ignore integer overflow because _PyTime_gettimeofday() has
103 no return value */
104 tv->tv_sec += sec;
105 ts.numerator = ts.numerator % ts.denominator;
106 }
107 if (MICROSECONDS >= ts.denominator) {
108 k = (_PyTime_fraction_t)MICROSECONDS / ts.denominator;
109 tv->tv_usec = (long)(ts.numerator * k);
110 }
111 else {
112 k = ts.denominator / (_PyTime_fraction_t)MICROSECONDS;
113 tv->tv_usec = (long)(ts.numerator / k);
114 }
115 }
116 else {
117 tv->tv_usec = 0;
118 }
119}
120
121static PyObject*
122_PyLong_FromTime_t(time_t value)
123{
124#if SIZEOF_TIME_T <= SIZEOF_LONG
125 return PyLong_FromLong(value);
126#else
127 assert(sizeof(time_t) <= sizeof(PY_LONG_LONG));
128 return PyLong_FromLongLong(value);
129#endif
130}
131
132#if defined(HAVE_LONG_LONG)
133# define _PyLong_FromTimeFraction_t PyLong_FromLongLong
134#else
135# define _PyLong_FromTimeFraction_t PyLong_FromSize_t
136#endif
137
138/* Convert a timestamp to a PyFloat object */
139static PyObject*
140_PyTime_AsFloat(_PyTime_t *ts)
141{
142 double d;
143 d = (double)ts->seconds;
144 d += (double)ts->numerator / (double)ts->denominator;
145 return PyFloat_FromDouble(d);
146}
147
148/* Convert a timestamp to a PyLong object */
149static PyObject*
150_PyTime_AsLong(_PyTime_t *ts)
151{
152 PyObject *a, *b, *c;
153
154 a = _PyLong_FromTime_t(ts->seconds);
155 if (a == NULL)
156 return NULL;
157 b = _PyLong_FromTimeFraction_t(ts->numerator / ts->denominator);
158 if (b == NULL)
159 {
160 Py_DECREF(a);
161 return NULL;
162 }
163 c = PyNumber_Add(a, b);
164 Py_DECREF(a);
165 Py_DECREF(b);
166 return c;
167}
168
169/* Convert a timestamp to a decimal.Decimal object */
170static PyObject*
171_PyTime_AsDecimal(_PyTime_t *ts)
172{
173 static PyObject* module = NULL;
174 static PyObject* decimal = NULL;
175 static PyObject* exponent_context = NULL;
176 static PyObject* context = NULL;
177 /* exponent cache, dictionary of:
178 int (denominator) => Decimal (1/denominator) */
179 static PyObject* exponent_cache = NULL;
180 PyObject *t = NULL;
181 PyObject *key, *exponent, *quantized;
182 _Py_IDENTIFIER(quantize);
183 _Py_IDENTIFIER(__truediv__);
184
185 if (!module) {
186 module = PyImport_ImportModuleNoBlock("decimal");
187 if (module == NULL)
188 return NULL;
189 }
190
191 if (!decimal) {
192 decimal = PyObject_GetAttrString(module, "Decimal");
193 if (decimal == NULL)
194 return NULL;
195 }
196
197 if (context == NULL)
198 {
199 /* Use 12 decimal digits to store 10,000 years in seconds + 9
200 decimal digits for the floating part in nanoseconds + 1 decimal
201 digit to round correctly.
202
203 context = decimal.Context(22, rounding=decimal.ROUND_HALF_EVEN)
204 exponent_context = decimal.Context(1, rounding=decimal.ROUND_HALF_EVEN)
205 */
206 PyObject *context_class, *rounding;
207 context_class = PyObject_GetAttrString(module, "Context");
208 if (context_class == NULL)
209 return NULL;
210 rounding = PyObject_GetAttrString(module, "ROUND_HALF_EVEN");
211 if (rounding == NULL)
212 {
213 Py_DECREF(context_class);
214 return NULL;
215 }
216 context = PyObject_CallFunction(context_class, "iO", 22, rounding);
217 if (context == NULL)
218 {
219 Py_DECREF(context_class);
220 Py_DECREF(rounding);
221 return NULL;
222 }
223
224 exponent_context = PyObject_CallFunction(context_class, "iO", 1, rounding);
225 Py_DECREF(context_class);
226 Py_DECREF(rounding);
227 if (exponent_context == NULL)
228 {
229 Py_CLEAR(context);
230 return NULL;
231 }
232 }
233
234 /* t = decimal.Decimal(value) */
235 if (ts->seconds) {
236 PyObject *f = _PyLong_FromTime_t(ts->seconds);
237 t = PyObject_CallFunction(decimal, "O", f);
238 Py_CLEAR(f);
239 }
240 else {
241 t = PyObject_CallFunction(decimal, "iO", 0, context);
242 }
243 if (t == NULL)
244 return NULL;
245
246 if (ts->numerator)
247 {
248 /* t += decimal.Decimal(numerator, ctx) / decimal.Decimal(denominator, ctx) */
249 PyObject *a, *b, *c, *d, *x;
250
251 x = _PyLong_FromTimeFraction_t(ts->numerator);
252 if (x == NULL)
253 goto error;
254 a = PyObject_CallFunction(decimal, "OO", x, context);
255 Py_CLEAR(x);
256 if (a == NULL)
257 goto error;
258
259 x = _PyLong_FromTimeFraction_t(ts->denominator);
260 if (x == NULL)
261 {
262 Py_DECREF(a);
263 goto error;
264 }
265 b = PyObject_CallFunction(decimal, "OO", x, context);
266 Py_CLEAR(x);
267 if (b == NULL)
268 {
269 Py_DECREF(a);
270 goto error;
271 }
272
273 c = _PyObject_CallMethodId(a, &PyId___truediv__, "OO",
274 b, context);
275 Py_DECREF(a);
276 Py_DECREF(b);
277 if (c == NULL)
278 goto error;
279
280 d = PyNumber_Add(t, c);
281 Py_DECREF(c);
282 if (d == NULL)
283 goto error;
284 Py_DECREF(t);
285 t = d;
286 }
287
288 if (exponent_cache == NULL) {
289 exponent_cache = PyDict_New();
290 if (exponent_cache == NULL)
291 goto error;
292 }
293
294 key = _PyLong_FromTimeFraction_t(ts->denominator);
295 if (key == NULL)
296 goto error;
297 exponent = PyDict_GetItem(exponent_cache, key);
298 if (exponent == NULL) {
299 /* exponent = decimal.Decimal(1) / decimal.Decimal(resolution) */
300 PyObject *one, *denominator;
301
302 one = PyObject_CallFunction(decimal, "i", 1);
303 if (one == NULL) {
304 Py_DECREF(key);
305 goto error;
306 }
307
308 denominator = PyObject_CallFunction(decimal, "O", key);
309 if (denominator == NULL) {
310 Py_DECREF(key);
311 Py_DECREF(one);
312 goto error;
313 }
314
315 exponent = _PyObject_CallMethodId(one, &PyId___truediv__, "OO",
316 denominator, exponent_context);
317 Py_DECREF(one);
318 Py_DECREF(denominator);
319 if (exponent == NULL) {
320 Py_DECREF(key);
321 goto error;
322 }
323
324 if (PyDict_SetItem(exponent_cache, key, exponent) < 0) {
325 Py_DECREF(key);
326 Py_DECREF(exponent);
327 goto error;
328 }
329 Py_DECREF(key);
330 }
331
332 /* t = t.quantize(exponent, None, context) */
333 quantized = _PyObject_CallMethodId(t, &PyId_quantize, "OOO",
334 exponent, Py_None, context);
335 if (quantized == NULL)
336 goto error;
337 Py_DECREF(t);
338 t = quantized;
339
340 return t;
341
342error:
343 Py_XDECREF(t);
344 return NULL;
345}
346
347PyObject*
348_PyTime_Convert(_PyTime_t *ts, PyObject *format)
349{
350 assert(ts->denominator != 0);
351
352 if (format == NULL || (PyTypeObject *)format == &PyFloat_Type)
353 return _PyTime_AsFloat(ts);
354 if ((PyTypeObject *)format == &PyLong_Type)
355 return _PyTime_AsLong(ts);
356
357 if (PyType_Check(format))
358 {
359 PyObject *module, *name;
360 _Py_IDENTIFIER(__name__);
361 _Py_IDENTIFIER(__module__);
362
363 module = _PyObject_GetAttrId(format, &PyId___module__);
364 name = _PyObject_GetAttrId(format, &PyId___name__);
365 if (module != NULL && PyUnicode_Check(module)
366 && name != NULL && PyUnicode_Check(name))
367 {
368 if (PyUnicode_CompareWithASCIIString(module, "decimal") == 0
369 && PyUnicode_CompareWithASCIIString(name, "Decimal") == 0)
370 return _PyTime_AsDecimal(ts);
371 }
372 else
373 PyErr_Clear();
374 }
375
376 PyErr_Format(PyExc_ValueError, "Unknown timestamp format: %R", format);
377 return NULL;
378}
379
380void
Alexander Belopolsky6fc4ade2010-08-05 17:34:27 +0000381_PyTime_Init()
382{
383 /* Do nothing. Needed to force linking. */
384}