|
|
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 1970\n\0 ! 31: * 012345678901234567890123 4 5 ! 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: int dysize(); ! 77: static char *gint(); ! 78: static dtparse(); ! 79: ! 80: char * ! 81: ctime(t) ! 82: long *t; ! 83: { ! 84: return(asctime(localtime(t))); ! 85: } ! 86: ! 87: struct tm * ! 88: localtime(tim) ! 89: long *tim; ! 90: { ! 91: register int dayno; ! 92: register struct tm *ct; ! 93: register daylbegin, daylend; ! 94: int boff, eoff; ! 95: register int i; ! 96: register int incr; ! 97: register int tmp; ! 98: long copyt; ! 99: struct timeb systime; ! 100: ! 101: ftime(&systime); ! 102: copyt = *tim - (long)systime.timezone*60; ! 103: ct = gmtime(©t); ! 104: if (systime.dstflag == 0) ! 105: return (ct); ! 106: dayno = ct->tm_yday; ! 107: daylbegin = 999; /* default: no dst */ ! 108: daylend = 999; ! 109: incr = 1*60*60; ! 110: boff = eoff = 0; ! 111: rdaytab(); ! 112: for (i = 0; i < ndaytab; i++) ! 113: if (daytab[i].ybeg <= ct->tm_year && ct->tm_year <= daytab[i].yend) { ! 114: daylbegin = daytab[i].dbeg; ! 115: daylend = daytab[i].dend; ! 116: boff = daytab[i].obeg; ! 117: eoff = daytab[i].oend; ! 118: break; ! 119: } ! 120: if (daylbegin > daylend) { ! 121: tmp = daylbegin; ! 122: daylbegin = daylend; ! 123: daylend = tmp; ! 124: copyt += incr; ! 125: incr = -incr; ! 126: } ! 127: daylbegin = sunday(ct, daylbegin)+boff; ! 128: daylend = sunday(ct, daylend)+eoff; ! 129: if ((dayno>daylbegin || (dayno==daylbegin && ct->tm_hour>=2)) && ! 130: (dayno<daylend || (dayno==daylend && ct->tm_hour<1))) { ! 131: copyt += incr; ! 132: ct = gmtime(©t); ! 133: ct->tm_isdst++; ! 134: } ! 135: return(ct); ! 136: } ! 137: ! 138: /* ! 139: * The argument is a 0-origin day number. ! 140: * The value is the day number of the next ! 141: * Sunday after the day. ! 142: */ ! 143: static ! 144: sunday(t, d) ! 145: register struct tm *t; ! 146: register int d; ! 147: { ! 148: if (d >= 58) ! 149: d += dysize(t->tm_year) - 365; ! 150: return(d + 7 - (d - t->tm_yday + t->tm_wday + 700) % 7); ! 151: } ! 152: ! 153: struct tm * ! 154: gmtime(tim) ! 155: long *tim; ! 156: { ! 157: register int d0, d1; ! 158: long hms, day; ! 159: register int *tp; ! 160: static struct tm xtime; ! 161: ! 162: /* ! 163: * break initial number into days ! 164: */ ! 165: hms = *tim % 86400; ! 166: day = *tim / 86400; ! 167: if (hms<0) { ! 168: hms += 86400; ! 169: day -= 1; ! 170: } ! 171: tp = (int *)&xtime; ! 172: ! 173: /* ! 174: * generate hours:minutes:seconds ! 175: */ ! 176: *tp++ = hms%60; ! 177: d1 = hms/60; ! 178: *tp++ = d1%60; ! 179: d1 /= 60; ! 180: *tp++ = d1; ! 181: ! 182: /* ! 183: * day is the day number. ! 184: * generate day of the week. ! 185: * The addend is 4 mod 7 (1/1/1970 was Thursday) ! 186: */ ! 187: ! 188: xtime.tm_wday = (day+7340036)%7; ! 189: ! 190: /* ! 191: * year number ! 192: */ ! 193: /* in 400 years there are 97*366+303*365=146097 days (40 bits and up)*/ ! 194: if(day>=0) { ! 195: for(d1 = 70; day >= 146097; d1 += 400) ! 196: day -= 146097; ! 197: for(; day >= dysize(d1); d1++) ! 198: day -= dysize(d1); ! 199: } ! 200: else { ! 201: for(d1 = 70; day <= -146097; d1 -= 400) ! 202: day += 146097; ! 203: for(; day < 0; d1--) ! 204: day += dysize(d1-1); /* ! */ ! 205: } ! 206: xtime.tm_year = d1; ! 207: xtime.tm_yday = d0 = day; ! 208: ! 209: /* ! 210: * generate month ! 211: */ ! 212: ! 213: if (dysize(d1)==366) ! 214: dmsize[1] = 29; ! 215: for(d1=0; d0 >= dmsize[d1]; d1++) ! 216: d0 -= dmsize[d1]; ! 217: dmsize[1] = 28; ! 218: *tp++ = d0+1; ! 219: *tp++ = d1; ! 220: xtime.tm_isdst = 0; ! 221: return(&xtime); ! 222: } ! 223: ! 224: char * ! 225: asctime(t) ! 226: struct tm *t; ! 227: { ! 228: register char *cp, *ncp; ! 229: register int *tp; ! 230: ! 231: cp = cbuf; ! 232: for (ncp = "Day Mon 00 00:00:00 1900\n"; *cp++ = *ncp++;); ! 233: ncp = &"SunMonTueWedThuFriSat"[3*t->tm_wday]; ! 234: cp = cbuf; ! 235: *cp++ = *ncp++; ! 236: *cp++ = *ncp++; ! 237: *cp++ = *ncp++; ! 238: cp++; ! 239: tp = &t->tm_mon; ! 240: ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(*tp)*3]; ! 241: *cp++ = *ncp++; ! 242: *cp++ = *ncp++; ! 243: *cp++ = *ncp++; ! 244: cp = ct_numb(cp, *--tp); ! 245: cp = ct_numb(cp, *--tp+100); ! 246: cp = ct_numb(cp, *--tp+100); ! 247: cp = ct_numb(cp, *--tp+100); ! 248: if (t->tm_year>=100) { ! 249: cp[1] = '2'; ! 250: cp[2] = '0'; ! 251: } ! 252: cp += 2; ! 253: cp = ct_numb(cp, t->tm_year+100); ! 254: return(cbuf); ! 255: } ! 256: ! 257: dysize(y) ! 258: { ! 259: if((y%4) == 0) ! 260: return(366); ! 261: return(365); ! 262: } ! 263: ! 264: static char * ! 265: ct_numb(cp, n) ! 266: register char *cp; ! 267: { ! 268: cp++; ! 269: if (n>=10) ! 270: *cp++ = (n/10)%10 + '0'; ! 271: else ! 272: *cp++ = ' '; ! 273: *cp++ = n%10 + '0'; ! 274: return(cp); ! 275: } ! 276: ! 277: #include <ctype.h> ! 278: ! 279: /* ! 280: * read the file of daylight savings time boundaries ! 281: * it looks like ! 282: * 1971 1983 32 0 317 1 ! 283: * to mean that for years 1971-1983, dst starts the first sunday after ! 284: * day 32, and ends the first monday after day 317 ! 285: */ ! 286: #define BUFSZ 1024 ! 287: #define DSTFILE "/lib/dst" ! 288: ! 289: static ! 290: rdaytab() ! 291: { ! 292: static int doneit; ! 293: int fd; ! 294: char buf[BUFSZ]; ! 295: char *p; ! 296: register int i; ! 297: char *rdline(); ! 298: ! 299: if (doneit++) ! 300: return; ! 301: if ((fd = open(DSTFILE, 0)) < 0) ! 302: return; ! 303: i = 0; ! 304: while ((p = rdline(fd, buf)) != 0) ! 305: if (dtparse(p, &daytab[i])) ! 306: if (++i >= NDAYTAB) ! 307: break; ! 308: ndaytab = i; ! 309: close(fd); ! 310: } ! 311: ! 312: static ! 313: dtparse(p, dp) ! 314: register char *p; ! 315: register struct daytab *dp; ! 316: { ! 317: short s; ! 318: ! 319: if ((p = gint(p, &s)) == 0) ! 320: return (0); ! 321: if (s < 1900) ! 322: dp->ybeg = 0; ! 323: else if (s > (1900+255)) ! 324: dp->ybeg = 255; ! 325: else ! 326: dp->ybeg = s - 1900; ! 327: if ((p = gint(p, &s)) == 0) ! 328: return (0); ! 329: if (s < 1900) ! 330: dp->yend = 0; ! 331: else if (s > (1900+255)) ! 332: dp->yend = 255; ! 333: else ! 334: dp->yend = s - 1900; ! 335: if ((p = gint(p, &dp->dbeg)) == 0) ! 336: return (0); ! 337: if ((p = gint(p, &s)) == 0) ! 338: return (0); ! 339: dp->obeg = s; ! 340: if ((p = gint(p, &dp->dend)) == 0) ! 341: return (0); ! 342: if ((p = gint(p, &s)) == 0) ! 343: return (0); ! 344: dp->oend = s; ! 345: return (1); ! 346: } ! 347: ! 348: static char * ! 349: gint(p, sp) ! 350: register char *p; ! 351: register short *sp; ! 352: { ! 353: register int i; ! 354: ! 355: while (isspace(*p)) ! 356: p++; ! 357: if (!isdigit(*p)) ! 358: return (0); ! 359: i = 0; ! 360: while (isdigit(*p)) ! 361: i = (i*10) + *p++ - '0'; ! 362: *sp = i; ! 363: return (p); ! 364: } ! 365: ! 366: static char * ! 367: rdline(fd, buf) ! 368: int fd; ! 369: char *buf; ! 370: { ! 371: register char *p, *q; ! 372: static char *lastp; ! 373: static char *endp; ! 374: int n; ! 375: ! 376: if (lastp == 0 || lastp >= endp) { ! 377: if ((n = read(fd, buf, BUFSZ)) <= 0) ! 378: return (0); ! 379: lastp = buf; ! 380: endp = &buf[n]; ! 381: } ! 382: for (p = lastp; p < endp && *p != '\n'; p++) ! 383: ; ! 384: if (p < endp || lastp == buf) { ! 385: *p++ = 0; ! 386: q = lastp; ! 387: lastp = p; ! 388: return (q); ! 389: } ! 390: /* ! 391: * unfinished line at end of buffer. try again. ! 392: */ ! 393: q = lastp; ! 394: p = buf; ! 395: while (q < endp) ! 396: *p++ = *q++; ! 397: if ((n = read(fd, p, BUFSZ - (p-buf))) <= 0) ! 398: return (0); ! 399: endp = &p[n]; ! 400: for (; p < endp && *p != '\n'; p++) ! 401: ; ! 402: if (p >= endp) ! 403: --p; /* too bad */ ! 404: *p++ = 0; ! 405: lastp = p; ! 406: return (buf); ! 407: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.