source: buchla-68k/orig/DATE/CTIME.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: 7.5 KB
Line 
1/*
2 =============================================================================
3 ctime.c -- time and date support ala' Unix
4 Version 3 -- 1989-01-13 -- D.N. Lynx Crowe
5 =============================================================================
6*/
7
8#define HAS_ENV 0 /* define non-zero if getenv() exists */
9
10/*
11 * This routine converts time as follows.
12 * The epoch is 0000 Jan 1 1970 GMT.
13 * The argument time is in seconds since then.
14 * The localtime(t) entry returns a pointer to an array containing:
15 *
16 * seconds (0-59)
17 * minutes (0-59)
18 * hours (0-23)
19 * day of month (1-31)
20 * month (0-11)
21 * year-1900
22 * weekday (0-6, Sun is 0)
23 * day of the year
24 * daylight savings flag
25 *
26 * The routine corrects for daylight savings time and will work in any
27 * time zone provided that "timezone" is adjusted to the difference between
28 * Greenwich and local standard time (measured in seconds).
29 *
30 * In places like Michigan "daylight" must be initialized to 0 to prevent
31 * the conversion to daylight savings time.
32 *
33 * There is a table which accounts for the peculiarities undergone by
34 * daylight savings time in 1974-1975.
35 *
36 * This routine does not work for Saudi Arabia, which runs on Solar time.
37 *
38 * asctime(tvec)
39 *
40 * where tvec is produced by localtime()
41 *
42 * Returns a ptr to a character string that has the ascii time in the form:
43 *
44 * Thu Jan 01 00:00:00 1970n0\\
45 * 01234567890123456789012345
46 * 0 1 2
47 *
48 * ctime(t)
49 *
50 * Just calls localtime(), then asctime()
51 *
52 * tzset()
53 *
54 * Looks for an environment variable named TZ.
55 *
56 * It should be in the form "ESTn" or "ESTnEDT",
57 * where "n" represents a string of digits with an optional
58 * negative sign (for locations east of Greenwich, England).
59 *
60 * If the variable is present, it will set the external
61 * variables "timezone", "daylight", and "tzname"
62 * appropriately. It is called by localtime, and
63 * may also be called explicitly by the user.
64 */
65
66/*
67 */
68
69#define dysize(A) (((A)%4)? 365: 366)
70
71#define void int
72
73#include "time.h"
74
75long timezone = 8*60*60;
76int daylight = 0;
77char *tzname[] = {"PST", "PDT"};
78
79struct tm *gmtime(), *localtime();
80char *ctime(), *asctime();
81void tzset();
82
83static char cbuf[26];
84static int dmsize[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
85
86/*
87 * The following table is used for 1974 and 1975 and
88 * gives the day number of the first day after the Sunday of the
89 * change.
90 */
91
92static struct {
93
94 int daylb;
95 int dayle;
96
97} daytab[] = {
98
99 5, 333, /* 1974: Jan 6 - last Sun. in Nov */
100 58, 303, /* 1975: Last Sun. in Feb - last Sun in Oct */
101};
102
103/*
104 */
105
106/*
107 =============================================================================
108 ctime(t)
109 =============================================================================
110*/
111
112char *
113ctime(t)
114long *t;
115{
116 return(asctime(localtime(t)));
117}
118
119/*
120 */
121
122/*
123 =============================================================================
124 localtime(tim)
125 =============================================================================
126*/
127
128struct tm *
129localtime(tim)
130long *tim;
131{
132 register int dayno, daylbegin, daylend;
133 register struct tm *ct;
134 long copyt;
135
136 tzset();
137 copyt = *tim - timezone;
138 ct = gmtime(&copyt);
139 dayno = ct->tm_yday;
140 daylbegin = 119; /* last Sun in Apr */
141 daylend = 303; /* Last Sun in Oct */
142
143 if(ct->tm_year == 74 || ct->tm_year == 75) {
144
145 daylbegin = daytab[ct->tm_year-74].daylb;
146 daylend = daytab[ct->tm_year-74].dayle;
147 }
148
149 daylbegin = sunday(ct, daylbegin);
150 daylend = sunday(ct, daylend);
151
152 if(daylight &&
153 (dayno>daylbegin || (dayno==daylbegin && ct->tm_hour>=2)) &&
154 (dayno<daylend || (dayno==daylend && ct->tm_hour<1))) {
155
156 copyt += 1*60*60;
157 ct = gmtime(&copyt);
158 ct->tm_isdst++;
159 }
160
161 return(ct);
162}
163
164/*
165 */
166
167/*
168 =============================================================================
169 sunday(t,d)
170
171 The argument is a 0-origin day number.
172 The value is the day number of the first
173 Sunday on or after the day.
174 =============================================================================
175 */
176
177static int
178sunday(t, d)
179register struct tm *t;
180register int d;
181{
182 if(d >= 58)
183 d += dysize(t->tm_year) - 365;
184
185 return(d - (d - t->tm_yday + t->tm_wday + 700) % 7);
186}
187
188/*
189 */
190
191/*
192 =============================================================================
193 gmtime(tim)
194 =============================================================================
195*/
196
197struct tm *
198gmtime(tim)
199long *tim;
200{
201 register int d0, d1;
202 long hms, day;
203 static struct tm xtime;
204
205 /*
206 * break initial number into days
207 */
208
209 hms = *tim % 86400L;
210 day = *tim / 86400L;
211
212 if(hms < 0) {
213 hms += 86400L;
214 day -= 1;
215 }
216
217 /*
218 * generate hours:minutes:seconds
219 */
220
221 xtime.tm_sec = hms % 60;
222 d1 = hms / 60;
223 xtime.tm_min = d1 % 60;
224 d1 /= 60;
225 xtime.tm_hour = d1;
226
227 /*
228 * day is the day number.
229 * generate day of the week.
230 * The addend is 4 mod 7 (1/1/1970 was Thursday)
231 */
232
233 xtime.tm_wday = (day + 7340036L) % 7;
234
235 /*
236 * year number
237 */
238
239 if(day >= 0)
240 for(d1=70; day >= dysize(d1); d1++)
241 day -= dysize(d1);
242 else
243 for(d1=70; day < 0; d1--)
244 day += dysize(d1-1);
245
246 xtime.tm_year = d1;
247 xtime.tm_yday = d0 = day;
248
249 /*
250 * generate month
251 */
252
253 if(dysize(d1) == 366)
254 dmsize[1] = 29;
255
256 for(d1=0; d0 >= dmsize[d1]; d1++)
257 d0 -= dmsize[d1];
258
259 dmsize[1] = 28;
260 xtime.tm_mday = d0+1;
261 xtime.tm_mon = d1;
262 xtime.tm_isdst = 0;
263 return(&xtime);
264}
265
266/*
267 */
268
269/*
270 =============================================================================
271 asctime(t)
272 =============================================================================
273*/
274
275char *
276asctime(t)
277struct tm *t;
278{
279 register char *cp, *ncp;
280 register int *tp;
281 char *ct_numb();
282
283 cp = cbuf;
284
285 for(ncp = "Day Mon 00 00:00:00 1900\n"; *cp++ = *ncp++; );
286
287 ncp = &"SunMonTueWedThuFriSat"[3*t->tm_wday];
288 cp = cbuf;
289 *cp++ = *ncp++;
290 *cp++ = *ncp++;
291 *cp++ = *ncp++;
292 cp++;
293 tp = &t->tm_mon;
294 ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(*tp)*3];
295 *cp++ = *ncp++;
296 *cp++ = *ncp++;
297 *cp++ = *ncp++;
298 cp = ct_numb(cp, *--tp);
299 cp = ct_numb(cp, *--tp+100);
300 cp = ct_numb(cp, *--tp+100);
301 cp = ct_numb(cp, *--tp+100);
302
303 if(t->tm_year >= 100) {
304 cp[1] = '2';
305 cp[2] = '0';
306 }
307
308 cp += 2;
309 cp = ct_numb(cp, t->tm_year+100);
310 return(cbuf);
311}
312
313/*
314 */
315
316/*
317 =============================================================================
318 ct_numb(cp,n)
319 =============================================================================
320*/
321
322static char *
323ct_numb(cp, n)
324register char *cp;
325int n;
326{
327 cp++;
328
329 if(n >= 10)
330 *cp++ = (n/10)%10 + '0';
331 else
332 *cp++ = ' ';
333
334 *cp++ = n%10 + '0';
335 return(cp);
336}
337
338/*
339 */
340
341/*
342 =============================================================================
343 tzset()
344 =============================================================================
345*/
346
347void
348tzset()
349{
350#if HAS_ENV
351 register char *p, *q;
352 register int n;
353 int sign;
354 char *getenv();
355
356 if((p = getenv ("TZ")) && *p) {
357
358 n = 3;
359 q = tzname[0];
360
361 do {
362
363 *q++ = *p? *p++: ' ';
364
365 } while(--n);
366
367 if(sign = *p == '-')
368 p++;
369
370 n = 0;
371
372 while(*p >= '0' && *p <= '9')
373 n = (n * 10) + *p++ - '0';
374
375 if(sign)
376 n = -n;
377
378 timezone = ((long)(n * 60)) * 60;
379
380 if(daylight = *p != '\0') {
381
382 q = tzname[1];
383 n = 3;
384
385 do {
386
387 *q++ = *p? *p++: ' ';
388
389 } while(--n);
390 }
391 }
392#endif
393}
Note: See TracBrowser for help on using the repository browser.