|
|
1.1 ! root 1: /* ! 2: * This routine converts time as follows. ! 3: * The epoch is 0000 Jan 1 1970 GMT. ! 4: * The argument time is in seconds since then. ! 5: * The localtime(t) entry returns a pointer to an array ! 6: * containing ! 7: * seconds (0-59) ! 8: * minutes (0-59) ! 9: * hours (0-23) ! 10: * day of month (1-31) ! 11: * month (0-11) ! 12: * year-1970 ! 13: * weekday (0-6, Sun is 0) ! 14: * day of the year ! 15: * daylight savings flag ! 16: * ! 17: * The routine calls the system to determine the local ! 18: * timezone and whether Daylight Saving Time is permitted locally. ! 19: * (DST is then determined by the current US standard rules) ! 20: * There is a table that accounts for the peculiarities ! 21: * undergone by daylight time in 1974-1975. ! 22: * ! 23: * The routine does not work ! 24: * in Saudi Arabia which runs on Solar time. ! 25: * ! 26: * asctime(tvec)) ! 27: * where tvec is produced by localtime ! 28: * returns a ptr to a character string ! 29: * that has the ascii time in the form ! 30: * Thu Jan 01 00:00:00 1970n0\\ ! 31: * 01234567890123456789012345 ! 32: * 0 1 2 ! 33: * ! 34: * ctime(t) just calls localtime, then asctime. ! 35: */ ! 36: ! 37: #include <time.h> ! 38: #include <sys/types.h> ! 39: #include <sys/timeb.h> ! 40: ! 41: static char cbuf[26]; ! 42: static int dmsize[12] = ! 43: { ! 44: 31, ! 45: 28, ! 46: 31, ! 47: 30, ! 48: 31, ! 49: 30, ! 50: 31, ! 51: 31, ! 52: 30, ! 53: 31, ! 54: 30, ! 55: 31 ! 56: }; ! 57: ! 58: #define NDAYTAB 10 ! 59: ! 60: static int ndaytab; ! 61: static struct daytab { ! 62: unsigned char ybeg; /* year-1900 */ ! 63: unsigned char yend; ! 64: unsigned char obeg; /* offset from sunday */ ! 65: unsigned char oend; ! 66: short dbeg; ! 67: short dend; ! 68: } daytab[NDAYTAB]; ! 69: ! 70: struct tm *gmtime(); ! 71: char *ct_numb(); ! 72: struct tm *localtime(); ! 73: char *ctime(); ! 74: char *ct_num(); ! 75: char *asctime(); ! 76: ! 77: char * ! 78: ctime(t) ! 79: long *t; ! 80: { ! 81: return(asctime(localtime(t))); ! 82: } ! 83: ! 84: struct tm * ! 85: localtime(tim) ! 86: long *tim; ! 87: { ! 88: register int dayno; ! 89: register struct tm *ct; ! 90: register daylbegin, daylend; ! 91: int boff, eoff; ! 92: register int i; ! 93: register int incr; ! 94: register int tmp; ! 95: long copyt; ! 96: struct timeb systime; ! 97: ! 98: ftime(&systime); ! 99: copyt = *tim - (long)systime.timezone*60; ! 100: ct = gmtime(©t); ! 101: if (systime.dstflag == 0) ! 102: return (ct); ! 103: dayno = ct->tm_yday; ! 104: daylbegin = 999; /* default: no dst */ ! 105: daylend = 999; ! 106: incr = 1*60*60; ! 107: boff = eoff = 0; ! 108: rdaytab(); ! 109: for (i = 0; i < ndaytab; i++) ! 110: if (daytab[i].ybeg <= ct->tm_year && ct->tm_year <= daytab[i].yend) { ! 111: daylbegin = daytab[i].dbeg; ! 112: daylend = daytab[i].dend; ! 113: boff = daytab[i].obeg; ! 114: eoff = daytab[i].oend; ! 115: break; ! 116: } ! 117: if (daylbegin > daylend) { ! 118: tmp = daylbegin; ! 119: daylbegin = daylend; ! 120: daylend = tmp; ! 121: copyt += incr; ! 122: incr = -incr; ! 123: } ! 124: daylbegin = sunday(ct, daylbegin)+boff; ! 125: daylend = sunday(ct, daylend)+eoff; ! 126: if ((dayno>daylbegin || (dayno==daylbegin && ct->tm_hour>=2)) && ! 127: (dayno<daylend || (dayno==daylend && ct->tm_hour<1))) { ! 128: copyt += incr; ! 129: ct = gmtime(©t); ! 130: ct->tm_isdst++; ! 131: } ! 132: return(ct); ! 133: } ! 134: ! 135: /* ! 136: * The argument is a 0-origin day number. ! 137: * The value is the day number of the last ! 138: * Sunday before or after the day. ! 139: */ ! 140: static ! 141: sunday(t, d) ! 142: register struct tm *t; ! 143: register int d; ! 144: { ! 145: if (d >= 58) ! 146: d += dysize(t->tm_year) - 365; ! 147: return(d - (d - t->tm_yday + t->tm_wday + 700) % 7); ! 148: } ! 149: ! 150: struct tm * ! 151: gmtime(tim) ! 152: long *tim; ! 153: { ! 154: register int d0, d1; ! 155: long hms, day; ! 156: register int *tp; ! 157: static struct tm xtime; ! 158: ! 159: /* ! 160: * break initial number into days ! 161: */ ! 162: hms = *tim % 86400; ! 163: day = *tim / 86400; ! 164: if (hms<0) { ! 165: hms += 86400; ! 166: day -= 1; ! 167: } ! 168: tp = (int *)&xtime; ! 169: ! 170: /* ! 171: * generate hours:minutes:seconds ! 172: */ ! 173: *tp++ = hms%60; ! 174: d1 = hms/60; ! 175: *tp++ = d1%60; ! 176: d1 /= 60; ! 177: *tp++ = d1; ! 178: ! 179: /* ! 180: * day is the day number. ! 181: * generate day of the week. ! 182: * The addend is 4 mod 7 (1/1/1970 was Thursday) ! 183: */ ! 184: ! 185: xtime.tm_wday = (day+7340036)%7; ! 186: ! 187: /* ! 188: * year number ! 189: */ ! 190: /* in 400 years there are 97*366+303*365=146097 days (40 bits and up)*/ ! 191: if(day>=0) { ! 192: for(d1 = 70; day >= 146097; d1 += 400) ! 193: day -= 146097; ! 194: for(; day >= dysize(d1); d1++) ! 195: day -= dysize(d1); ! 196: } ! 197: else { ! 198: for(d1 = 70; day <= -146097; d1 -= 400) ! 199: day += 146097; ! 200: for(; day < 0; d1--) ! 201: day += dysize(d1-1); /* ! */ ! 202: } ! 203: xtime.tm_year = d1; ! 204: xtime.tm_yday = d0 = day; ! 205: ! 206: /* ! 207: * generate month ! 208: */ ! 209: ! 210: if (dysize(d1)==366) ! 211: dmsize[1] = 29; ! 212: for(d1=0; d0 >= dmsize[d1]; d1++) ! 213: d0 -= dmsize[d1]; ! 214: dmsize[1] = 28; ! 215: *tp++ = d0+1; ! 216: *tp++ = d1; ! 217: xtime.tm_isdst = 0; ! 218: return(&xtime); ! 219: } ! 220: ! 221: char * ! 222: asctime(t) ! 223: struct tm *t; ! 224: { ! 225: register char *cp, *ncp; ! 226: register int *tp; ! 227: ! 228: cp = cbuf; ! 229: for (ncp = "Day Mon 00 00:00:00 1900\n"; *cp++ = *ncp++;); ! 230: ncp = &"SunMonTueWedThuFriSat"[3*t->tm_wday]; ! 231: cp = cbuf; ! 232: *cp++ = *ncp++; ! 233: *cp++ = *ncp++; ! 234: *cp++ = *ncp++; ! 235: cp++; ! 236: tp = &t->tm_mon; ! 237: ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(*tp)*3]; ! 238: *cp++ = *ncp++; ! 239: *cp++ = *ncp++; ! 240: *cp++ = *ncp++; ! 241: cp = ct_numb(cp, *--tp); ! 242: cp = ct_numb(cp, *--tp+100); ! 243: cp = ct_numb(cp, *--tp+100); ! 244: cp = ct_numb(cp, *--tp+100); ! 245: if (t->tm_year>=100) { ! 246: cp[1] = '2'; ! 247: cp[2] = '0'; ! 248: } ! 249: cp += 2; ! 250: cp = ct_numb(cp, t->tm_year+100); ! 251: return(cbuf); ! 252: } ! 253: ! 254: dysize(y) ! 255: { ! 256: if((y%4) == 0) ! 257: return(366); ! 258: return(365); ! 259: } ! 260: ! 261: static char * ! 262: ct_numb(cp, n) ! 263: register char *cp; ! 264: { ! 265: cp++; ! 266: if (n>=10) ! 267: *cp++ = (n/10)%10 + '0'; ! 268: else ! 269: *cp++ = ' '; ! 270: *cp++ = n%10 + '0'; ! 271: return(cp); ! 272: } ! 273: ! 274: #include <ctype.h> ! 275: ! 276: /* ! 277: * read the file of daylight savings time boundaries ! 278: * it looks like ! 279: * 1971 1983 32 0 317 1 ! 280: * to mean that for years 1971-1983, dst starts the first sunday after ! 281: * day 32, and ends the first monday after day 317 ! 282: */ ! 283: #define BUFSZ 1024 ! 284: #define DSTFILE "/lib/dst" ! 285: ! 286: static ! 287: rdaytab() ! 288: { ! 289: static int doneit; ! 290: int fd; ! 291: char buf[BUFSZ]; ! 292: char *p; ! 293: register int i; ! 294: char *rdline(); ! 295: ! 296: if (doneit++) ! 297: return; ! 298: if ((fd = open(DSTFILE, 0)) < 0) ! 299: return; ! 300: i = 0; ! 301: while ((p = rdline(fd, buf)) != 0) ! 302: if (dtparse(p, &daytab[i])) ! 303: if (++i >= NDAYTAB) ! 304: break; ! 305: ndaytab = i; ! 306: close(fd); ! 307: } ! 308: ! 309: dtparse(p, dp) ! 310: register char *p; ! 311: register struct daytab *dp; ! 312: { ! 313: short s; ! 314: char *gint(); ! 315: ! 316: if ((p = gint(p, &s)) == 0) ! 317: return (0); ! 318: if (s < 1900) ! 319: dp->ybeg = 0; ! 320: else if (s > (1900+255)) ! 321: dp->ybeg = 255; ! 322: else ! 323: dp->ybeg = s - 1900; ! 324: if ((p = gint(p, &s)) == 0) ! 325: return (0); ! 326: if (s < 1900) ! 327: dp->yend = 0; ! 328: else if (s > (1900+255)) ! 329: dp->yend = 255; ! 330: else ! 331: dp->yend = s - 1900; ! 332: if ((p = gint(p, &dp->dbeg)) == 0) ! 333: return (0); ! 334: if ((p = gint(p, &s)) == 0) ! 335: return (0); ! 336: dp->obeg = s; ! 337: if ((p = gint(p, &dp->dend)) == 0) ! 338: return (0); ! 339: if ((p = gint(p, &s)) == 0) ! 340: return (0); ! 341: dp->oend = s; ! 342: return (1); ! 343: } ! 344: ! 345: static char * ! 346: gint(p, sp) ! 347: register char *p; ! 348: register short *sp; ! 349: { ! 350: register int i; ! 351: ! 352: while (isspace(*p)) ! 353: p++; ! 354: if (!isdigit(*p)) ! 355: return (0); ! 356: i = 0; ! 357: while (isdigit(*p)) ! 358: i = (i*10) + *p++ - '0'; ! 359: *sp = i; ! 360: return (p); ! 361: } ! 362: ! 363: static char * ! 364: rdline(fd, buf) ! 365: int fd; ! 366: char *buf; ! 367: { ! 368: register char *p, *q; ! 369: static char *lastp; ! 370: static char *endp; ! 371: int n; ! 372: ! 373: if (lastp == 0 || lastp >= endp) { ! 374: if ((n = read(fd, buf, BUFSZ)) <= 0) ! 375: return (0); ! 376: lastp = buf; ! 377: endp = &buf[n]; ! 378: } ! 379: for (p = lastp; p < endp && *p != '\n'; p++) ! 380: ; ! 381: if (p < endp || lastp == buf) { ! 382: *p++ = 0; ! 383: q = lastp; ! 384: lastp = p; ! 385: return (q); ! 386: } ! 387: /* ! 388: * unfinished line at end of buffer. try again. ! 389: */ ! 390: q = lastp; ! 391: p = buf; ! 392: while (q < endp) ! 393: *p++ = *q++; ! 394: if ((n = read(fd, p, BUFSZ - (p-buf))) <= 0) ! 395: return (0); ! 396: endp = &p[n]; ! 397: for (; p < endp && *p != '\n'; p++) ! 398: ; ! 399: if (p >= endp) ! 400: --p; /* too bad */ ! 401: *p++ = 0; ! 402: lastp = p; ! 403: return (buf); ! 404: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.