1: /* @(#)ctime.c 2.1 SCCS id keyword */ 2: /* 3: * This routine converts time as follows. 4: * The epoch is 0000 Jan 1 1970 GMT. 5: * The argument time is in seconds since then. 6: * The localtime(t) entry returns a pointer to an array 7: * containing 8: * seconds (0-59) 9: * minutes (0-59) 10: * hours (0-23) 11: * day of month (1-31) 12: * month (0-11) 13: * year-1970 14: * weekday (0-6, Sun is 0) 15: * day of the year 16: * daylight savings flag 17: * 18: * The routine calls the system to determine the local 19: * timezone and whether Daylight Saving Time is permitted locally. 20: * (DST is then determined by the current US standard rules) 21: * There is a table that accounts for the peculiarities 22: * undergone by daylight time in 1974-1975. 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 <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: static struct { 65: int daylb; 66: int dayle; 67: } daytab[] = { 68: 5, 333, /* 1974: Jan 6 - last Sun. in Nov */ 69: 58, 303, /* 1975: Last Sun. in Feb - last Sun in Oct */ 70: }; 71: 72: struct tm *gmtime(); 73: char *ct_numb(); 74: struct tm *localtime(); 75: char *ctime(); 76: char *ct_num(); 77: char *asctime(); 78: 79: char * 80: ctime(t) 81: long *t; 82: { 83: return(asctime(localtime(t))); 84: } 85: 86: struct tm * 87: localtime(tim) 88: long *tim; 89: { 90: register int dayno; 91: register struct tm *ct; 92: register daylbegin, daylend; 93: long copyt; 94: struct timeb systime; 95: 96: ftime(&systime); 97: copyt = *tim - (long)systime.timezone*60; 98: ct = gmtime(©t); 99: dayno = ct->tm_yday; 100: daylbegin = 119; /* last Sun in Apr */ 101: daylend = 303; /* Last Sun in Oct */ 102: if (ct->tm_year==74 || ct->tm_year==75) { 103: daylbegin = daytab[ct->tm_year-74].daylb; 104: daylend = daytab[ct->tm_year-74].dayle; 105: } 106: daylbegin = sunday(ct, daylbegin); 107: daylend = sunday(ct, daylend); 108: if (systime.dstflag && 109: (dayno>daylbegin || (dayno==daylbegin && ct->tm_hour>=2)) && 110: (dayno<daylend || (dayno==daylend && ct->tm_hour<1))) { 111: copyt += 1*60*60; 112: ct = gmtime(©t); 113: ct->tm_isdst++; 114: } 115: return(ct); 116: } 117: 118: /* 119: * The argument is a 0-origin day number. 120: * The value is the day number of the first 121: * Sunday on or after the day. 122: */ 123: static 124: sunday(t, d) 125: register struct tm *t; 126: register int d; 127: { 128: if (d >= 58) 129: d += dysize(t->tm_year) - 365; 130: return(d - (d - t->tm_yday + t->tm_wday + 700) % 7); 131: } 132: 133: struct tm * 134: gmtime(tim) 135: long *tim; 136: { 137: register int d0, d1; 138: long hms, day; 139: register int *tp; 140: static struct tm xtime; 141: 142: /* 143: * break initial number into days 144: */ 145: hms = *tim % 86400; 146: day = *tim / 86400; 147: if (hms<0) { 148: hms += 86400; 149: day -= 1; 150: } 151: tp = (int *)&xtime; 152: 153: /* 154: * generate hours:minutes:seconds 155: */ 156: *tp++ = hms%60; 157: d1 = hms/60; 158: *tp++ = d1%60; 159: d1 /= 60; 160: *tp++ = d1; 161: 162: /* 163: * day is the day number. 164: * generate day of the week. 165: * The addend is 4 mod 7 (1/1/1970 was Thursday) 166: */ 167: 168: xtime.tm_wday = (day+7340036)%7; 169: 170: /* 171: * year number 172: */ 173: if (day>=0) for(d1=70; day >= dysize(d1); d1++) 174: day -= dysize(d1); 175: else for (d1=70; day<0; d1--) 176: day += dysize(d1-1); 177: xtime.tm_year = d1; 178: xtime.tm_yday = d0 = day; 179: 180: /* 181: * generate month 182: */ 183: 184: if (dysize(d1)==366) 185: dmsize[1] = 29; 186: for(d1=0; d0 >= dmsize[d1]; d1++) 187: d0 -= dmsize[d1]; 188: dmsize[1] = 28; 189: *tp++ = d0+1; 190: *tp++ = d1; 191: xtime.tm_isdst = 0; 192: return(&xtime); 193: } 194: 195: char * 196: asctime(t) 197: struct tm *t; 198: { 199: register char *cp, *ncp; 200: register int *tp; 201: 202: cp = cbuf; 203: for (ncp = "Day Mon 00 00:00:00 1900\n"; *cp++ = *ncp++;); 204: ncp = &"SunMonTueWedThuFriSat"[3*t->tm_wday]; 205: cp = cbuf; 206: *cp++ = *ncp++; 207: *cp++ = *ncp++; 208: *cp++ = *ncp++; 209: cp++; 210: tp = &t->tm_mon; 211: ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(*tp)*3]; 212: *cp++ = *ncp++; 213: *cp++ = *ncp++; 214: *cp++ = *ncp++; 215: cp = ct_numb(cp, *--tp); 216: cp = ct_numb(cp, *--tp+100); 217: cp = ct_numb(cp, *--tp+100); 218: cp = ct_numb(cp, *--tp+100); 219: if (t->tm_year>=100) { 220: cp[1] = '2'; 221: cp[2] = '0'; 222: } 223: cp += 2; 224: cp = ct_numb(cp, t->tm_year+100); 225: return(cbuf); 226: } 227: 228: dysize(y) 229: { 230: if((y%4) == 0) 231: return(366); 232: return(365); 233: } 234: 235: static char * 236: ct_numb(cp, n) 237: register char *cp; 238: { 239: cp++; 240: if (n>=10) 241: *cp++ = (n/10)%10 + '0'; 242: else 243: *cp++ = ' '; 244: *cp++ = n%10 + '0'; 245: return(cp); 246: }