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