blob: 8b125083a83c4e9297833140562d194bb43c5c02 [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00004
5 All Rights Reserved
6
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossumf70e43a1991-02-19 12:39:46 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossumf70e43a1991-02-19 12:39:46 +000029
30******************************************************************/
31
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000032/* Time module */
33
Barry Warsaw9a2a8a81996-12-06 23:32:14 +000034#include "Python.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000035
Guido van Rossum99d90c01996-08-08 19:17:45 +000036#ifdef HAVE_SELECT
37#include "mymath.h"
38#endif
39
Guido van Rossum6d946f91992-08-14 13:49:30 +000040#ifdef macintosh
Guido van Rossumb6775db1994-08-01 11:34:53 +000041#include <time.h>
42#else
43#include <sys/types.h>
Guido van Rossum6d946f91992-08-14 13:49:30 +000044#endif
45
Guido van Rossumb6775db1994-08-01 11:34:53 +000046#ifdef QUICKWIN
47#include <io.h>
48#endif
49
50#ifdef HAVE_UNISTD_H
Guido van Rossum2762f251992-03-27 17:22:13 +000051#include <unistd.h>
52#endif
53
Guido van Rossumb6775db1994-08-01 11:34:53 +000054#ifdef HAVE_SELECT
55#include "myselect.h"
56#else
57#include "mytime.h"
58#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000059
Guido van Rossumb6775db1994-08-01 11:34:53 +000060#ifdef HAVE_FTIME
61#include <sys/timeb.h>
Guido van Rossum52174571996-12-09 18:38:52 +000062#ifndef MS_WINDOWS
Guido van Rossum1bb126f1996-12-06 20:17:44 +000063extern int ftime();
Guido van Rossum52174571996-12-09 18:38:52 +000064#endif /* MS_WINDOWS */
65#endif /* HAVE_FTIME */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000066
Guido van Rossumbceeac81996-05-23 22:53:47 +000067#ifdef __WATCOMC__
68#include <i86.h>
69#else
Guido van Rossumcac6c721996-09-06 13:34:02 +000070#ifdef MS_WINDOWS
Guido van Rossumb6775db1994-08-01 11:34:53 +000071#include <windows.h>
Guido van Rossumb2fb3641996-09-07 00:47:35 +000072#ifdef MS_WIN16
73/* These overrides not needed for Win32 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000074#define timezone _timezone
Guido van Rossumcc081121995-03-14 15:05:41 +000075#define tzname _tzname
76#define daylight _daylight
77#define altzone _altzone
Guido van Rossumb2fb3641996-09-07 00:47:35 +000078#endif /* MS_WIN16 */
Guido van Rossumcac6c721996-09-06 13:34:02 +000079#endif /* MS_WINDOWS */
80#endif /* !__WATCOMC__ */
Guido van Rossum234f9421993-06-17 12:35:49 +000081
Guido van Rossum3917c221997-04-02 05:35:28 +000082#ifdef MS_WIN32
83/* Win32 has better clock replacement */
84#include <largeint.h>
85#undef HAVE_CLOCK /* We have our own version down below */
86#endif /* MS_WIN32 */
87
Guido van Rossum234f9421993-06-17 12:35:49 +000088/* Forward declarations */
Barry Warsaw9a2a8a81996-12-06 23:32:14 +000089static int floatsleep Py_PROTO((double));
90static double floattime Py_PROTO(());
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000091
Guido van Rossume6a4b7b1997-10-08 15:27:56 +000092#ifdef macintosh
93/* Our own timezone. We have enough information to deduce whether
94** DST is on currently, but unfortunately we cannot put it to good
95** use because we don't know the rules (and that is needed to have
96** localtime() return correct tm_isdst values for times other than
97** the current time. So, we cop out and only tell the user the current
98** timezone.
99*/
100static long timezone;
101
102static void
103initmactimezone()
104{
105 MachineLocation loc;
106 long delta;
107
108 ReadLocation(&loc);
109
110 if (loc.latitude == 0 && loc.longitude == 0 && loc.u.gmtDelta == 0)
111 return;
112
113 delta = loc.u.gmtDelta & 0x00FFFFFF;
114
115 if (delta & 0x00800000)
116 delta |= 0xFF000000;
117
118 timezone = -delta;
119}
120#endif /* macintosh */
121
122
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000123static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000124time_time(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000125 PyObject *self;
126 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000127{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000128 double secs;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000129 if (!PyArg_NoArgs(args))
Guido van Rossuma2b7f401993-01-04 09:09:59 +0000130 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000131 secs = floattime();
132 if (secs == 0.0) {
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000133 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma2b7f401993-01-04 09:09:59 +0000134 return NULL;
135 }
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000136 return PyFloat_FromDouble(secs);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000137}
138
139#ifdef HAVE_CLOCK
140
141#ifndef CLOCKS_PER_SEC
Guido van Rossum1b66a4f1996-02-25 04:50:33 +0000142#ifdef CLK_TCK
143#define CLOCKS_PER_SEC CLK_TCK
144#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000145#define CLOCKS_PER_SEC 1000000
146#endif
Guido van Rossum1b66a4f1996-02-25 04:50:33 +0000147#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000148
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000149static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000150time_clock(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000151 PyObject *self;
152 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000153{
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000154 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155 return NULL;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000156 return PyFloat_FromDouble(((double)clock()) / CLOCKS_PER_SEC);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000157}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000158#endif /* HAVE_CLOCK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000159
Guido van Rossum3917c221997-04-02 05:35:28 +0000160#ifdef MS_WIN32
161/* Due to Mark Hammond */
162static PyObject *
163time_clock(self, args)
164 PyObject *self;
165 PyObject *args;
166{
167 static LARGE_INTEGER ctrStart;
168 static LARGE_INTEGER divisor = {0,0};
169 LARGE_INTEGER now, diff, rem;
170
171 if (!PyArg_NoArgs(args))
172 return NULL;
173
174 if (LargeIntegerEqualToZero(divisor)) {
175 QueryPerformanceCounter(&ctrStart);
176 if (!QueryPerformanceFrequency(&divisor) ||
177 LargeIntegerEqualToZero(divisor)) {
178 /* Unlikely to happen -
179 this works on all intel machines at least!
180 Revert to clock() */
181 return PyFloat_FromDouble(clock());
182 }
183 }
184 QueryPerformanceCounter(&now);
185 diff = LargeIntegerSubtract(now, ctrStart);
186 diff = LargeIntegerDivide(diff, divisor, &rem);
187 /* XXX - we assume both divide results fit in 32 bits. This is
188 true on Intels. First person who can afford a machine that
189 doesnt deserves to fix it :-)
190 */
191 return PyFloat_FromDouble((double)diff.LowPart +
192 ((double)rem.LowPart / (double)divisor.LowPart));
193}
194#define HAVE_CLOCK /* So it gets included in the methods */
195#endif /* MS_WIN32 */
196
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000197static PyObject *
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000198time_sleep(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000199 PyObject *self;
200 PyObject *args;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000201{
Guido van Rossum775f4da1993-01-09 17:18:52 +0000202 double secs;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000203 if (!PyArg_Parse(args, "d", &secs))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000204 return NULL;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000205 Py_BEGIN_ALLOW_THREADS
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000206 if (floatsleep(secs) != 0) {
207 Py_BLOCK_THREADS
Guido van Rossum3917c221997-04-02 05:35:28 +0000208 return NULL;
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000209 }
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000210 Py_END_ALLOW_THREADS
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000211 Py_INCREF(Py_None);
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000212 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000213}
214
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000215static PyObject *
Guido van Rossum234f9421993-06-17 12:35:49 +0000216time_convert(when, function)
217 time_t when;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000218 struct tm * (*function) Py_PROTO((const time_t *));
Guido van Rossum234f9421993-06-17 12:35:49 +0000219{
Guido van Rossum6e8583d1996-10-08 14:19:52 +0000220 struct tm *p;
221 errno = 0;
222 p = function(&when);
223 if (p == NULL) {
224#ifdef EINVAL
Guido van Rossum0b1ff661996-11-02 17:31:22 +0000225 if (errno == 0)
Guido van Rossum6e8583d1996-10-08 14:19:52 +0000226 errno = EINVAL;
227#endif
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000228 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum6e8583d1996-10-08 14:19:52 +0000229 }
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000230 return Py_BuildValue("(iiiiiiiii)",
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000231 p->tm_year + 1900,
232 p->tm_mon + 1, /* Want January == 1 */
233 p->tm_mday,
234 p->tm_hour,
235 p->tm_min,
236 p->tm_sec,
237 (p->tm_wday + 6) % 7, /* Want Monday == 0 */
238 p->tm_yday + 1, /* Want January, 1 == 1 */
239 p->tm_isdst);
Guido van Rossum234f9421993-06-17 12:35:49 +0000240}
241
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000242static PyObject *
Guido van Rossum234f9421993-06-17 12:35:49 +0000243time_gmtime(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000244 PyObject *self;
245 PyObject *args;
Guido van Rossum234f9421993-06-17 12:35:49 +0000246{
247 double when;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000248 if (!PyArg_Parse(args, "d", &when))
Guido van Rossum234f9421993-06-17 12:35:49 +0000249 return NULL;
250 return time_convert((time_t)when, gmtime);
251}
252
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000253static PyObject *
Guido van Rossum234f9421993-06-17 12:35:49 +0000254time_localtime(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000255 PyObject *self;
256 PyObject *args;
Guido van Rossum234f9421993-06-17 12:35:49 +0000257{
258 double when;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000259 if (!PyArg_Parse(args, "d", &when))
Guido van Rossum234f9421993-06-17 12:35:49 +0000260 return NULL;
261 return time_convert((time_t)when, localtime);
262}
263
Guido van Rossum9e90a671993-06-24 11:10:19 +0000264static int
265gettmarg(args, p)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000266 PyObject *args;
Guido van Rossum9e90a671993-06-24 11:10:19 +0000267 struct tm *p;
268{
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000269 if (!PyArg_Parse(args, "(iiiiiiiii)",
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000270 &p->tm_year,
271 &p->tm_mon,
272 &p->tm_mday,
273 &p->tm_hour,
274 &p->tm_min,
275 &p->tm_sec,
276 &p->tm_wday,
277 &p->tm_yday,
278 &p->tm_isdst))
Guido van Rossum9e90a671993-06-24 11:10:19 +0000279 return 0;
280 if (p->tm_year >= 1900)
281 p->tm_year -= 1900;
282 p->tm_mon--;
283 p->tm_wday = (p->tm_wday + 1) % 7;
284 p->tm_yday--;
285 return 1;
286}
287
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000288#ifdef HAVE_STRFTIME
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000289static PyObject *
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000290time_strftime(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000291 PyObject *self;
292 PyObject *args;
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000293{
294 struct tm buf;
295 const char *fmt;
296 char *outbuf = 0;
297 int i;
298
299 if (!PyArg_ParseTuple(args, "s(iiiiiiiii)",
300 &fmt,
301 &(buf.tm_year),
302 &(buf.tm_mon),
303 &(buf.tm_mday),
304 &(buf.tm_hour),
305 &(buf.tm_min),
306 &(buf.tm_sec),
307 &(buf.tm_wday),
308 &(buf.tm_yday),
309 &(buf.tm_isdst)))
310 return NULL;
311 if (buf.tm_year >= 1900)
312 buf.tm_year -= 1900;
313 buf.tm_mon--;
314 buf.tm_wday = (buf.tm_wday + 1) % 7;
315 buf.tm_yday--;
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000316 /* I hate these functions that presume you know how big the output
317 * will be ahead of time...
318 */
Guido van Rossuma78bfe11997-02-14 16:35:10 +0000319 for (i = 1024 ; i <= 8192 ; i += 1024) {
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000320 outbuf = malloc(i);
321 if (outbuf == NULL) {
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000322 return PyErr_NoMemory();
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000323 }
324 if (strftime(outbuf, i-1, fmt, &buf) != 0) {
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000325 PyObject *ret;
326 ret = PyString_FromString(outbuf);
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000327 free(outbuf);
328 return ret;
329 }
330 free(outbuf);
331 }
Guido van Rossuma78bfe11997-02-14 16:35:10 +0000332 PyErr_SetString(PyExc_ValueError,
333 "bad strftime format or result too big");
334 return NULL;
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000335}
336#endif /* HAVE_STRFTIME */
337
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000338static PyObject *
Guido van Rossum9e90a671993-06-24 11:10:19 +0000339time_asctime(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000340 PyObject *self;
341 PyObject *args;
Guido van Rossum9e90a671993-06-24 11:10:19 +0000342{
343 struct tm buf;
344 char *p;
345 if (!gettmarg(args, &buf))
346 return NULL;
347 p = asctime(&buf);
348 if (p[24] == '\n')
349 p[24] = '\0';
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000350 return PyString_FromString(p);
Guido van Rossum9e90a671993-06-24 11:10:19 +0000351}
352
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000353static PyObject *
Guido van Rossum9e90a671993-06-24 11:10:19 +0000354time_ctime(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000355 PyObject *self;
356 PyObject *args;
Guido van Rossum9e90a671993-06-24 11:10:19 +0000357{
358 double dt;
359 time_t tt;
360 char *p;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000361 if (!PyArg_Parse(args, "d", &dt))
Guido van Rossum9e90a671993-06-24 11:10:19 +0000362 return NULL;
Guido van Rossumcac6c721996-09-06 13:34:02 +0000363 tt = (time_t)dt;
Guido van Rossum9e90a671993-06-24 11:10:19 +0000364 p = ctime(&tt);
365 if (p[24] == '\n')
366 p[24] = '\0';
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000367 return PyString_FromString(p);
Guido van Rossum9e90a671993-06-24 11:10:19 +0000368}
369
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000370static PyObject *
Guido van Rossum234f9421993-06-17 12:35:49 +0000371time_mktime(self, args)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000372 PyObject *self;
373 PyObject *args;
Guido van Rossum234f9421993-06-17 12:35:49 +0000374{
375 struct tm buf;
Guido van Rossumbceeac81996-05-23 22:53:47 +0000376 time_t tt;
377 tt = time(&tt);
378 buf = *localtime(&tt);
Guido van Rossum9e90a671993-06-24 11:10:19 +0000379 if (!gettmarg(args, &buf))
Guido van Rossum234f9421993-06-17 12:35:49 +0000380 return NULL;
Guido van Rossumbceeac81996-05-23 22:53:47 +0000381 tt = mktime(&buf);
382 if (tt == (time_t)(-1)) {
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000383 PyErr_SetString(PyExc_OverflowError,
384 "mktime argument out of range");
Guido van Rossumbceeac81996-05-23 22:53:47 +0000385 return NULL;
386 }
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000387 return PyFloat_FromDouble((double)tt);
Guido van Rossum234f9421993-06-17 12:35:49 +0000388}
389
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000390static PyMethodDef time_methods[] = {
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000391 {"time", time_time},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000392#ifdef HAVE_CLOCK
393 {"clock", time_clock},
394#endif
395 {"sleep", time_sleep},
Guido van Rossum234f9421993-06-17 12:35:49 +0000396 {"gmtime", time_gmtime},
397 {"localtime", time_localtime},
Guido van Rossum9e90a671993-06-24 11:10:19 +0000398 {"asctime", time_asctime},
399 {"ctime", time_ctime},
Guido van Rossum234f9421993-06-17 12:35:49 +0000400 {"mktime", time_mktime},
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000401#ifdef HAVE_STRFTIME
Guido van Rossum5416e201996-02-13 00:14:09 +0000402 {"strftime", time_strftime, 1},
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000403#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000404 {NULL, NULL} /* sentinel */
405};
406
Guido van Rossum8239f0f1995-01-22 00:49:01 +0000407static void
408ins(d, name, v)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000409 PyObject *d;
Guido van Rossum8239f0f1995-01-22 00:49:01 +0000410 char *name;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000411 PyObject *v;
Guido van Rossum8239f0f1995-01-22 00:49:01 +0000412{
413 if (v == NULL)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000414 Py_FatalError("Can't initialize time module -- NULL value");
415 if (PyDict_SetItemString(d, name, v) != 0)
416 Py_FatalError(
Guido van Rossum52174571996-12-09 18:38:52 +0000417 "Can't initialize time module -- PyDict_SetItemString failed");
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000418 Py_DECREF(v);
Guido van Rossum8239f0f1995-01-22 00:49:01 +0000419}
420
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000421void
422inittime()
423{
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000424 PyObject *m, *d;
425 m = Py_InitModule("time", time_methods);
426 d = PyModule_GetDict(m);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000427#ifdef HAVE_TZNAME
Guido van Rossum234f9421993-06-17 12:35:49 +0000428 tzset();
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000429 ins(d, "timezone", PyInt_FromLong((long)timezone));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000430#ifdef HAVE_ALTZONE
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000431 ins(d, "altzone", PyInt_FromLong((long)altzone));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000432#else
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000433 ins(d, "altzone", PyInt_FromLong((long)timezone-3600));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000434#endif
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000435 ins(d, "daylight", PyInt_FromLong((long)daylight));
436 ins(d, "tzname", Py_BuildValue("(zz)", tzname[0], tzname[1]));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000437#else /* !HAVE_TZNAME */
438#if HAVE_TM_ZONE
Guido van Rossum234f9421993-06-17 12:35:49 +0000439 {
440#define YEAR ((time_t)((365 * 24 + 6) * 3600))
441 time_t t;
442 struct tm *p;
443 long winterzone, summerzone;
444 char wintername[10], summername[10];
Guido van Rossumb6775db1994-08-01 11:34:53 +0000445 /* XXX This won't work on the southern hemisphere.
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000446 XXX Anybody got a better idea? */
Guido van Rossum234f9421993-06-17 12:35:49 +0000447 t = (time((time_t *)0) / YEAR) * YEAR;
448 p = localtime(&t);
449 winterzone = -p->tm_gmtoff;
450 strncpy(wintername, p->tm_zone ? p->tm_zone : " ", 9);
451 wintername[9] = '\0';
452 t += YEAR/2;
453 p = localtime(&t);
454 summerzone = -p->tm_gmtoff;
455 strncpy(summername, p->tm_zone ? p->tm_zone : " ", 9);
456 summername[9] = '\0';
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000457 ins(d, "timezone", PyInt_FromLong(winterzone));
458 ins(d, "altzone", PyInt_FromLong(summerzone));
459 ins(d, "daylight",
460 PyInt_FromLong((long)(winterzone != summerzone)));
461 ins(d, "tzname",
462 Py_BuildValue("(zz)", wintername, summername));
Guido van Rossum234f9421993-06-17 12:35:49 +0000463 }
Guido van Rossume6a4b7b1997-10-08 15:27:56 +0000464#else
465#ifdef macintosh
466 initmactimezone();
467 ins(d, "timezone", PyInt_FromLong(timezone));
468#endif /* macintosh */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000469#endif /* HAVE_TM_ZONE */
470#endif /* !HAVE_TZNAME */
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000471 if (PyErr_Occurred())
472 Py_FatalError("Can't initialize time module");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000473}
474
475
Guido van Rossumb6775db1994-08-01 11:34:53 +0000476/* Implement floattime() for various platforms */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000477
Guido van Rossumb6775db1994-08-01 11:34:53 +0000478static double
479floattime()
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000480{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000481 /* There are three ways to get the time:
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000482 (1) gettimeofday() -- resolution in microseconds
483 (2) ftime() -- resolution in milliseconds
484 (3) time() -- resolution in seconds
485 In all cases the return value is a float in seconds.
486 Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
487 fail, so we fall back on ftime() or time().
488 Note: clock resolution does not imply clock accuracy! */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000489#ifdef HAVE_GETTIMEOFDAY
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000490 {
491 struct timeval t;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000492#ifdef GETTIMEOFDAY_NO_TZ
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000493 if (gettimeofday(&t) == 0)
494 return (double)t.tv_sec + t.tv_usec*0.000001;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000495#else /* !GETTIMEOFDAY_NO_TZ */
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000496 if (gettimeofday(&t, (struct timezone *)NULL) == 0)
497 return (double)t.tv_sec + t.tv_usec*0.000001;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000498#endif /* !GETTIMEOFDAY_NO_TZ */
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000499 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000500#endif /* !HAVE_GETTIMEOFDAY */
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000501 {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000502#ifdef HAVE_FTIME
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000503 struct timeb t;
504 ftime(&t);
505 return (double)t.time + (double)t.millitm * (double)0.001;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000506#else /* !HAVE_FTIME */
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000507 time_t secs;
508 time(&secs);
509 return (double)secs;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000510#endif /* !HAVE_FTIME */
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000511 }
Guido van Rossum426035c1991-02-19 12:27:35 +0000512}
513
Guido van Rossumb6775db1994-08-01 11:34:53 +0000514
515/* Implement floatsleep() for various platforms.
516 When interrupted (or when another error occurs), return -1 and
517 set an exception; else return 0. */
518
519static int
Guido van Rossuma320fd31995-03-09 12:14:15 +0000520#ifdef MPW
521floatsleep(double secs)
522#else
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000523 floatsleep(secs)
Guido van Rossum775f4da1993-01-09 17:18:52 +0000524 double secs;
Guido van Rossuma320fd31995-03-09 12:14:15 +0000525#endif /* MPW */
Guido van Rossum426035c1991-02-19 12:27:35 +0000526{
Guido van Rossuma78bfe11997-02-14 16:35:10 +0000527/* XXX Should test for MS_WIN32 first! */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000528#ifdef HAVE_SELECT
Guido van Rossum426035c1991-02-19 12:27:35 +0000529 struct timeval t;
Guido van Rossum775f4da1993-01-09 17:18:52 +0000530 double frac;
Guido van Rossum775f4da1993-01-09 17:18:52 +0000531 frac = fmod(secs, 1.0);
532 secs = floor(secs);
533 t.tv_sec = (long)secs;
534 t.tv_usec = (long)(frac*1000000.0);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000535 if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) {
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000536 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000537 return -1;
538 }
539#else /* !HAVE_SELECT */
540#ifdef macintosh
541#define MacTicks (* (long *)0x16A)
542 long deadline;
543 deadline = MacTicks + (long)(secs * 60.0);
544 while (MacTicks < deadline) {
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000545 if (PyErr_CheckSignals())
Guido van Rossumb6775db1994-08-01 11:34:53 +0000546 return -1;
547 }
548#else /* !macintosh */
Guido van Rossumbceeac81996-05-23 22:53:47 +0000549#ifdef __WATCOMC__
550 /* XXX Can't interrupt this sleep */
551 delay((int)(secs * 1000 + 0.5)); /* delay() uses milliseconds */
552#else /* !__WATCOMC__ */
Guido van Rossume22e6441993-07-09 10:51:31 +0000553#ifdef MSDOS
Guido van Rossumb6775db1994-08-01 11:34:53 +0000554 struct timeb t1, t2;
555 double frac;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000556 extern double fmod Py_PROTO((double, double));
557 extern double floor Py_PROTO((double));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000558 if (secs <= 0.0)
559 return;
560 frac = fmod(secs, 1.0);
561 secs = floor(secs);
562 ftime(&t1);
563 t2.time = t1.time + (int)secs;
564 t2.millitm = t1.millitm + (int)(frac*1000.0);
565 while (t2.millitm >= 1000) {
566 t2.time++;
567 t2.millitm -= 1000;
568 }
569 for (;;) {
570#ifdef QUICKWIN
571 _wyield();
Guido van Rossum80c9d881991-04-16 08:47:51 +0000572#endif
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000573 if (PyErr_CheckSignals())
Guido van Rossumb6775db1994-08-01 11:34:53 +0000574 return -1;
575 ftime(&t1);
576 if (t1.time > t2.time ||
577 t1.time == t2.time && t1.millitm >= t2.millitm)
578 break;
579 }
580#else /* !MSDOS */
Guido van Rossumb2fb3641996-09-07 00:47:35 +0000581#ifdef MS_WIN32
Guido van Rossumb6775db1994-08-01 11:34:53 +0000582 /* XXX Can't interrupt this sleep */
583 Sleep((int)(secs*1000));
Guido van Rossumb2fb3641996-09-07 00:47:35 +0000584#else /* !MS_WIN32 */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000585 /* XXX Can't interrupt this sleep */
586 sleep((int)secs);
Guido van Rossumb2fb3641996-09-07 00:47:35 +0000587#endif /* !MS_WIN32 */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000588#endif /* !MSDOS */
Guido van Rossumbceeac81996-05-23 22:53:47 +0000589#endif /* !__WATCOMC__ */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000590#endif /* !macintosh */
591#endif /* !HAVE_SELECT */
592 return 0;
Guido van Rossum80c9d881991-04-16 08:47:51 +0000593}