source: buchla-68k/orig/DATE/LCTIME.C

Last change on this file was 3ae31e9, checked in by Thomas Lopatic <thomas@…>, 7 years ago

Imported original source code.

  • Property mode set to 100755
File size: 9.1 KB
Line 
1/*
2 =============================================================================
3 lctime.c -- a Unix(tm)-like time and date package
4 Version 1 -- 1988-01-14 -- D.N. Lynx Crowe
5
6 These are similar in function to the Unix functions, but are
7 able to be used in re-entrant code.
8 =============================================================================
9*/
10
11#include "stddefs.h"
12#include "time.h"
13
14#define void int /* define to handle lack of 'void's */
15
16#define HASENV 0 /* non-zero if getenv() is available */
17
18#if HASENV
19extern char *getenv();
20#endif
21
22long timezn = 8*60*60; /* PST offset from GMT */
23int daylite = 1; /* daylight savings time = ON */
24char *ltzname[] = {"PST", "PDT"};
25
26/*
27 =============================================================================
28 These routines convert time as follows:
29
30 The epoch is 0000 Jan 1 1970 GMT.
31 The argument time is in seconds since then.
32
33 struct tm *
34 lcltime(tim, tmsp)
35 long *tim;
36 struct tm *tmsp;
37
38 returns a pointer to a filled in structure containing:
39
40 tm_sec seconds (0..59)
41 tm_min minutes (0..59)
42 tm_hour hours (0..23)
43 tm_mday day of month (1..31)
44 tm_mon month (0..11)
45 tm_year year - 1900
46 tm_wday weekday (0..6, Sun is 0)
47 tm_yday day of the year
48 tm_dst daylight savings time flag
49
50 The routine corrects for daylight savings time and will work in
51 any time zone provided "timezn" is adjusted to the difference
52 between Greenwich and local standard time (measured in seconds).
53
54 In places like Michigan "daylite" must be initialized to 0
55 to prevent the conversion to daylight time.
56
57 There is a table which accounts for the peculiarities
58 undergone by daylight savings time in 1974-1975.
59
60 The routine does not work in Saudi Arabia,
61 which runs on Solar time.
62
63 char *
64 latime(t, cbuf)
65 struct tm *t;
66 char *cbuf;
67
68 Where t is produced by lcltime(), and cbuf points to a
69 character string of at least 26 bytes.
70
71 Fills in a character string with the ascii time in the form:
72
73 Thu Jan 01 00:00:00 1970\n\0
74 012345678901234567890123
75 0 1 2
76
77 The string is terminated with a new-line and a zero byte.
78
79 struct tm *
80 lgmtime(tim, xtime)
81 long *tim;
82 struct tm *xtime;
83
84 Fills in a tm structure with GMT and returns a pointer to it.
85
86 char *
87 lctime(t, tmsp, cbuf)
88 long *t;
89 struct tm *tmsp;
90 char *cbuf;
91
92 Fills in a tm structure and a character string with the
93 current local time.
94
95 void
96 ltzset()
97
98 Looks for an environment variable named TZ.
99
100 It should be in the form "ESTn" or "ESTnEDT",
101 where "n" represents a string of digits with an optional
102 negative sign (for locations east of Greenwich, England).
103
104 If the variable is present, it will set the external
105 variables "timezn", "daylite", and "ltzname"
106 appropriately. It is called by lcltime(), and
107 may also be called explicitly by the user.
108 =============================================================================
109*/
110
111/*
112 */
113
114#define dysize(A) (((A) % 4) ? 365 : 366)
115
116static int xdmsize[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
117
118/*
119 Daylight savings time change table:
120
121 The following table is used for 1974 and 1975 and gives the day number
122 of the first day after the Sunday of the change.
123 */
124
125static struct {
126
127 int daylb;
128 int dayle;
129
130} daytab[] = {
131
132 5, 333, /* 1974: Jan 6 - last Sun. in Nov */
133 58, 303, /* 1975: Last Sun. in Feb - last Sun in Oct */
134};
135
136/*
137 */
138
139/*
140 =============================================================================
141 ct_numb(cp, n) -- convert n to a 2 character string at cp (RJBF)
142 =============================================================================
143*/
144
145static char *
146ct_numb(cp, n)
147register char *cp;
148int n;
149{
150 cp++;
151
152 if (n GE 10)
153 *cp++ = (n / 10) % 10 + '0';
154 else
155 *cp++ = ' ';
156
157 *cp++ = n % 10 + '0';
158
159 return(cp);
160}
161
162/*
163 */
164
165/*
166 =============================================================================
167 sunday(t, d)
168
169 The argument d is a 0-origin day number.
170 The value is the day number of the first Sunday on or after the day.
171 =============================================================================
172*/
173
174static
175int
176sunday(t, d)
177register struct tm *t;
178register int d;
179{
180 if (d GE 58)
181 d += dysize(t->tm_year) - 365;
182
183 return(d - (d - t->tm_yday + t->tm_wday + 700) % 7);
184}
185
186/*
187 */
188
189/*
190 =============================================================================
191 ltzset() -- set time variables based on TZ environment variable
192 =============================================================================
193*/
194
195void
196ltzset()
197{
198 register char *p, *q;
199 register int n;
200 int sign;
201
202#if HASENV
203
204 if ((p = getenv("TZ")) AND *p) {
205
206 n = 3;
207 q = ltzname[0];
208
209 do {
210
211 *q++ = *p ? *p++ : ' ';
212
213 } while (--n);
214
215 if (sign = *p EQ '-')
216 p++;
217
218 n = 0;
219
220 while (*p GE '0' AND *p LE '9')
221 n = (n * 10) + *p++ - '0';
222
223 if (sign)
224 n = -n;
225
226 timezn = ((long)(n * 60)) * 60;
227
228 if (daylite = *p NE '\0') {
229
230 q = ltzname[1];
231 n = 3;
232
233 do {
234
235 *q++ = *p ? *p++ : ' ';
236
237 } while (--n);
238 }
239 }
240
241#endif
242}
243
244/*
245 */
246
247/*
248 =============================================================================
249 lgmtime(tim, xtime) -- get Greenwich Mean Time from system time
250 =============================================================================
251*/
252
253struct tm *
254lgmtime(tim, xtime)
255register long *tim;
256register struct tm *xtime;
257{
258 register int d0, d1, i;
259 register long hms, day;
260 int dmsize[12];
261
262 /* break initial number into days */
263
264 hms = *tim % 86400L;
265 day = *tim / 86400L;
266
267 if (hms < 0) {
268
269 hms += 86400L;
270 day -= 1;
271 }
272
273 /* generate hours:minutes:seconds */
274
275 xtime->tm_sec = hms % 60;
276 d1 = hms / 60;
277 xtime->tm_min = d1 % 60;
278 d1 /= 60;
279 xtime->tm_hour = d1;
280
281 /*
282 day is the day number.
283 generate day of the week.
284 The addend is 4 mod 7 (1/1/1970 was Thursday)
285 */
286
287 xtime->tm_wday = (day + 7340036L) % 7;
288
289 /* year number */
290
291 if (day GE 0)
292 for (d1 = 70; day GE dysize(d1); d1++)
293 day -= dysize(d1);
294 else
295 for (d1 = 70; day < 0; d1--)
296 day += dysize(d1 - 1);
297
298 xtime->tm_year = d1;
299 xtime->tm_yday = d0 = day;
300
301 /* generate month */
302
303 for (i = 0; i < 12; i++)
304 xdmsize[i] = dmsize[i];
305
306 if (dysize(d1) EQ 366)
307 xdmsize[1] = 29;
308 else
309 xdmsize[1] = 28;
310
311 for (d1 = 0; d0 GE xdmsize[d1]; d1++)
312 d0 -= xdmsize[d1];
313
314 xtime->tm_mday = d0+1;
315 xtime->tm_mon = d1;
316 xtime->tm_dst = 0;
317
318 return(xtime);
319}
320
321/*
322 */
323
324/*
325 =============================================================================
326 lcltime(tim, tmsp) -- get local time from system time
327 =============================================================================
328*/
329
330struct tm *
331lcltime(tim, tmsp)
332long *tim;
333struct tm *tmsp;
334{
335 register int dayno, daylbgn, daylend;
336 int daylbtm, dayletm;
337 register struct tm *ct;
338 long copyt;
339
340 ltzset();
341 copyt = *tim - timezn;
342 ct = lgmtime(&copyt, tmsp);
343
344 dayno = ct->tm_yday;
345
346 daylbgn = 119; /* Last Sun in Apr */
347 daylend = 303; /* Last Sun in Oct */
348 daylbtm = 2; /* 02:00 */
349 dayletm = 1; /* 01:00 */
350
351 if (ct->tm_year EQ 74 OR ct->tm_year EQ 75) {
352
353 daylbgn = daytab[ct->tm_year-74].daylb;
354 daylend = daytab[ct->tm_year-74].dayle;
355 }
356
357 if (ct->tm_year EQ 88) {
358
359 /* NOTE: this will need to accomodate the change
360 to the first sunday in Apr in 1988 */
361
362 dayletm = 2;
363 }
364
365 daylbgn = sunday(ct, daylbgn);
366 daylend = sunday(ct, daylend);
367
368 if (daylite AND
369 (dayno > daylbgn OR (dayno EQ daylbgn AND ct->tm_hour GE daylbtm)) AND
370 (dayno < daylend OR (dayno EQ daylend AND ct->tm_hour < dayletm))) {
371
372 copyt += 1 * 60 * 60;
373 ct = lgmtime(&copyt, tmsp);
374 ct->tm_dst++;
375 }
376
377 return(ct);
378}
379
380/*
381 */
382
383/*
384 =============================================================================
385 latime(t, cbuf) -- convert a tm structure to an ASCII string
386 =============================================================================
387*/
388
389char *
390latime(t, cbuf)
391struct tm *t;
392char *cbuf;
393{
394 register char *cp, *ncp;
395 register int *tp;
396
397 cp = cbuf;
398
399 for (ncp = "Day Mon 00 00:00:00 1900\n"; *cp++ = *ncp++; );
400
401 ncp = &"SunMonTueWedThuFriSat"[3 * t->tm_wday];
402 cp = cbuf;
403 *cp++ = *ncp++;
404 *cp++ = *ncp++;
405 *cp++ = *ncp++;
406 cp++;
407 tp = &t->tm_mon;
408 ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(*tp) * 3];
409 *cp++ = *ncp++;
410 *cp++ = *ncp++;
411 *cp++ = *ncp++;
412 cp = ct_numb(cp, *--tp);
413 cp = ct_numb(cp, *--tp + 100);
414 cp = ct_numb(cp, *--tp + 100);
415 cp = ct_numb(cp, *--tp + 100);
416
417 if (t->tm_year GE 100) {
418
419 cp[1] = '2';
420 cp[2] = '0';
421 }
422
423 cp += 2;
424 cp = ct_numb(cp, t->tm_year + 100);
425
426 return(cbuf);
427}
428
429/*
430 */
431
432/*
433 =============================================================================
434 lctime() -- get the current time as a tm structure and an ASCII string
435 =============================================================================
436*/
437
438char *
439lctime(t, tmsp, cbuf)
440long *t;
441struct tm *tmsp;
442char *cbuf;
443{
444 return(latime(lcltime(t, tmsp), cbuf));
445}
Note: See TracBrowser for help on using the repository browser.