]> diplodocus.org Git - nmh/blob - docs/historical/mh-6.8.5/zotnet/tws/dtime.c
sbr/mts.c: Delete mmdlm2; use same-valued mmdlm1 instead.
[nmh] / docs / historical / mh-6.8.5 / zotnet / tws / dtime.c
1 /* dtime.c - routines to do ``ARPA-style'' time structures */
2 #ifndef lint
3 static char ident[] = "@(#)$Id: dtime.c,v 1.15 1992/12/15 00:20:22 jromine Exp $";
4 #endif /* lint */
5
6 /* LINTLIBRARY */
7
8
9 #include "tws.h"
10 #ifndef INETONLY
11 #include "../h/strings.h"
12 #else /* INETONLY */
13 #include "strings.h"
14 #endif /* INETONLY */
15 #include <stdio.h>
16 #include <sys/types.h>
17 #if !defined(SYS5) && !defined(ZONEINFO)
18 #include <sys/timeb.h>
19 #endif /* !defined(SYS5) && !defined(ZONEINFO) */
20 #ifdef _AIX
21 #include <sys/time.h>
22 #include <time.h>
23 #else
24 #ifdef BSD42
25 #include <sys/time.h>
26 #else /* BSD42 */
27 #include <time.h>
28 #endif /* BSD42 */
29 #endif
30
31 #ifdef SYS5
32 extern int daylight;
33 extern long timezone;
34 extern char *tzname[];
35 #endif /* SYS5 */
36
37 /* \f */
38
39 #ifndef abs
40 #define abs(a) (a >= 0 ? a : -a)
41 #endif
42
43 #define dysize(y) \
44 (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366)))
45
46 /* \f */
47
48 char *tw_moty[] = {
49 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
50 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL
51 };
52
53 char *tw_dotw[] = {
54 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL
55 };
56
57 char *tw_ldotw[] = {
58 "Sunday", "Monday", "Tuesday", "Wednesday",
59 "Thursday", "Friday", "Saturday", NULL
60 };
61
62 /* \f */
63
64 static struct zone {
65 char *std,
66 *dst;
67 int shift;
68 } zones[] = {
69 "GMT", "BST", 0,
70 "EST", "EDT", -5,
71 "CST", "CDT", -6,
72 "MST", "MDT", -7,
73 "PST", "PDT", -8,
74 #ifdef notdef /* RFC1123 specifies do not use military TZs */
75 "A", NULL, -1,
76 "B", NULL, -2,
77 "C", NULL, -3,
78 "D", NULL, -4,
79 "E", NULL, -5,
80 "F", NULL, -6,
81 "G", NULL, -7,
82 "H", NULL, -8,
83 "I", NULL, -9,
84 "K", NULL, -10,
85 "L", NULL, -11,
86 "M", NULL, -12,
87 "N", NULL, 1,
88 #ifndef HUJI
89 "O", NULL, 2,
90 #else /* HUJI */
91 "JST", "JDT", 2,
92 #endif /* HUJI */
93 "P", NULL, 3,
94 "Q", NULL, 4,
95 "R", NULL, 5,
96 "S", NULL, 6,
97 "T", NULL, 7,
98 "U", NULL, 8,
99 "V", NULL, 9,
100 "W", NULL, 10,
101 "X", NULL, 11,
102 "Y", NULL, 12,
103 #endif /* notdef */
104
105 NULL
106 };
107
108 #define CENTURY 1900
109
110 long time ();
111 struct tm *localtime ();
112
113 /* \f */
114
115 char *dtimenow () {
116 long clock;
117
118 (void) time (&clock);
119 return dtime (&clock);
120 }
121
122
123 char *dctime (tw)
124 register struct tws *tw;
125 {
126 static char buffer[25];
127
128 if (!tw)
129 return NULL;
130
131 (void) sprintf (buffer, "%.3s %.3s %02d %02d:%02d:%02d %.4d\n",
132 tw_dotw[tw -> tw_wday], tw_moty[tw -> tw_mon], tw -> tw_mday,
133 tw -> tw_hour, tw -> tw_min, tw -> tw_sec,
134 tw -> tw_year >= 100 ? tw -> tw_year : CENTURY + tw -> tw_year);
135
136 return buffer;
137 }
138
139 /* \f */
140
141 struct tws *dtwstime () {
142 long clock;
143
144 (void) time (&clock);
145 return dlocaltime (&clock);
146 }
147
148
149 struct tws *dlocaltime (clock)
150 register long *clock;
151 {
152 register struct tm *tm;
153 #if !defined(SYS5) && !defined(ZONEINFO)
154 struct timeb tb;
155 #endif /* !defined(SYS5) && !defined(ZONEINFO) */
156 static struct tws tw;
157
158 if (!clock)
159 return NULL;
160 tw.tw_flags = TW_NULL;
161
162 tm = localtime (clock);
163 tw.tw_sec = tm -> tm_sec;
164 tw.tw_min = tm -> tm_min;
165 tw.tw_hour = tm -> tm_hour;
166 tw.tw_mday = tm -> tm_mday;
167 tw.tw_mon = tm -> tm_mon;
168 tw.tw_year = tm -> tm_year + CENTURY;
169 tw.tw_wday = tm -> tm_wday;
170 tw.tw_yday = tm -> tm_yday;
171 if (tm -> tm_isdst)
172 tw.tw_flags |= TW_DST;
173 #if defined(SYS5)
174 tzset ();
175 tw.tw_zone = -(timezone / 60);
176 #else /* defined(SYS5) */
177 #if defined(ZONEINFO)
178 tw.tw_zone = tm->tm_gmtoff / 60;
179 if (tm -> tm_isdst) /* if DST is in effect */
180 tw.tw_zone -= 60; /* reset to normal offset */
181 #else /* defined(ZONEINFO) */
182 ftime (&tb);
183 tw.tw_zone = -tb.timezone;
184 #endif /* defined(ZONEINFO) */
185 #endif /* defined(SYS5) */
186 tw.tw_flags &= ~TW_SDAY, tw.tw_flags |= TW_SEXP;
187 tw.tw_flags &= ~TW_SZONE, tw.tw_flags |= TW_SZEXP;
188 tw.tw_clock = *clock;
189
190 return (&tw);
191 }
192
193
194 struct tws *dgmtime (clock)
195 register long *clock;
196 {
197 register struct tm *tm;
198 static struct tws tw;
199
200 if (!clock)
201 return NULL;
202 tw.tw_flags = TW_NULL;
203
204 tm = gmtime (clock);
205 tw.tw_sec = tm -> tm_sec;
206 tw.tw_min = tm -> tm_min;
207 tw.tw_hour = tm -> tm_hour;
208 tw.tw_mday = tm -> tm_mday;
209 tw.tw_mon = tm -> tm_mon;
210 tw.tw_year = tm -> tm_year + CENTURY;
211 tw.tw_wday = tm -> tm_wday;
212 tw.tw_yday = tm -> tm_yday;
213 if (tm -> tm_isdst)
214 tw.tw_flags |= TW_DST;
215 tw.tw_zone = 0;
216 tw.tw_flags &= ~TW_SDAY, tw.tw_flags |= TW_SEXP;
217 tw.tw_flags &= ~TW_SZONE, tw.tw_flags |= TW_SZEXP;
218 tw.tw_clock = *clock;
219
220 return (&tw);
221 }
222
223 /* \f */
224
225 char *dasctime (tw, flags)
226 register struct tws *tw;
227 int flags;
228 {
229 char buffer[80];
230 static char result[80];
231
232 if (!tw)
233 return NULL;
234
235 /* Display timezone if known */
236 if ((tw->tw_flags & TW_SZONE) == TW_SZNIL)
237 result[0] = '\0';
238 else
239 (void) sprintf(result, " %s",
240 dtimezone(tw -> tw_zone, tw->tw_flags | flags));
241 (void) sprintf(buffer, "%02d %s %0*d %02d:%02d:%02d%s",
242 tw->tw_mday, tw_moty[tw->tw_mon],
243 tw -> tw_year < 100 ? 2 : 4, tw -> tw_year,
244 tw->tw_hour, tw->tw_min, tw->tw_sec, result);
245
246 if ((tw -> tw_flags & TW_SDAY) == TW_SEXP)
247 (void) sprintf (result, "%s, %s", tw_dotw[tw -> tw_wday], buffer);
248 else
249 if ((tw -> tw_flags & TW_SDAY) == TW_SNIL)
250 (void) strcpy (result, buffer);
251 else
252 (void) sprintf (result, "%s (%s)", buffer, tw_dotw[tw -> tw_wday]);
253
254 return result;
255 }
256
257 /* \f */
258
259 char *dtimezone (offset, flags)
260 register int offset,
261 flags;
262 {
263 register int hours,
264 mins;
265 register struct zone *z;
266 static char buffer[10];
267
268 if (offset < 0) {
269 mins = -((-offset) % 60);
270 hours = -((-offset) / 60);
271 }
272 else {
273 mins = offset % 60;
274 hours = offset / 60;
275 }
276
277 if (!(flags & TW_ZONE) && mins == 0)
278 #if defined(SYS5) && defined(TZNAME)
279 {
280 tzset();
281 return ((flags & TW_DST) ? tzname[1] : tzname[0]);
282 }
283 #else
284 for (z = zones; z -> std; z++)
285 if (z -> shift == hours)
286 return (z -> dst && (flags & TW_DST) ? z -> dst : z -> std);
287 #endif
288
289 #if defined(DSTXXX)
290 if (flags & TW_DST)
291 hours += 1;
292 #endif /* defined(DSTXXX) */
293 (void) sprintf (buffer, "%s%02d%02d",
294 offset < 0 ? "-" : "+", abs (hours), abs (mins));
295 return buffer;
296 }
297
298 /* \f */
299
300 void twscopy (tb, tw)
301 register struct tws *tb,
302 *tw;
303 {
304 #ifdef notdef
305 tb -> tw_sec = tw -> tw_sec;
306 tb -> tw_min = tw -> tw_min;
307 tb -> tw_hour = tw -> tw_hour;
308 tb -> tw_mday = tw -> tw_mday;
309 tb -> tw_mon = tw -> tw_mon;
310 tb -> tw_year = tw -> tw_year;
311 tb -> tw_wday = tw -> tw_wday;
312 tb -> tw_yday = tw -> tw_yday;
313 tb -> tw_zone = tw -> tw_zone;
314 tb -> tw_clock = tw -> tw_clock;
315 tb -> tw_flags = tw -> tw_flags;
316 #else /* not notdef */
317 *tb = *tw;
318 #endif /* not notdef */
319 }
320
321
322 int twsort (tw1, tw2)
323 register struct tws *tw1,
324 *tw2;
325 {
326 register long c1,
327 c2;
328
329 if (tw1 -> tw_clock == 0L)
330 (void) twclock (tw1);
331 if (tw2 -> tw_clock == 0L)
332 (void) twclock (tw2);
333
334 return ((c1 = tw1 -> tw_clock) > (c2 = tw2 -> tw_clock) ? 1
335 : c1 == c2 ? 0 : -1);
336 }
337
338 /* \f */
339
340 /* This routine is based on the gtime() routine written by Steven Shafer
341 (sas) at CMU. It was forwarded to MTR by Jay Lepreau at Utah-CS.
342 */
343
344 static int dmsize[] = {
345 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
346 };
347
348
349 long twclock (tw)
350 register struct tws *tw;
351 {
352 register int i,
353 sec,
354 min,
355 hour,
356 mday,
357 mon,
358 year;
359 register long result;
360
361 if (tw -> tw_clock != 0L)
362 return tw -> tw_clock;
363
364 if ((sec = tw -> tw_sec) < 0 || sec > 59
365 || (min = tw -> tw_min) < 0 || min > 59
366 || (hour = tw -> tw_hour) < 0 || hour > 23
367 || (mday = tw -> tw_mday) < 1 || mday > 31
368 || (mon = tw -> tw_mon + 1) < 1 || mon > 12)
369 return (tw -> tw_clock = -1L);
370 year = tw -> tw_year;
371
372 result = 0L;
373 if (year < 100)
374 year += CENTURY;
375 for (i = 1970; i < year; i++)
376 result += dysize (i);
377 if (dysize (year) == 366 && mon >= 3)
378 result++;
379 while (--mon)
380 result += dmsize[mon - 1];
381 result += mday - 1;
382 result = 24 * result + hour;
383 result = 60 * result + min;
384 result = 60 * result + sec;
385 result -= 60 * tw -> tw_zone;
386 if (tw -> tw_flags & TW_DST)
387 result -= 60 * 60;
388
389 return (tw -> tw_clock = result);
390 }
391
392 /* \f */
393
394 /*
395 * Simple calculation of day of the week. Algorithm used is Zeller's
396 * congruence. Currently, we assume if tw -> tw_year < 100
397 * then the century is CENTURY.
398 */
399
400 set_dotw (tw)
401 register struct tws *tw;
402 {
403 register int month,
404 day,
405 year,
406 century;
407
408 month = tw -> tw_mon - 1;
409 day = tw -> tw_mday;
410 year = tw -> tw_year % 100;
411 century = tw -> tw_year >= 100 ? tw -> tw_year / 100 : (CENTURY / 100);
412
413 if (month <= 0) {
414 month += 12;
415 if (--year < 0) {
416 year += 100;
417 century--;
418 }
419 }
420
421 tw -> tw_wday =
422 ((26 * month - 2) / 10 + day + year + year / 4
423 - 3 * century / 4 + 1) % 7;
424
425 tw -> tw_flags &= ~TW_SDAY, tw -> tw_flags |= TW_SIMP;
426 }