|
|
1.1 ! root 1: #ifndef lint ! 2: static char sccsid[] = "@(#)ctime.c 4.4 (Berkeley) 7/9/83"; ! 3: #endif ! 4: /* ! 5: * This routine converts time as follows. ! 6: * The epoch is 0000 Jan 1 1970 GMT. ! 7: * The argument time is in seconds since then. ! 8: * The localtime(t) entry returns a pointer to an array ! 9: * containing ! 10: * seconds (0-59) ! 11: * minutes (0-59) ! 12: * hours (0-23) ! 13: * day of month (1-31) ! 14: * month (0-11) ! 15: * year-1970 ! 16: * weekday (0-6, Sun is 0) ! 17: * day of the year ! 18: * daylight savings flag ! 19: * ! 20: * The routine calls the system to determine the local ! 21: * timezone and whether Daylight Saving Time is permitted locally. ! 22: * (DST is then determined by the current local rules) ! 23: * ! 24: * The routine does not work ! 25: * in Saudi Arabia which runs on Solar time. ! 26: * ! 27: * asctime(tvec)) ! 28: * where tvec is produced by localtime ! 29: * returns a ptr to a character string ! 30: * that has the ascii time in the form ! 31: * Thu Jan 01 00:00:00 1970n0\\ ! 32: * 01234567890123456789012345 ! 33: * 0 1 2 ! 34: * ! 35: * ctime(t) just calls localtime, then asctime. ! 36: */ ! 37: ! 38: #include <sys/time.h> ! 39: #include <sys/types.h> ! 40: #include <sys/timeb.h> ! 41: ! 42: static char cbuf[26]; ! 43: static int dmsize[12] = ! 44: { ! 45: 31, ! 46: 28, ! 47: 31, ! 48: 30, ! 49: 31, ! 50: 30, ! 51: 31, ! 52: 31, ! 53: 30, ! 54: 31, ! 55: 30, ! 56: 31 ! 57: }; ! 58: ! 59: /* ! 60: * The following table is used for 1974 and 1975 and ! 61: * gives the day number of the first day after the Sunday of the ! 62: * change. ! 63: */ ! 64: struct dstab { ! 65: int dayyr; ! 66: int daylb; ! 67: int dayle; ! 68: }; ! 69: ! 70: static struct dstab usdaytab[] = { ! 71: 1974, 5, 333, /* 1974: Jan 6 - last Sun. in Nov */ ! 72: 1975, 58, 303, /* 1975: Last Sun. in Feb - last Sun in Oct */ ! 73: 0, 119, 303, /* all other years: end Apr - end Oct */ ! 74: }; ! 75: static struct dstab ausdaytab[] = { ! 76: 1970, 400, 0, /* 1970: no daylight saving at all */ ! 77: 1971, 303, 0, /* 1971: daylight saving from Oct 31 */ ! 78: 1972, 303, 58, /* 1972: Jan 1 -> Feb 27 & Oct 31 -> dec 31 */ ! 79: 0, 303, 65, /* others: -> Mar 7, Oct 31 -> */ ! 80: }; ! 81: ! 82: /* ! 83: * The European tables ... based on hearsay ! 84: * Believed correct for: ! 85: * WE: Great Britain, Ireland, Portugal ! 86: * ME: Belgium, Luxembourg, Netherlands, Denmark, Norway, ! 87: * Austria, Poland, Czechoslovakia, Sweden, Switzerland, ! 88: * DDR, DBR, France, Spain, Hungary, Italy, Jugoslavia ! 89: * Eastern European dst is unknown, we'll make it ME until someone speaks up. ! 90: * EE: Bulgaria, Finland, Greece, Rumania, Turkey, Western Russia ! 91: */ ! 92: static struct dstab wedaytab[] = { ! 93: 1983, 86, 303, /* 1983: end March - end Oct */ ! 94: 1984, 86, 303, /* 1984: end March - end Oct */ ! 95: 1985, 86, 303, /* 1985: end March - end Oct */ ! 96: 0, 400, 0, /* others: no daylight saving at all ??? */ ! 97: }; ! 98: ! 99: static struct dstab medaytab[] = { ! 100: 1983, 86, 272, /* 1983: end March - end Sep */ ! 101: 1984, 86, 272, /* 1984: end March - end Sep */ ! 102: 1985, 86, 272, /* 1985: end March - end Sep */ ! 103: 0, 400, 0, /* others: no daylight saving at all ??? */ ! 104: }; ! 105: ! 106: static struct dayrules { ! 107: int dst_type; /* number obtained from system */ ! 108: int dst_hrs; /* hours to add when dst on */ ! 109: struct dstab * dst_rules; /* one of the above */ ! 110: enum {STH,NTH} dst_hemi; /* southern, northern hemisphere */ ! 111: } dayrules [] = { ! 112: DST_USA, 1, usdaytab, NTH, ! 113: DST_AUST, 1, ausdaytab, STH, ! 114: DST_WET, 1, wedaytab, NTH, ! 115: DST_MET, 1, medaytab, NTH, ! 116: DST_EET, 1, medaytab, NTH, /* XXX */ ! 117: -1, ! 118: }; ! 119: ! 120: struct tm *gmtime(); ! 121: char *ct_numb(); ! 122: struct tm *localtime(); ! 123: char *ctime(); ! 124: char *ct_num(); ! 125: char *asctime(); ! 126: ! 127: char * ! 128: ctime(t) ! 129: unsigned long *t; ! 130: { ! 131: return(asctime(localtime(t))); ! 132: } ! 133: ! 134: struct tm * ! 135: localtime(tim) ! 136: unsigned long *tim; ! 137: { ! 138: register int dayno; ! 139: register struct tm *ct; ! 140: register dalybeg, daylend; ! 141: register struct dayrules *dr; ! 142: register struct dstab *ds; ! 143: int year; ! 144: unsigned long copyt; ! 145: struct timeval curtime; ! 146: struct timezone zone; ! 147: ! 148: gettimeofday(&curtime, &zone); ! 149: copyt = *tim - (unsigned long)zone.tz_minuteswest*60; ! 150: ct = gmtime(©t); ! 151: dayno = ct->tm_yday; ! 152: for (dr = dayrules; dr->dst_type >= 0; dr++) ! 153: if (dr->dst_type == zone.tz_dsttime) ! 154: break; ! 155: if (dr->dst_type >= 0) { ! 156: year = ct->tm_year + 1900; ! 157: for (ds = dr->dst_rules; ds->dayyr; ds++) ! 158: if (ds->dayyr == year) ! 159: break; ! 160: dalybeg = ds->daylb; /* first Sun after dst starts */ ! 161: daylend = ds->dayle; /* first Sun after dst ends */ ! 162: dalybeg = sunday(ct, dalybeg); ! 163: daylend = sunday(ct, daylend); ! 164: switch (dr->dst_hemi) { ! 165: case NTH: ! 166: if (!( ! 167: (dayno>dalybeg || (dayno==dalybeg && ct->tm_hour>=2)) && ! 168: (dayno<daylend || (dayno==daylend && ct->tm_hour<1)) ! 169: )) ! 170: return(ct); ! 171: break; ! 172: case STH: ! 173: if (!( ! 174: (dayno>dalybeg || (dayno==dalybeg && ct->tm_hour>=2)) || ! 175: (dayno<daylend || (dayno==daylend && ct->tm_hour<2)) ! 176: )) ! 177: return(ct); ! 178: break; ! 179: default: ! 180: return(ct); ! 181: } ! 182: copyt += dr->dst_hrs*60*60; ! 183: ct = gmtime(©t); ! 184: ct->tm_isdst++; ! 185: } ! 186: return(ct); ! 187: } ! 188: ! 189: /* ! 190: * The argument is a 0-origin day number. ! 191: * The value is the day number of the first ! 192: * Sunday on or after the day. ! 193: */ ! 194: static ! 195: sunday(t, d) ! 196: register struct tm *t; ! 197: register int d; ! 198: { ! 199: if (d >= 58) ! 200: d += dysize(t->tm_year) - 365; ! 201: return(d - (d - t->tm_yday + t->tm_wday + 700) % 7); ! 202: } ! 203: ! 204: struct tm * ! 205: gmtime(tim) ! 206: unsigned long *tim; ! 207: { ! 208: register int d0, d1; ! 209: unsigned long hms, day; ! 210: register int *tp; ! 211: static struct tm xtime; ! 212: ! 213: /* ! 214: * break initial number into days ! 215: */ ! 216: hms = *tim % 86400; ! 217: day = *tim / 86400; ! 218: if (hms<0) { ! 219: hms += 86400; ! 220: day -= 1; ! 221: } ! 222: tp = (int *)&xtime; ! 223: ! 224: /* ! 225: * generate hours:minutes:seconds ! 226: */ ! 227: *tp++ = hms%60; ! 228: d1 = hms/60; ! 229: *tp++ = d1%60; ! 230: d1 /= 60; ! 231: *tp++ = d1; ! 232: ! 233: /* ! 234: * day is the day number. ! 235: * generate day of the week. ! 236: * The addend is 4 mod 7 (1/1/1970 was Thursday) ! 237: */ ! 238: ! 239: xtime.tm_wday = (day+7340036)%7; ! 240: ! 241: /* ! 242: * year number ! 243: */ ! 244: if (day>=0) for(d1=70; day >= dysize(d1); d1++) ! 245: day -= dysize(d1); ! 246: else for (d1=70; day<0; d1--) ! 247: day += dysize(d1-1); ! 248: xtime.tm_year = d1; ! 249: xtime.tm_yday = d0 = day; ! 250: ! 251: /* ! 252: * generate month ! 253: */ ! 254: ! 255: if (dysize(d1)==366) ! 256: dmsize[1] = 29; ! 257: for(d1=0; d0 >= dmsize[d1]; d1++) ! 258: d0 -= dmsize[d1]; ! 259: dmsize[1] = 28; ! 260: *tp++ = d0+1; ! 261: *tp++ = d1; ! 262: xtime.tm_isdst = 0; ! 263: return(&xtime); ! 264: } ! 265: ! 266: char * ! 267: asctime(t) ! 268: struct tm *t; ! 269: { ! 270: register char *cp, *ncp; ! 271: register int *tp; ! 272: ! 273: cp = cbuf; ! 274: for (ncp = "Day Mon 00 00:00:00 1900\n"; *cp++ = *ncp++;); ! 275: ncp = &"SunMonTueWedThuFriSat"[3*t->tm_wday]; ! 276: cp = cbuf; ! 277: *cp++ = *ncp++; ! 278: *cp++ = *ncp++; ! 279: *cp++ = *ncp++; ! 280: cp++; ! 281: tp = &t->tm_mon; ! 282: ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(*tp)*3]; ! 283: *cp++ = *ncp++; ! 284: *cp++ = *ncp++; ! 285: *cp++ = *ncp++; ! 286: cp = ct_numb(cp, *--tp); ! 287: cp = ct_numb(cp, *--tp+100); ! 288: cp = ct_numb(cp, *--tp+100); ! 289: cp = ct_numb(cp, *--tp+100); ! 290: if (t->tm_year>=100) { ! 291: cp[1] = '2'; ! 292: cp[2] = '0' + t->tm_year >= 200; ! 293: } ! 294: cp += 2; ! 295: cp = ct_numb(cp, t->tm_year+100); ! 296: return(cbuf); ! 297: } ! 298: ! 299: dysize(y) ! 300: { ! 301: if((y%4) == 0) ! 302: return(366); ! 303: return(365); ! 304: } ! 305: ! 306: static char * ! 307: ct_numb(cp, n) ! 308: register char *cp; ! 309: { ! 310: cp++; ! 311: if (n>=10) ! 312: *cp++ = (n/10)%10 + '0'; ! 313: else ! 314: *cp++ = ' '; ! 315: *cp++ = n%10 + '0'; ! 316: return(cp); ! 317: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.