1 /* dtime.c - routines to do ``ARPA-style'' time structures */
3 static char ident[] = "@(#)$Id: dtime.c,v 1.15 1992/12/15 00:20:22 jromine Exp $";
11 #include "../h/strings.h"
16 #include <sys/types.h>
17 #if !defined(SYS5) && !defined(ZONEINFO)
18 #include <sys/timeb.h>
19 #endif /* !defined(SYS5) && !defined(ZONEINFO) */
34 extern char *tzname[];
40 #define abs(a) (a >= 0 ? a : -a)
44 (((y) % 4) ? 365 : (((y) % 100) ? 366 : (((y) % 400) ? 365 : 366)))
49 "Jan", "Feb", "Mar", "Apr", "May", "Jun",
50 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", NULL
54 "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", NULL
58 "Sunday", "Monday", "Tuesday", "Wednesday",
59 "Thursday", "Friday", "Saturday", NULL
74 #ifdef notdef /* RFC1123 specifies do not use military TZs */
111 struct tm *localtime ();
118 (void) time (&clock);
119 return dtime (&clock);
124 register struct tws *tw;
126 static char buffer[25];
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);
141 struct tws *dtwstime () {
144 (void) time (&clock);
145 return dlocaltime (&clock);
149 struct tws *dlocaltime (clock)
150 register long *clock;
152 register struct tm *tm;
153 #if !defined(SYS5) && !defined(ZONEINFO)
155 #endif /* !defined(SYS5) && !defined(ZONEINFO) */
156 static struct tws tw;
160 tw.tw_flags = TW_NULL;
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;
172 tw.tw_flags |= TW_DST;
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) */
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;
194 struct tws *dgmtime (clock)
195 register long *clock;
197 register struct tm *tm;
198 static struct tws tw;
202 tw.tw_flags = TW_NULL;
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;
214 tw.tw_flags |= TW_DST;
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;
225 char *dasctime (tw, flags)
226 register struct tws *tw;
230 static char result[80];
235 /* Display timezone if known */
236 if ((tw->tw_flags & TW_SZONE) == TW_SZNIL)
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);
246 if ((tw -> tw_flags & TW_SDAY) == TW_SEXP)
247 (void) sprintf (result, "%s, %s", tw_dotw[tw -> tw_wday], buffer);
249 if ((tw -> tw_flags & TW_SDAY) == TW_SNIL)
250 (void) strcpy (result, buffer);
252 (void) sprintf (result, "%s (%s)", buffer, tw_dotw[tw -> tw_wday]);
259 char *dtimezone (offset, flags)
265 register struct zone *z;
266 static char buffer[10];
269 mins = -((-offset) % 60);
270 hours = -((-offset) / 60);
277 if (!(flags & TW_ZONE) && mins == 0)
278 #if defined(SYS5) && defined(TZNAME)
281 return ((flags & TW_DST) ? tzname[1] : tzname[0]);
284 for (z = zones; z -> std; z++)
285 if (z -> shift == hours)
286 return (z -> dst && (flags & TW_DST) ? z -> dst : z -> std);
292 #endif /* defined(DSTXXX) */
293 (void) sprintf (buffer, "%s%02d%02d",
294 offset < 0 ? "-" : "+", abs (hours), abs (mins));
300 void twscopy (tb, tw)
301 register struct tws *tb,
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 */
318 #endif /* not notdef */
322 int twsort (tw1, tw2)
323 register struct tws *tw1,
329 if (tw1 -> tw_clock == 0L)
330 (void) twclock (tw1);
331 if (tw2 -> tw_clock == 0L)
332 (void) twclock (tw2);
334 return ((c1 = tw1 -> tw_clock) > (c2 = tw2 -> tw_clock) ? 1
335 : c1 == c2 ? 0 : -1);
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.
344 static int dmsize[] = {
345 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
350 register struct tws *tw;
359 register long result;
361 if (tw -> tw_clock != 0L)
362 return tw -> tw_clock;
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;
375 for (i = 1970; i < year; i++)
376 result += dysize (i);
377 if (dysize (year) == 366 && mon >= 3)
380 result += dmsize[mon - 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)
389 return (tw -> tw_clock = result);
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.
401 register struct tws *tw;
408 month = tw -> tw_mon - 1;
410 year = tw -> tw_year % 100;
411 century = tw -> tw_year >= 100 ? tw -> tw_year / 100 : (CENTURY / 100);
422 ((26 * month - 2) / 10 + day + year + year / 4
423 - 3 * century / 4 + 1) % 7;
425 tw -> tw_flags &= ~TW_SDAY, tw -> tw_flags |= TW_SIMP;