blob: 8cb7484984055b16e9b419de8d46c0adde3779ea [file] [log] [blame]
Guido van Rossumf70e43a1991-02-19 12:39:46 +00001/***********************************************************
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00002Copyright (c) 2000, BeOpen.com.
3Copyright (c) 1995-2000, Corporation for National Research Initiatives.
4Copyright (c) 1990-1995, Stichting Mathematisch Centrum.
5All rights reserved.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00006
Guido van Rossumfd71b9e2000-06-30 23:50:40 +00007See the file "Misc/COPYRIGHT" for information on usage and
8redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
Guido van Rossumf70e43a1991-02-19 12:39:46 +00009******************************************************************/
10
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000011/* Time module */
12
Barry Warsaw9a2a8a81996-12-06 23:32:14 +000013#include "Python.h"
Guido van Rossum3f5da241990-12-20 15:06:42 +000014
Guido van Rossum87ce7bb1998-06-09 16:30:31 +000015#include <ctype.h>
16
Guido van Rossum6d946f91992-08-14 13:49:30 +000017#ifdef macintosh
Guido van Rossumb6775db1994-08-01 11:34:53 +000018#include <time.h>
Guido van Rossumc410e922000-04-26 20:40:13 +000019#include <OSUtils.h>
20#ifdef USE_GUSI2
21/* GUSI, the I/O library which has the time() function and such uses the
22** Mac epoch of 1904. MSL, the C library which has localtime() and so uses
23** the ANSI epoch of 1900.
24*/
25#define GUSI_TO_MSL_EPOCH (4*365*24*60*60)
26#endif /* USE_GUSI2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000027#else
28#include <sys/types.h>
Guido van Rossum6d946f91992-08-14 13:49:30 +000029#endif
30
Guido van Rossumb6775db1994-08-01 11:34:53 +000031#ifdef QUICKWIN
32#include <io.h>
33#endif
34
35#ifdef HAVE_UNISTD_H
Guido van Rossum2762f251992-03-27 17:22:13 +000036#include <unistd.h>
37#endif
38
Guido van Rossumb6775db1994-08-01 11:34:53 +000039#ifdef HAVE_FTIME
40#include <sys/timeb.h>
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000041#if !defined(MS_WINDOWS) && !defined(PYOS_OS2)
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +000042extern int ftime(struct timeb *);
Guido van Rossum52174571996-12-09 18:38:52 +000043#endif /* MS_WINDOWS */
44#endif /* HAVE_FTIME */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000045
Guido van Rossum7bf22de1997-12-02 20:34:19 +000046#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossumbceeac81996-05-23 22:53:47 +000047#include <i86.h>
48#else
Guido van Rossumcac6c721996-09-06 13:34:02 +000049#ifdef MS_WINDOWS
Guido van Rossumb6775db1994-08-01 11:34:53 +000050#include <windows.h>
Guido van Rossumb2fb3641996-09-07 00:47:35 +000051#ifdef MS_WIN16
52/* These overrides not needed for Win32 */
Guido van Rossumb6775db1994-08-01 11:34:53 +000053#define timezone _timezone
Guido van Rossumcc081121995-03-14 15:05:41 +000054#define tzname _tzname
55#define daylight _daylight
56#define altzone _altzone
Guido van Rossumb2fb3641996-09-07 00:47:35 +000057#endif /* MS_WIN16 */
Guido van Rossumcac6c721996-09-06 13:34:02 +000058#endif /* MS_WINDOWS */
Guido van Rossum7bf22de1997-12-02 20:34:19 +000059#endif /* !__WATCOMC__ || __QNX__ */
Guido van Rossum234f9421993-06-17 12:35:49 +000060
Fred Drakedfb4ebd2000-06-29 20:56:28 +000061#if defined(MS_WIN32) && !defined(MS_WIN64)
62/* Win32 has better clock replacement
63 XXX Win64 does not yet, but might when the platform matures. */
Guido van Rossum3917c221997-04-02 05:35:28 +000064#include <largeint.h>
65#undef HAVE_CLOCK /* We have our own version down below */
Fred Drakedfb4ebd2000-06-29 20:56:28 +000066#endif /* MS_WIN32 && !MS_WIN64 */
Guido van Rossum3917c221997-04-02 05:35:28 +000067
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000068#if defined(PYCC_VACPP)
Guido van Rossum26452411998-09-28 22:07:11 +000069#include <sys/time.h>
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +000070#endif
71
Guido van Rossumbcc20741998-08-04 22:53:56 +000072#ifdef __BEOS__
Fred Drake56221a72000-08-15 18:52:33 +000073#include <time.h>
Guido van Rossumbcc20741998-08-04 22:53:56 +000074/* For bigtime_t, snooze(). - [cjh] */
75#include <support/SupportDefs.h>
76#include <kernel/OS.h>
77#endif
78
Guido van Rossum234f9421993-06-17 12:35:49 +000079/* Forward declarations */
Tim Petersdbd9ba62000-07-09 03:09:57 +000080static int floatsleep(double);
Thomas Woutersed77bac2000-07-24 15:26:39 +000081static double floattime(void);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +000082
Guido van Rossumcfbaecc1998-08-25 14:51:12 +000083/* For Y2K check */
84static PyObject *moddict;
85
Guido van Rossume6a4b7b1997-10-08 15:27:56 +000086#ifdef macintosh
87/* Our own timezone. We have enough information to deduce whether
88** DST is on currently, but unfortunately we cannot put it to good
89** use because we don't know the rules (and that is needed to have
90** localtime() return correct tm_isdst values for times other than
91** the current time. So, we cop out and only tell the user the current
92** timezone.
93*/
94static long timezone;
95
96static void
Thomas Woutersf3f33dc2000-07-21 06:00:07 +000097initmactimezone(void)
Guido van Rossume6a4b7b1997-10-08 15:27:56 +000098{
99 MachineLocation loc;
100 long delta;
101
102 ReadLocation(&loc);
103
104 if (loc.latitude == 0 && loc.longitude == 0 && loc.u.gmtDelta == 0)
105 return;
106
107 delta = loc.u.gmtDelta & 0x00FFFFFF;
108
109 if (delta & 0x00800000)
110 delta |= 0xFF000000;
111
112 timezone = -delta;
113}
114#endif /* macintosh */
115
116
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000117static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000118time_time(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000119{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000120 double secs;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000121 if (!PyArg_NoArgs(args))
Guido van Rossuma2b7f401993-01-04 09:09:59 +0000122 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000123 secs = floattime();
124 if (secs == 0.0) {
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000125 PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossuma2b7f401993-01-04 09:09:59 +0000126 return NULL;
127 }
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000128 return PyFloat_FromDouble(secs);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000129}
130
Guido van Rossum0ef577b1998-06-27 20:38:36 +0000131static char time_doc[] =
132"time() -> floating point number\n\
133\n\
134Return the current time in seconds since the Epoch.\n\
135Fractions of a second may be present if the system clock provides them.";
136
Guido van Rossumb6775db1994-08-01 11:34:53 +0000137#ifdef HAVE_CLOCK
138
139#ifndef CLOCKS_PER_SEC
Guido van Rossum1b66a4f1996-02-25 04:50:33 +0000140#ifdef CLK_TCK
141#define CLOCKS_PER_SEC CLK_TCK
142#else
Guido van Rossumb6775db1994-08-01 11:34:53 +0000143#define CLOCKS_PER_SEC 1000000
144#endif
Guido van Rossum1b66a4f1996-02-25 04:50:33 +0000145#endif
Guido van Rossumb6775db1994-08-01 11:34:53 +0000146
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000147static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000148time_clock(PyObject *self, PyObject *args)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000149{
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000150 if (!PyArg_NoArgs(args))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000151 return NULL;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000152 return PyFloat_FromDouble(((double)clock()) / CLOCKS_PER_SEC);
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000153}
Guido van Rossumb6775db1994-08-01 11:34:53 +0000154#endif /* HAVE_CLOCK */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000155
Fred Drakedfb4ebd2000-06-29 20:56:28 +0000156#if defined(MS_WIN32) && !defined(MS_WIN64)
Guido van Rossum3917c221997-04-02 05:35:28 +0000157/* Due to Mark Hammond */
158static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000159time_clock(PyObject *self, PyObject *args)
Guido van Rossum3917c221997-04-02 05:35:28 +0000160{
161 static LARGE_INTEGER ctrStart;
162 static LARGE_INTEGER divisor = {0,0};
163 LARGE_INTEGER now, diff, rem;
164
165 if (!PyArg_NoArgs(args))
166 return NULL;
167
168 if (LargeIntegerEqualToZero(divisor)) {
169 QueryPerformanceCounter(&ctrStart);
170 if (!QueryPerformanceFrequency(&divisor) ||
171 LargeIntegerEqualToZero(divisor)) {
172 /* Unlikely to happen -
173 this works on all intel machines at least!
174 Revert to clock() */
175 return PyFloat_FromDouble(clock());
176 }
177 }
178 QueryPerformanceCounter(&now);
179 diff = LargeIntegerSubtract(now, ctrStart);
180 diff = LargeIntegerDivide(diff, divisor, &rem);
181 /* XXX - we assume both divide results fit in 32 bits. This is
182 true on Intels. First person who can afford a machine that
183 doesnt deserves to fix it :-)
184 */
185 return PyFloat_FromDouble((double)diff.LowPart +
186 ((double)rem.LowPart / (double)divisor.LowPart));
187}
Guido van Rossum0ef577b1998-06-27 20:38:36 +0000188
Guido van Rossum3917c221997-04-02 05:35:28 +0000189#define HAVE_CLOCK /* So it gets included in the methods */
Fred Drakedfb4ebd2000-06-29 20:56:28 +0000190#endif /* MS_WIN32 && !MS_WIN64 */
Guido van Rossum3917c221997-04-02 05:35:28 +0000191
Guido van Rossum0ef577b1998-06-27 20:38:36 +0000192#ifdef HAVE_CLOCK
193static char clock_doc[] =
194"clock() -> floating point number\n\
195\n\
196Return the CPU time or real time since the start of the process or since\n\
197the first call to clock(). This has as much precision as the system records.";
198#endif
199
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000200static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000201time_sleep(PyObject *self, PyObject *args)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000202{
Guido van Rossum775f4da1993-01-09 17:18:52 +0000203 double secs;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000204 if (!PyArg_Parse(args, "d", &secs))
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000205 return NULL;
Guido van Rossum8607ae21997-11-03 22:04:46 +0000206 if (floatsleep(secs) != 0)
207 return NULL;
208 Py_INCREF(Py_None);
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000209 return Py_None;
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000210}
211
Guido van Rossum0ef577b1998-06-27 20:38:36 +0000212static char sleep_doc[] =
213"sleep(seconds)\n\
214\n\
215Delay execution for a given number of seconds. The argument may be\n\
216a floating point number for subsecond precision.";
217
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000218static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000219tmtotuple(struct tm *p)
Guido van Rossum87ce7bb1998-06-09 16:30:31 +0000220{
221 return Py_BuildValue("(iiiiiiiii)",
222 p->tm_year + 1900,
223 p->tm_mon + 1, /* Want January == 1 */
224 p->tm_mday,
225 p->tm_hour,
226 p->tm_min,
227 p->tm_sec,
228 (p->tm_wday + 6) % 7, /* Want Monday == 0 */
229 p->tm_yday + 1, /* Want January, 1 == 1 */
230 p->tm_isdst);
231}
232
233static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000234time_convert(time_t when, struct tm * (*function)(const time_t *))
Guido van Rossum234f9421993-06-17 12:35:49 +0000235{
Guido van Rossum6e8583d1996-10-08 14:19:52 +0000236 struct tm *p;
237 errno = 0;
Jack Jansenee398fa2000-07-03 21:37:27 +0000238#if defined(macintosh) && defined(USE_GUSI204)
Guido van Rossumc410e922000-04-26 20:40:13 +0000239 when = when + GUSI_TO_MSL_EPOCH;
240#endif
Guido van Rossum6e8583d1996-10-08 14:19:52 +0000241 p = function(&when);
242 if (p == NULL) {
243#ifdef EINVAL
Guido van Rossum0b1ff661996-11-02 17:31:22 +0000244 if (errno == 0)
Guido van Rossum6e8583d1996-10-08 14:19:52 +0000245 errno = EINVAL;
246#endif
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000247 return PyErr_SetFromErrno(PyExc_IOError);
Guido van Rossum6e8583d1996-10-08 14:19:52 +0000248 }
Guido van Rossum87ce7bb1998-06-09 16:30:31 +0000249 return tmtotuple(p);
Guido van Rossum234f9421993-06-17 12:35:49 +0000250}
251
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000252static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000253time_gmtime(PyObject *self, PyObject *args)
Guido van Rossum234f9421993-06-17 12:35:49 +0000254{
255 double when;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000256 if (!PyArg_Parse(args, "d", &when))
Guido van Rossum234f9421993-06-17 12:35:49 +0000257 return NULL;
258 return time_convert((time_t)when, gmtime);
259}
260
Guido van Rossum0ef577b1998-06-27 20:38:36 +0000261static char gmtime_doc[] =
262"gmtime(seconds) -> tuple\n\
263\n\
264Convert seconds since the Epoch to a time tuple expressing UTC (a.k.a. GMT).";
265
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000266static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000267time_localtime(PyObject *self, PyObject *args)
Guido van Rossum234f9421993-06-17 12:35:49 +0000268{
269 double when;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000270 if (!PyArg_Parse(args, "d", &when))
Guido van Rossum234f9421993-06-17 12:35:49 +0000271 return NULL;
272 return time_convert((time_t)when, localtime);
273}
274
Guido van Rossum0ef577b1998-06-27 20:38:36 +0000275static char localtime_doc[] =
276"localtime(seconds) -> tuple\n\
277Convert seconds since the Epoch to a time tuple expressing local time.";
278
Guido van Rossum9e90a671993-06-24 11:10:19 +0000279static int
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000280gettmarg(PyObject *args, struct tm *p)
Guido van Rossum9e90a671993-06-24 11:10:19 +0000281{
Guido van Rossumcfbaecc1998-08-25 14:51:12 +0000282 int y;
Thomas Wouters334fb892000-07-25 12:56:38 +0000283 memset((void *) p, '\0', sizeof(struct tm));
Guido van Rossumcfbaecc1998-08-25 14:51:12 +0000284
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000285 if (!PyArg_Parse(args, "(iiiiiiiii)",
Guido van Rossumcfbaecc1998-08-25 14:51:12 +0000286 &y,
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000287 &p->tm_mon,
288 &p->tm_mday,
289 &p->tm_hour,
290 &p->tm_min,
291 &p->tm_sec,
292 &p->tm_wday,
293 &p->tm_yday,
294 &p->tm_isdst))
Guido van Rossum9e90a671993-06-24 11:10:19 +0000295 return 0;
Guido van Rossumcfbaecc1998-08-25 14:51:12 +0000296 if (y < 1900) {
297 PyObject *accept = PyDict_GetItemString(moddict,
298 "accept2dyear");
299 if (accept == NULL || !PyInt_Check(accept) ||
300 PyInt_AsLong(accept) == 0) {
301 PyErr_SetString(PyExc_ValueError,
302 "year >= 1900 required");
303 return 0;
304 }
305 if (69 <= y && y <= 99)
306 y += 1900;
307 else if (0 <= y && y <= 68)
308 y += 2000;
309 else {
310 PyErr_SetString(PyExc_ValueError,
311 "year out of range (00-99, 1900-*)");
312 return 0;
313 }
314 }
315 p->tm_year = y - 1900;
Guido van Rossum9e90a671993-06-24 11:10:19 +0000316 p->tm_mon--;
317 p->tm_wday = (p->tm_wday + 1) % 7;
318 p->tm_yday--;
319 return 1;
320}
321
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000322#ifdef HAVE_STRFTIME
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000323static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000324time_strftime(PyObject *self, PyObject *args)
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000325{
Guido van Rossumcfbaecc1998-08-25 14:51:12 +0000326 PyObject *tup;
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000327 struct tm buf;
328 const char *fmt;
Guido van Rossumfa481162000-06-28 21:33:59 +0000329 size_t fmtlen, buflen;
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000330 char *outbuf = 0;
Guido van Rossumfa481162000-06-28 21:33:59 +0000331 size_t i;
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000332
Thomas Wouters334fb892000-07-25 12:56:38 +0000333 memset((void *) &buf, '\0', sizeof(buf));
Guido van Rossum1f41f841998-04-27 19:04:26 +0000334
Jeremy Hylton7ceab652000-03-14 21:17:16 +0000335 if (!PyArg_ParseTuple(args, "sO:strftime", &fmt, &tup)
336 || !gettmarg(tup, &buf))
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000337 return NULL;
Guido van Rossumc222ec21999-02-23 00:00:10 +0000338 fmtlen = strlen(fmt);
339
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000340 /* I hate these functions that presume you know how big the output
341 * will be ahead of time...
342 */
Guido van Rossumc222ec21999-02-23 00:00:10 +0000343 for (i = 1024; ; i += i) {
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000344 outbuf = malloc(i);
345 if (outbuf == NULL) {
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000346 return PyErr_NoMemory();
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000347 }
Guido van Rossumc222ec21999-02-23 00:00:10 +0000348 buflen = strftime(outbuf, i, fmt, &buf);
349 if (buflen > 0 || i >= 256 * fmtlen) {
350 /* If the buffer is 256 times as long as the format,
351 it's probably not failing for lack of room!
352 More likely, the format yields an empty result,
353 e.g. an empty format, or %Z when the timezone
354 is unknown. */
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000355 PyObject *ret;
Guido van Rossumc222ec21999-02-23 00:00:10 +0000356 ret = PyString_FromStringAndSize(outbuf, buflen);
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000357 free(outbuf);
358 return ret;
359 }
360 free(outbuf);
361 }
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000362}
Guido van Rossum0ef577b1998-06-27 20:38:36 +0000363
364static char strftime_doc[] =
365"strftime(format, tuple) -> string\n\
366\n\
367Convert a time tuple to a string according to a format specification.\n\
368See the library reference manual for formatting codes.";
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000369#endif /* HAVE_STRFTIME */
370
Guido van Rossum87ce7bb1998-06-09 16:30:31 +0000371#ifdef HAVE_STRPTIME
Fred Drakeaff60182000-05-09 19:52:40 +0000372
373#if 0
Thomas Woutersbd4bc4e2000-07-22 23:57:55 +0000374/* Enable this if it's not declared in <time.h> */
375extern char *strptime(const char *, const char *, struct tm *);
Fred Drakeaff60182000-05-09 19:52:40 +0000376#endif
Guido van Rossumc2068731998-10-07 16:35:25 +0000377
Guido van Rossum87ce7bb1998-06-09 16:30:31 +0000378static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000379time_strptime(PyObject *self, PyObject *args)
Guido van Rossum87ce7bb1998-06-09 16:30:31 +0000380{
381 struct tm tm;
382 char *fmt = "%a %b %d %H:%M:%S %Y";
383 char *buf;
384 char *s;
385
Jeremy Hylton7ceab652000-03-14 21:17:16 +0000386 if (!PyArg_ParseTuple(args, "s|s:strptime", &buf, &fmt))
387 return NULL;
Thomas Wouters334fb892000-07-25 12:56:38 +0000388 memset((void *) &tm, '\0', sizeof(tm));
Guido van Rossum87ce7bb1998-06-09 16:30:31 +0000389 s = strptime(buf, fmt, &tm);
390 if (s == NULL) {
391 PyErr_SetString(PyExc_ValueError, "format mismatch");
392 return NULL;
393 }
394 while (*s && isspace(*s))
395 s++;
396 if (*s) {
397 PyErr_Format(PyExc_ValueError,
398 "unconverted data remains: '%.400s'", s);
399 return NULL;
400 }
401 return tmtotuple(&tm);
402}
Guido van Rossum0ef577b1998-06-27 20:38:36 +0000403
404static char strptime_doc[] =
Guido van Rossum446ccfe1999-01-07 18:29:26 +0000405"strptime(string, format) -> tuple\n\
Guido van Rossum0ef577b1998-06-27 20:38:36 +0000406Parse a string to a time tuple according to a format specification.\n\
407See the library reference manual for formatting codes (same as strftime()).";
Guido van Rossum87ce7bb1998-06-09 16:30:31 +0000408#endif /* HAVE_STRPTIME */
409
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000410static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000411time_asctime(PyObject *self, PyObject *args)
Guido van Rossum9e90a671993-06-24 11:10:19 +0000412{
Guido van Rossumb2b42dd2000-01-12 16:38:20 +0000413 PyObject *tup;
Guido van Rossum9e90a671993-06-24 11:10:19 +0000414 struct tm buf;
415 char *p;
Guido van Rossum43713e52000-02-29 13:59:29 +0000416 if (!PyArg_ParseTuple(args, "O:asctime", &tup))
Guido van Rossumb2b42dd2000-01-12 16:38:20 +0000417 return NULL;
418 if (!gettmarg(tup, &buf))
Guido van Rossum9e90a671993-06-24 11:10:19 +0000419 return NULL;
420 p = asctime(&buf);
421 if (p[24] == '\n')
422 p[24] = '\0';
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000423 return PyString_FromString(p);
Guido van Rossum9e90a671993-06-24 11:10:19 +0000424}
425
Guido van Rossum0ef577b1998-06-27 20:38:36 +0000426static char asctime_doc[] =
427"asctime(tuple) -> string\n\
428\n\
429Convert a time tuple to a string, e.g. 'Sat Jun 06 16:26:11 1998'.";
430
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000431static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000432time_ctime(PyObject *self, PyObject *args)
Guido van Rossum9e90a671993-06-24 11:10:19 +0000433{
434 double dt;
435 time_t tt;
436 char *p;
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000437 if (!PyArg_Parse(args, "d", &dt))
Guido van Rossum9e90a671993-06-24 11:10:19 +0000438 return NULL;
Guido van Rossumcac6c721996-09-06 13:34:02 +0000439 tt = (time_t)dt;
Jack Jansenee398fa2000-07-03 21:37:27 +0000440#if defined(macintosh) && defined(USE_GUSI204)
Guido van Rossumc410e922000-04-26 20:40:13 +0000441 tt = tt + GUSI_TO_MSL_EPOCH;
442#endif
Guido van Rossum9e90a671993-06-24 11:10:19 +0000443 p = ctime(&tt);
Guido van Rossum78535701998-03-03 22:19:10 +0000444 if (p == NULL) {
445 PyErr_SetString(PyExc_ValueError, "unconvertible time");
446 return NULL;
447 }
Guido van Rossum9e90a671993-06-24 11:10:19 +0000448 if (p[24] == '\n')
449 p[24] = '\0';
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000450 return PyString_FromString(p);
Guido van Rossum9e90a671993-06-24 11:10:19 +0000451}
452
Guido van Rossum0ef577b1998-06-27 20:38:36 +0000453static char ctime_doc[] =
454"ctime(seconds) -> string\n\
455\n\
456Convert a time in seconds since the Epoch to a string in local time.\n\
457This is equivalent to asctime(localtime(seconds)).";
458
Guido van Rossum60cd8131998-03-06 17:16:21 +0000459#ifdef HAVE_MKTIME
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000460static PyObject *
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000461time_mktime(PyObject *self, PyObject *args)
Guido van Rossum234f9421993-06-17 12:35:49 +0000462{
Guido van Rossumb2b42dd2000-01-12 16:38:20 +0000463 PyObject *tup;
Guido van Rossum234f9421993-06-17 12:35:49 +0000464 struct tm buf;
Guido van Rossumbceeac81996-05-23 22:53:47 +0000465 time_t tt;
Guido van Rossum43713e52000-02-29 13:59:29 +0000466 if (!PyArg_ParseTuple(args, "O:mktime", &tup))
Guido van Rossumb2b42dd2000-01-12 16:38:20 +0000467 return NULL;
Guido van Rossumbceeac81996-05-23 22:53:47 +0000468 tt = time(&tt);
469 buf = *localtime(&tt);
Guido van Rossumb2b42dd2000-01-12 16:38:20 +0000470 if (!gettmarg(tup, &buf))
Guido van Rossum234f9421993-06-17 12:35:49 +0000471 return NULL;
Guido van Rossumbceeac81996-05-23 22:53:47 +0000472 tt = mktime(&buf);
473 if (tt == (time_t)(-1)) {
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000474 PyErr_SetString(PyExc_OverflowError,
475 "mktime argument out of range");
Guido van Rossumbceeac81996-05-23 22:53:47 +0000476 return NULL;
477 }
Guido van Rossumc410e922000-04-26 20:40:13 +0000478#if defined(macintosh) && defined(USE_GUSI2)
479 tt = tt - GUSI_TO_MSL_EPOCH;
480#endif
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000481 return PyFloat_FromDouble((double)tt);
Guido van Rossum234f9421993-06-17 12:35:49 +0000482}
Guido van Rossum0ef577b1998-06-27 20:38:36 +0000483
484static char mktime_doc[] =
485"mktime(tuple) -> floating point number\n\
486\n\
487Convert a time tuple in local time to seconds since the Epoch.";
Guido van Rossum60cd8131998-03-06 17:16:21 +0000488#endif /* HAVE_MKTIME */
Guido van Rossum234f9421993-06-17 12:35:49 +0000489
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000490static PyMethodDef time_methods[] = {
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000491 {"time", time_time, METH_OLDARGS, time_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000492#ifdef HAVE_CLOCK
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000493 {"clock", time_clock, METH_OLDARGS, clock_doc},
Guido van Rossumb6775db1994-08-01 11:34:53 +0000494#endif
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000495 {"sleep", time_sleep, METH_OLDARGS, sleep_doc},
496 {"gmtime", time_gmtime, METH_OLDARGS, gmtime_doc},
497 {"localtime", time_localtime, METH_OLDARGS, localtime_doc},
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000498 {"asctime", time_asctime, METH_VARARGS, asctime_doc},
Andrew M. Kuchlinga1abb722000-08-03 02:34:44 +0000499 {"ctime", time_ctime, METH_OLDARGS, ctime_doc},
Guido van Rossum60cd8131998-03-06 17:16:21 +0000500#ifdef HAVE_MKTIME
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000501 {"mktime", time_mktime, METH_VARARGS, mktime_doc},
Guido van Rossum60cd8131998-03-06 17:16:21 +0000502#endif
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000503#ifdef HAVE_STRFTIME
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000504 {"strftime", time_strftime, METH_VARARGS, strftime_doc},
Guido van Rossum8d8c1ee1995-09-13 17:38:35 +0000505#endif
Guido van Rossum87ce7bb1998-06-09 16:30:31 +0000506#ifdef HAVE_STRPTIME
Andrew M. Kuchlinge365fb82000-08-03 02:06:16 +0000507 {"strptime", time_strptime, METH_VARARGS, strptime_doc},
Guido van Rossum87ce7bb1998-06-09 16:30:31 +0000508#endif
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000509 {NULL, NULL} /* sentinel */
510};
511
Guido van Rossum8239f0f1995-01-22 00:49:01 +0000512static void
Peter Schneider-Kamp416d4132000-07-10 12:15:54 +0000513ins(PyObject *d, char *name, PyObject *v)
Guido van Rossum8239f0f1995-01-22 00:49:01 +0000514{
515 if (v == NULL)
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000516 Py_FatalError("Can't initialize time module -- NULL value");
517 if (PyDict_SetItemString(d, name, v) != 0)
518 Py_FatalError(
Guido van Rossum52174571996-12-09 18:38:52 +0000519 "Can't initialize time module -- PyDict_SetItemString failed");
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000520 Py_DECREF(v);
Guido van Rossum8239f0f1995-01-22 00:49:01 +0000521}
522
Guido van Rossum0ef577b1998-06-27 20:38:36 +0000523static char module_doc[] =
524"This module provides various functions to manipulate time values.\n\
525\n\
526There are two standard representations of time. One is the number\n\
527of seconds since the Epoch, in UTC (a.k.a. GMT). It may be an integer\n\
528or a floating point number (to represent fractions of seconds).\n\
529The Epoch is system-defined; on Unix, it is generally January 1st, 1970.\n\
530The actual value can be retrieved by calling gmtime(0).\n\
531\n\
532The other representation is a tuple of 9 integers giving local time.\n\
533The tuple items are:\n\
534 year (four digits, e.g. 1998)\n\
535 month (1-12)\n\
536 day (1-31)\n\
537 hours (0-23)\n\
538 minutes (0-59)\n\
Guido van Rossum360eb9f1999-02-22 16:19:52 +0000539 seconds (0-59)\n\
Guido van Rossum0ef577b1998-06-27 20:38:36 +0000540 weekday (0-6, Monday is 0)\n\
541 Julian day (day in the year, 1-366)\n\
542 DST (Daylight Savings Time) flag (-1, 0 or 1)\n\
543If the DST flag is 0, the time is given in the regular time zone;\n\
544if it is 1, the time is given in the DST time zone;\n\
545if it is -1, mktime() should guess based on the date and time.\n\
546\n\
547Variables:\n\
548\n\
549timezone -- difference in seconds between UTC and local standard time\n\
550altzone -- difference in seconds between UTC and local DST time\n\
551daylight -- whether local time should reflect DST\n\
552tzname -- tuple of (standard time zone name, DST time zone name)\n\
553\n\
554Functions:\n\
555\n\
556time() -- return current time in seconds since the Epoch as a float\n\
557clock() -- return CPU time since process start as a float\n\
558sleep() -- delay for a number of seconds given as a float\n\
559gmtime() -- convert seconds since Epoch to UTC tuple\n\
560localtime() -- convert seconds since Epoch to local time tuple\n\
561asctime() -- convert time tuple to string\n\
562ctime() -- convert time in seconds to string\n\
563mktime() -- convert local time tuple to seconds since Epoch\n\
564strftime() -- convert time tuple to string according to format specification\n\
565strptime() -- parse string to time tuple according to format specification\n\
566";
567
568
Guido van Rossum3886bb61998-12-04 18:50:17 +0000569DL_EXPORT(void)
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000570inittime(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000571{
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000572 PyObject *m, *d;
Guido van Rossumcfbaecc1998-08-25 14:51:12 +0000573 char *p;
Guido van Rossum0ef577b1998-06-27 20:38:36 +0000574 m = Py_InitModule3("time", time_methods, module_doc);
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000575 d = PyModule_GetDict(m);
Guido van Rossumc2068731998-10-07 16:35:25 +0000576 /* Accept 2-digit dates unless PYTHONY2K is set and non-empty */
577 p = getenv("PYTHONY2K");
578 ins(d, "accept2dyear", PyInt_FromLong((long) (!p || !*p)));
579 /* Squirrel away the module's dictionary for the y2k check */
580 Py_INCREF(d);
581 moddict = d;
Guido van Rossumea424e11999-04-23 20:59:05 +0000582#if defined(HAVE_TZNAME) && !defined(__GLIBC__)
Guido van Rossum234f9421993-06-17 12:35:49 +0000583 tzset();
Guido van Rossum26452411998-09-28 22:07:11 +0000584#ifdef PYOS_OS2
585 ins(d, "timezone", PyInt_FromLong((long)_timezone));
586#else /* !PYOS_OS2 */
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000587 ins(d, "timezone", PyInt_FromLong((long)timezone));
Guido van Rossum26452411998-09-28 22:07:11 +0000588#endif /* PYOS_OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000589#ifdef HAVE_ALTZONE
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000590 ins(d, "altzone", PyInt_FromLong((long)altzone));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000591#else
Guido van Rossum26452411998-09-28 22:07:11 +0000592#ifdef PYOS_OS2
593 ins(d, "altzone", PyInt_FromLong((long)_timezone-3600));
594#else /* !PYOS_OS2 */
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000595 ins(d, "altzone", PyInt_FromLong((long)timezone-3600));
Guido van Rossum26452411998-09-28 22:07:11 +0000596#endif /* PYOS_OS2 */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000597#endif
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000598 ins(d, "daylight", PyInt_FromLong((long)daylight));
599 ins(d, "tzname", Py_BuildValue("(zz)", tzname[0], tzname[1]));
Guido van Rossumea424e11999-04-23 20:59:05 +0000600#else /* !HAVE_TZNAME || __GLIBC__ */
Guido van Rossum0ffdd051999-04-05 21:54:14 +0000601#ifdef HAVE_TM_ZONE
Guido van Rossum234f9421993-06-17 12:35:49 +0000602 {
603#define YEAR ((time_t)((365 * 24 + 6) * 3600))
604 time_t t;
605 struct tm *p;
Guido van Rossum57731601999-03-29 19:12:04 +0000606 long janzone, julyzone;
607 char janname[10], julyname[10];
Guido van Rossum234f9421993-06-17 12:35:49 +0000608 t = (time((time_t *)0) / YEAR) * YEAR;
609 p = localtime(&t);
Guido van Rossum57731601999-03-29 19:12:04 +0000610 janzone = -p->tm_gmtoff;
611 strncpy(janname, p->tm_zone ? p->tm_zone : " ", 9);
612 janname[9] = '\0';
Guido van Rossum234f9421993-06-17 12:35:49 +0000613 t += YEAR/2;
614 p = localtime(&t);
Guido van Rossum57731601999-03-29 19:12:04 +0000615 julyzone = -p->tm_gmtoff;
616 strncpy(julyname, p->tm_zone ? p->tm_zone : " ", 9);
617 julyname[9] = '\0';
618
619 if( janzone < julyzone ) {
620 /* DST is reversed in the southern hemisphere */
621 ins(d, "timezone", PyInt_FromLong(julyzone));
622 ins(d, "altzone", PyInt_FromLong(janzone));
623 ins(d, "daylight",
624 PyInt_FromLong((long)(janzone != julyzone)));
625 ins(d, "tzname",
626 Py_BuildValue("(zz)", julyname, janname));
627 } else {
628 ins(d, "timezone", PyInt_FromLong(janzone));
629 ins(d, "altzone", PyInt_FromLong(julyzone));
630 ins(d, "daylight",
631 PyInt_FromLong((long)(janzone != julyzone)));
632 ins(d, "tzname",
633 Py_BuildValue("(zz)", janname, julyname));
634 }
Guido van Rossum234f9421993-06-17 12:35:49 +0000635 }
Guido van Rossume6a4b7b1997-10-08 15:27:56 +0000636#else
637#ifdef macintosh
Guido van Rossumbe1eb0d1997-12-08 21:56:43 +0000638 /* The only thing we can obtain is the current timezone
639 ** (and whether dst is currently _active_, but that is not what
640 ** we're looking for:-( )
641 */
Guido van Rossume6a4b7b1997-10-08 15:27:56 +0000642 initmactimezone();
643 ins(d, "timezone", PyInt_FromLong(timezone));
Guido van Rossumbe1eb0d1997-12-08 21:56:43 +0000644 ins(d, "altzone", PyInt_FromLong(timezone));
645 ins(d, "daylight", PyInt_FromLong((long)0));
646 ins(d, "tzname", Py_BuildValue("(zz)", "", ""));
Guido van Rossume6a4b7b1997-10-08 15:27:56 +0000647#endif /* macintosh */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000648#endif /* HAVE_TM_ZONE */
Guido van Rossumea424e11999-04-23 20:59:05 +0000649#endif /* !HAVE_TZNAME || __GLIBC__ */
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000650 if (PyErr_Occurred())
651 Py_FatalError("Can't initialize time module");
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000652}
653
654
Guido van Rossumb6775db1994-08-01 11:34:53 +0000655/* Implement floattime() for various platforms */
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000656
Guido van Rossumb6775db1994-08-01 11:34:53 +0000657static double
Thomas Woutersf3f33dc2000-07-21 06:00:07 +0000658floattime(void)
Guido van Rossum85a5fbb1990-10-14 12:07:46 +0000659{
Guido van Rossumb6775db1994-08-01 11:34:53 +0000660 /* There are three ways to get the time:
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000661 (1) gettimeofday() -- resolution in microseconds
662 (2) ftime() -- resolution in milliseconds
663 (3) time() -- resolution in seconds
664 In all cases the return value is a float in seconds.
665 Since on some systems (e.g. SCO ODT 3.0) gettimeofday() may
666 fail, so we fall back on ftime() or time().
667 Note: clock resolution does not imply clock accuracy! */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000668#ifdef HAVE_GETTIMEOFDAY
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000669 {
670 struct timeval t;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000671#ifdef GETTIMEOFDAY_NO_TZ
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000672 if (gettimeofday(&t) == 0)
673 return (double)t.tv_sec + t.tv_usec*0.000001;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000674#else /* !GETTIMEOFDAY_NO_TZ */
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000675 if (gettimeofday(&t, (struct timezone *)NULL) == 0)
676 return (double)t.tv_sec + t.tv_usec*0.000001;
Guido van Rossum3bbc62e1995-01-02 19:30:30 +0000677#endif /* !GETTIMEOFDAY_NO_TZ */
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000678 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000679#endif /* !HAVE_GETTIMEOFDAY */
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000680 {
Guido van Rossumd3eb5771999-03-09 16:07:23 +0000681#if defined(HAVE_FTIME)
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000682 struct timeb t;
683 ftime(&t);
684 return (double)t.time + (double)t.millitm * (double)0.001;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000685#else /* !HAVE_FTIME */
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000686 time_t secs;
687 time(&secs);
688 return (double)secs;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000689#endif /* !HAVE_FTIME */
Barry Warsaw4a6cf411997-01-13 22:44:55 +0000690 }
Guido van Rossum426035c1991-02-19 12:27:35 +0000691}
692
Guido van Rossumb6775db1994-08-01 11:34:53 +0000693
694/* Implement floatsleep() for various platforms.
695 When interrupted (or when another error occurs), return -1 and
696 set an exception; else return 0. */
697
698static int
Guido van Rossuma320fd31995-03-09 12:14:15 +0000699floatsleep(double secs)
Guido van Rossum426035c1991-02-19 12:27:35 +0000700{
Guido van Rossuma78bfe11997-02-14 16:35:10 +0000701/* XXX Should test for MS_WIN32 first! */
Guido van Rossumbcc20741998-08-04 22:53:56 +0000702#if defined(HAVE_SELECT) && !defined(__BEOS__)
Guido van Rossum426035c1991-02-19 12:27:35 +0000703 struct timeval t;
Guido van Rossum775f4da1993-01-09 17:18:52 +0000704 double frac;
Guido van Rossum775f4da1993-01-09 17:18:52 +0000705 frac = fmod(secs, 1.0);
706 secs = floor(secs);
707 t.tv_sec = (long)secs;
708 t.tv_usec = (long)(frac*1000000.0);
Guido van Rossum8607ae21997-11-03 22:04:46 +0000709 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb6775db1994-08-01 11:34:53 +0000710 if (select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t) != 0) {
Guido van Rossum09cbb011999-11-08 15:32:27 +0000711#ifdef EINTR
Guido van Rossuma5456d51999-08-19 14:40:27 +0000712 if (errno != EINTR) {
Guido van Rossum09cbb011999-11-08 15:32:27 +0000713#else
714 if (1) {
715#endif
Andrew M. Kuchlingc24ca4b2000-03-24 20:35:20 +0000716 Py_BLOCK_THREADS
Guido van Rossuma5456d51999-08-19 14:40:27 +0000717 PyErr_SetFromErrno(PyExc_IOError);
718 return -1;
719 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000720 }
Guido van Rossum8607ae21997-11-03 22:04:46 +0000721 Py_END_ALLOW_THREADS
Guido van Rossumbcc20741998-08-04 22:53:56 +0000722#else /* !HAVE_SELECT || __BEOS__ */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000723#ifdef macintosh
724#define MacTicks (* (long *)0x16A)
725 long deadline;
726 deadline = MacTicks + (long)(secs * 60.0);
727 while (MacTicks < deadline) {
Guido van Rossum8607ae21997-11-03 22:04:46 +0000728 /* XXX Should call some yielding function here */
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000729 if (PyErr_CheckSignals())
Guido van Rossumb6775db1994-08-01 11:34:53 +0000730 return -1;
731 }
732#else /* !macintosh */
Guido van Rossum7bf22de1997-12-02 20:34:19 +0000733#if defined(__WATCOMC__) && !defined(__QNX__)
Guido van Rossumbceeac81996-05-23 22:53:47 +0000734 /* XXX Can't interrupt this sleep */
Guido van Rossum8607ae21997-11-03 22:04:46 +0000735 Py_BEGIN_ALLOW_THREADS
Guido van Rossumbceeac81996-05-23 22:53:47 +0000736 delay((int)(secs * 1000 + 0.5)); /* delay() uses milliseconds */
Guido van Rossum8607ae21997-11-03 22:04:46 +0000737 Py_END_ALLOW_THREADS
Guido van Rossum7bf22de1997-12-02 20:34:19 +0000738#else /* !__WATCOMC__ || __QNX__ */
Guido van Rossume22e6441993-07-09 10:51:31 +0000739#ifdef MSDOS
Guido van Rossumb6775db1994-08-01 11:34:53 +0000740 struct timeb t1, t2;
741 double frac;
Tim Petersdbd9ba62000-07-09 03:09:57 +0000742 extern double fmod(double, double);
743 extern double floor(double);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000744 if (secs <= 0.0)
745 return;
746 frac = fmod(secs, 1.0);
747 secs = floor(secs);
748 ftime(&t1);
749 t2.time = t1.time + (int)secs;
750 t2.millitm = t1.millitm + (int)(frac*1000.0);
751 while (t2.millitm >= 1000) {
752 t2.time++;
753 t2.millitm -= 1000;
754 }
755 for (;;) {
756#ifdef QUICKWIN
Guido van Rossum8607ae21997-11-03 22:04:46 +0000757 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb6775db1994-08-01 11:34:53 +0000758 _wyield();
Guido van Rossum8607ae21997-11-03 22:04:46 +0000759 Py_END_ALLOW_THREADS
Guido van Rossum80c9d881991-04-16 08:47:51 +0000760#endif
Barry Warsaw9a2a8a81996-12-06 23:32:14 +0000761 if (PyErr_CheckSignals())
Guido van Rossumb6775db1994-08-01 11:34:53 +0000762 return -1;
763 ftime(&t1);
764 if (t1.time > t2.time ||
765 t1.time == t2.time && t1.millitm >= t2.millitm)
766 break;
767 }
768#else /* !MSDOS */
Guido van Rossumb2fb3641996-09-07 00:47:35 +0000769#ifdef MS_WIN32
Fred Drake0e123952000-06-29 21:31:02 +0000770 {
771 double millisecs = secs * 1000.0;
772 if (millisecs > (double)ULONG_MAX) {
773 PyErr_SetString(PyExc_OverflowError, "sleep length is too large");
774 return -1;
775 }
776 /* XXX Can't interrupt this sleep */
777 Py_BEGIN_ALLOW_THREADS
778 Sleep((unsigned long)millisecs);
779 Py_END_ALLOW_THREADS
780 }
Guido van Rossumb2fb3641996-09-07 00:47:35 +0000781#else /* !MS_WIN32 */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000782#ifdef PYOS_OS2
783 /* This Sleep *IS* Interruptable by Exceptions */
Guido van Rossum1d0d7e41997-12-29 20:03:10 +0000784 Py_BEGIN_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000785 if (DosSleep(secs * 1000) != NO_ERROR) {
Guido van Rossum1d0d7e41997-12-29 20:03:10 +0000786 Py_BLOCK_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000787 PyErr_SetFromErrno(PyExc_IOError);
788 return -1;
789 }
Guido van Rossum1d0d7e41997-12-29 20:03:10 +0000790 Py_END_ALLOW_THREADS
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000791#else /* !PYOS_OS2 */
Guido van Rossumbcc20741998-08-04 22:53:56 +0000792#ifdef __BEOS__
793 /* This sleep *CAN BE* interrupted. */
794 {
Guido van Rossumbcc20741998-08-04 22:53:56 +0000795 if( secs <= 0.0 ) {
796 return;
797 }
Guido van Rossumd3eb5771999-03-09 16:07:23 +0000798
Guido van Rossumbcc20741998-08-04 22:53:56 +0000799 Py_BEGIN_ALLOW_THREADS
Guido van Rossumd3eb5771999-03-09 16:07:23 +0000800 /* BeOS snooze() is in microseconds... */
801 if( snooze( (bigtime_t)( secs * 1000.0 * 1000.0 ) ) == B_INTERRUPTED ) {
Guido van Rossumbcc20741998-08-04 22:53:56 +0000802 Py_BLOCK_THREADS
803 PyErr_SetFromErrno( PyExc_IOError );
804 return -1;
805 }
806 Py_END_ALLOW_THREADS
807 }
808#else /* !__BEOS__ */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000809 /* XXX Can't interrupt this sleep */
Guido van Rossum8607ae21997-11-03 22:04:46 +0000810 Py_BEGIN_ALLOW_THREADS
Guido van Rossumb6775db1994-08-01 11:34:53 +0000811 sleep((int)secs);
Guido van Rossum8607ae21997-11-03 22:04:46 +0000812 Py_END_ALLOW_THREADS
Guido van Rossumbcc20741998-08-04 22:53:56 +0000813#endif /* !__BEOS__ */
Guido van Rossum8e9ebfd1997-11-22 21:53:48 +0000814#endif /* !PYOS_OS2 */
Guido van Rossumb2fb3641996-09-07 00:47:35 +0000815#endif /* !MS_WIN32 */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000816#endif /* !MSDOS */
Guido van Rossum7bf22de1997-12-02 20:34:19 +0000817#endif /* !__WATCOMC__ || __QNX__ */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000818#endif /* !macintosh */
819#endif /* !HAVE_SELECT */
820 return 0;
Guido van Rossum80c9d881991-04-16 08:47:51 +0000821}