OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [insight/] [tcl/] [win/] [tclWinTime.c] - Blame information for rev 1774

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 578 markom
/*
2
 * tclWinTime.c --
3
 *
4
 *      Contains Windows specific versions of Tcl functions that
5
 *      obtain time values from the operating system.
6
 *
7
 * Copyright 1995 by Sun Microsystems, Inc.
8
 *
9
 * See the file "license.terms" for information on usage and redistribution
10
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
11
 *
12
 * RCS: @(#) $Id: tclWinTime.c,v 1.1.1.1 2002-01-16 10:25:39 markom Exp $
13
 */
14
 
15
#include "tclInt.h"
16
#include "tclPort.h"
17
 
18
#define SECSPERDAY (60L * 60L * 24L)
19
#define SECSPERYEAR (SECSPERDAY * 365L)
20
#define SECSPER4YEAR (SECSPERYEAR * 4L + SECSPERDAY)
21
 
22
/*
23
 * The following arrays contain the day of year for the last day of
24
 * each month, where index 1 is January.
25
 */
26
 
27
static int normalDays[] = {
28
    -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364
29
};
30
 
31
static int leapDays[] = {
32
    -1, 30, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365
33
};
34
 
35
/*
36
 * Declarations for functions defined later in this file.
37
 */
38
 
39
static struct tm *      ComputeGMT _ANSI_ARGS_((const time_t *tp));
40
 
41
/*
42
 *----------------------------------------------------------------------
43
 *
44
 * TclpGetSeconds --
45
 *
46
 *      This procedure returns the number of seconds from the epoch.
47
 *      On most Unix systems the epoch is Midnight Jan 1, 1970 GMT.
48
 *
49
 * Results:
50
 *      Number of seconds from the epoch.
51
 *
52
 * Side effects:
53
 *      None.
54
 *
55
 *----------------------------------------------------------------------
56
 */
57
 
58
unsigned long
59
TclpGetSeconds()
60
{
61
    return (unsigned long) time((time_t *) NULL);
62
}
63
 
64
/*
65
 *----------------------------------------------------------------------
66
 *
67
 * TclpGetClicks --
68
 *
69
 *      This procedure returns a value that represents the highest
70
 *      resolution clock available on the system.  There are no
71
 *      guarantees on what the resolution will be.  In Tcl we will
72
 *      call this value a "click".  The start time is also system
73
 *      dependant.
74
 *
75
 * Results:
76
 *      Number of clicks from some start time.
77
 *
78
 * Side effects:
79
 *      None.
80
 *
81
 *----------------------------------------------------------------------
82
 */
83
 
84
unsigned long
85
TclpGetClicks()
86
{
87
    return GetTickCount();
88
}
89
 
90
/*
91
 *----------------------------------------------------------------------
92
 *
93
 * TclpGetTimeZone --
94
 *
95
 *      Determines the current timezone.  The method varies wildly
96
 *      between different Platform implementations, so its hidden in
97
 *      this function.
98
 *
99
 * Results:
100
 *      Minutes west of GMT.
101
 *
102
 * Side effects:
103
 *      None.
104
 *
105
 *----------------------------------------------------------------------
106
 */
107
 
108
int
109
TclpGetTimeZone (currentTime)
110
    unsigned long  currentTime;
111
{
112
    int timeZone;
113
 
114
    tzset();
115
    timeZone = _timezone / 60;
116
 
117
    return timeZone;
118
}
119
 
120
/*
121
 *----------------------------------------------------------------------
122
 *
123
 * TclpGetTime --
124
 *
125
 *      Gets the current system time in seconds and microseconds
126
 *      since the beginning of the epoch: 00:00 UCT, January 1, 1970.
127
 *
128
 * Results:
129
 *      Returns the current time in timePtr.
130
 *
131
 * Side effects:
132
 *      None.
133
 *
134
 *----------------------------------------------------------------------
135
 */
136
 
137
void
138
TclpGetTime(timePtr)
139
    Tcl_Time *timePtr;          /* Location to store time information. */
140
{
141
    struct timeb t;
142
 
143
    ftime(&t);
144
    timePtr->sec = t.time;
145
    timePtr->usec = t.millitm * 1000;
146
}
147
 
148
/*
149
 *----------------------------------------------------------------------
150
 *
151
 * TclpGetTZName --
152
 *
153
 *      Gets the current timezone string.
154
 *
155
 * Results:
156
 *      Returns a pointer to a static string, or NULL on failure.
157
 *
158
 * Side effects:
159
 *      None.
160
 *
161
 *----------------------------------------------------------------------
162
 */
163
 
164
char *
165
TclpGetTZName()
166
{
167
    tzset();
168
    if (_daylight && _tzname[1] != NULL) {
169
        return _tzname[1];
170
    } else {
171
        return _tzname[0];
172
    }
173
}
174
 
175
/*
176
 *----------------------------------------------------------------------
177
 *
178
 * TclpGetDate --
179
 *
180
 *      This function converts between seconds and struct tm.  If
181
 *      useGMT is true, then the returned date will be in Greenwich
182
 *      Mean Time (GMT).  Otherwise, it will be in the local time zone.
183
 *
184
 * Results:
185
 *      Returns a static tm structure.
186
 *
187
 * Side effects:
188
 *      None.
189
 *
190
 *----------------------------------------------------------------------
191
 */
192
 
193
struct tm *
194
TclpGetDate(tp, useGMT)
195
    const time_t *tp;
196
    int useGMT;
197
{
198
    struct tm *tmPtr;
199
    long time;
200
 
201
    if (!useGMT) {
202
        tzset();
203
 
204
        /*
205
         * If we are in the valid range, let the C run-time library
206
         * handle it.  Otherwise we need to fake it.  Note that this
207
         * algorithm ignores daylight savings time before the epoch.
208
         */
209
 
210
        time = *tp - _timezone;
211
        if (time >= 0) {
212
            return localtime(tp);
213
        }
214
 
215
        /*
216
         * If we aren't near to overflowing the long, just add the bias and
217
         * use the normal calculation.  Otherwise we will need to adjust
218
         * the result at the end.
219
         */
220
 
221
        if (*tp < (LONG_MAX - 2 * SECSPERDAY)
222
                && *tp > (LONG_MIN + 2 * SECSPERDAY)) {
223
            tmPtr = ComputeGMT(&time);
224
        } else {
225
            tmPtr = ComputeGMT(tp);
226
 
227
            tzset();
228
 
229
            /*
230
             * Add the bias directly to the tm structure to avoid overflow.
231
             * Propagate seconds overflow into minutes, hours and days.
232
             */
233
 
234
            time = tmPtr->tm_sec - _timezone;
235
            tmPtr->tm_sec = (int)(time % 60);
236
            if (tmPtr->tm_sec < 0) {
237
                tmPtr->tm_sec += 60;
238
                time -= 60;
239
            }
240
 
241
            time = tmPtr->tm_min + time/60;
242
            tmPtr->tm_min = (int)(time % 60);
243
            if (tmPtr->tm_min < 0) {
244
                tmPtr->tm_min += 60;
245
                time -= 60;
246
            }
247
 
248
            time = tmPtr->tm_hour + time/60;
249
            tmPtr->tm_hour = (int)(time % 24);
250
            if (tmPtr->tm_hour < 0) {
251
                tmPtr->tm_hour += 24;
252
                time -= 24;
253
            }
254
 
255
            time /= 24;
256
            tmPtr->tm_mday += time;
257
            tmPtr->tm_yday += time;
258
            tmPtr->tm_wday = (tmPtr->tm_wday + time) % 7;
259
        }
260
    } else {
261
        tmPtr = ComputeGMT(tp);
262
    }
263
    return tmPtr;
264
}
265
 
266
/*
267
 *----------------------------------------------------------------------
268
 *
269
 * ComputeGMT --
270
 *
271
 *      This function computes GMT given the number of seconds since
272
 *      the epoch (midnight Jan 1 1970).
273
 *
274
 * Results:
275
 *      Returns a statically allocated struct tm.
276
 *
277
 * Side effects:
278
 *      Updates the values of the static struct tm.
279
 *
280
 *----------------------------------------------------------------------
281
 */
282
 
283
static struct tm *
284
ComputeGMT(tp)
285
    const time_t *tp;
286
{
287
    static struct tm tm;          /* This should be allocated per thread.*/
288
    long tmp, rem;
289
    int isLeap;
290
    int *days;
291
 
292
    /*
293
     * Compute the 4 year span containing the specified time.
294
     */
295
 
296
    tmp = *tp / SECSPER4YEAR;
297
    rem = *tp % SECSPER4YEAR;
298
 
299
    /*
300
     * Correct for weird mod semantics so the remainder is always positive.
301
     */
302
 
303
    if (rem < 0) {
304
        tmp--;
305
        rem += SECSPER4YEAR;
306
    }
307
 
308
    /*
309
     * Compute the year after 1900 by taking the 4 year span and adjusting
310
     * for the remainder.  This works because 2000 is a leap year, and
311
     * 1900/2100 are out of the range.
312
     */
313
 
314
    tmp = (tmp * 4) + 70;
315
    isLeap = 0;
316
    if (rem >= SECSPERYEAR) {                     /* 1971, etc. */
317
        tmp++;
318
        rem -= SECSPERYEAR;
319
        if (rem >= SECSPERYEAR) {                 /* 1972, etc. */
320
            tmp++;
321
            rem -= SECSPERYEAR;
322
            if (rem >= SECSPERYEAR + SECSPERDAY) { /* 1973, etc. */
323
                tmp++;
324
                rem -= SECSPERYEAR + SECSPERDAY;
325
            } else {
326
                isLeap = 1;
327
            }
328
        }
329
    }
330
    tm.tm_year = tmp;
331
 
332
    /*
333
     * Compute the day of year and leave the seconds in the current day in
334
     * the remainder.
335
     */
336
 
337
    tm.tm_yday = rem / SECSPERDAY;
338
    rem %= SECSPERDAY;
339
 
340
    /*
341
     * Compute the time of day.
342
     */
343
 
344
    tm.tm_hour = rem / 3600;
345
    rem %= 3600;
346
    tm.tm_min = rem / 60;
347
    tm.tm_sec = rem % 60;
348
 
349
    /*
350
     * Compute the month and day of month.
351
     */
352
 
353
    days = (isLeap) ? leapDays : normalDays;
354
    for (tmp = 1; days[tmp] < tm.tm_yday; tmp++) {
355
    }
356
    tm.tm_mon = --tmp;
357
    tm.tm_mday = tm.tm_yday - days[tmp];
358
 
359
    /*
360
     * Compute day of week.  Epoch started on a Thursday.
361
     */
362
 
363
    tm.tm_wday = (*tp / SECSPERDAY) + 4;
364
    if ((*tp % SECSPERDAY) < 0) {
365
        tm.tm_wday--;
366
    }
367
    tm.tm_wday %= 7;
368
    if (tm.tm_wday < 0) {
369
        tm.tm_wday += 7;
370
    }
371
 
372
    return &tm;
373
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.