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