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