1 #include "../hdr/macros.h" 2 3 SCCSID(@(#)ctime.c 4.3); 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 #ifdef notdef 42 #include <sys/types.h> /* included by macros.h above */ 43 #endif 44 #include <sys/time.h> 45 #include <sys/timeb.h> 46 47 static char cbuf[26]; 48 int dmsize[12] = 49 { 50 31, 51 28, 52 31, 53 30, 54 31, 55 30, 56 31, 57 31, 58 30, 59 31, 60 30, 61 31 62 }; 63 64 /* 65 * The following table is used for 1974 and 1975 and 66 * gives the day number of the first day after the Sunday of the 67 * change. 68 */ 69 static struct { 70 int daylb; 71 int dayle; 72 } daytab[] = { 73 5, 333, /* 1974: Jan 6 - last Sun. in Nov */ 74 58, 303, /* 1975: Last Sun. in Feb - last Sun in Oct */ 75 }; 76 77 struct tm *gmtime(); 78 char *ct_numb(); 79 struct tm *localtime(); 80 char *ctime(); 81 char *ct_num(); 82 char *asctime(); 83 84 char * 85 ctime(t) 86 long *t; 87 { 88 return(asctime(localtime(t))); 89 } 90 91 struct tm * 92 localtime(tim) 93 long *tim; 94 { 95 register int dayno; 96 register struct tm *ct; 97 register daylbegin, daylend; 98 long copyt; 99 struct timeb systime; 100 101 ftime(&systime); 102 copyt = *tim - (long)systime.timezone*60; 103 ct = gmtime(©t); 104 dayno = ct->tm_yday; 105 daylbegin = 119; /* last Sun in Apr */ 106 daylend = 303; /* Last Sun in Oct */ 107 if (ct->tm_year==74 || ct->tm_year==75) { 108 daylbegin = daytab[ct->tm_year-74].daylb; 109 daylend = daytab[ct->tm_year-74].dayle; 110 } 111 daylbegin = sunday(ct, daylbegin); 112 daylend = sunday(ct, daylend); 113 if (systime.dstflag && 114 (dayno>daylbegin || (dayno==daylbegin && ct->tm_hour>=2)) && 115 (dayno<daylend || (dayno==daylend && ct->tm_hour<1))) { 116 copyt += 1*60*60; 117 ct = gmtime(©t); 118 ct->tm_isdst++; 119 } 120 return(ct); 121 } 122 123 /* 124 * The argument is a 0-origin day number. 125 * The value is the day number of the first 126 * Sunday on or after the day. 127 */ 128 static 129 sunday(t, d) 130 register struct tm *t; 131 register int d; 132 { 133 if (d >= 58) 134 d += dysize(t->tm_year) - 365; 135 return(d - (d - t->tm_yday + t->tm_wday + 700) % 7); 136 } 137 138 struct tm * 139 gmtime(tim) 140 long *tim; 141 { 142 register int d0, d1; 143 long hms, day; 144 register int *tp; 145 static struct tm xtime; 146 147 /* 148 * break initial number into days 149 */ 150 hms = *tim % 86400; 151 day = *tim / 86400; 152 if (hms<0) { 153 hms += 86400; 154 day -= 1; 155 } 156 tp = (int *)&xtime; 157 158 /* 159 * generate hours:minutes:seconds 160 */ 161 *tp++ = hms%60; 162 d1 = hms/60; 163 *tp++ = d1%60; 164 d1 /= 60; 165 *tp++ = d1; 166 167 /* 168 * day is the day number. 169 * generate day of the week. 170 * The addend is 4 mod 7 (1/1/1970 was Thursday) 171 */ 172 173 xtime.tm_wday = (day+7340036)%7; 174 175 /* 176 * year number 177 */ 178 if (day>=0) for(d1=70; day >= dysize(d1); d1++) 179 day -= dysize(d1); 180 else for (d1=70; day<0; d1--) 181 day += dysize(d1-1); 182 xtime.tm_year = d1; 183 xtime.tm_yday = d0 = day; 184 185 /* 186 * generate month 187 */ 188 189 if (dysize(d1)==366) 190 dmsize[1] = 29; 191 for(d1=0; d0 >= dmsize[d1]; d1++) 192 d0 -= dmsize[d1]; 193 dmsize[1] = 28; 194 *tp++ = d0+1; 195 *tp++ = d1; 196 xtime.tm_isdst = 0; 197 return(&xtime); 198 } 199 200 char * 201 asctime(t) 202 struct tm *t; 203 { 204 register char *cp, *ncp; 205 register int *tp; 206 207 cp = cbuf; 208 for (ncp = "Day Mon 00 00:00:00 1900\n"; *cp++ = *ncp++;); 209 ncp = &"SunMonTueWedThuFriSat"[3*t->tm_wday]; 210 cp = cbuf; 211 *cp++ = *ncp++; 212 *cp++ = *ncp++; 213 *cp++ = *ncp++; 214 cp++; 215 tp = &t->tm_mon; 216 ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(*tp)*3]; 217 *cp++ = *ncp++; 218 *cp++ = *ncp++; 219 *cp++ = *ncp++; 220 cp = ct_numb(cp, *--tp); 221 cp = ct_numb(cp, *--tp+100); 222 cp = ct_numb(cp, *--tp+100); 223 cp = ct_numb(cp, *--tp+100); 224 if (t->tm_year>=100) { 225 cp[1] = '2'; 226 cp[2] = '0'; 227 } 228 cp += 2; 229 cp = ct_numb(cp, t->tm_year+100); 230 return(cbuf); 231 } 232 233 dysize(y) 234 { 235 if((y%4) == 0) 236 return(366); 237 return(365); 238 } 239 240 static char * 241 ct_numb(cp, n) 242 register char *cp; 243 { 244 cp++; 245 if (n>=10) 246 *cp++ = (n/10)%10 + '0'; 247 else 248 *cp++ = ' '; 249 *cp++ = n%10 + '0'; 250 return(cp); 251 } 252