1 /* @(#)ctime.c 4.1 (Berkeley) 12/21/80 */ 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 } 247