1*13743Ssam #include "../hdr/macros.h" 22158Seric 3*13743Ssam SCCSID(@(#)ctime.c 4.2); 42158Seric 52158Seric /* 62158Seric * This routine converts time as follows. 72158Seric * The epoch is 0000 Jan 1 1970 GMT. 82158Seric * The argument time is in seconds since then. 92158Seric * The localtime(t) entry returns a pointer to an array 102158Seric * containing 112158Seric * seconds (0-59) 122158Seric * minutes (0-59) 132158Seric * hours (0-23) 142158Seric * day of month (1-31) 152158Seric * month (0-11) 162158Seric * year-1970 172158Seric * weekday (0-6, Sun is 0) 182158Seric * day of the year 192158Seric * daylight savings flag 202158Seric * 212158Seric * The routine calls the system to determine the local 222158Seric * timezone and whether Daylight Saving Time is permitted locally. 232158Seric * (DST is then determined by the current US standard rules) 242158Seric * There is a table that accounts for the peculiarities 252158Seric * undergone by daylight time in 1974-1975. 262158Seric * 272158Seric * The routine does not work 282158Seric * in Saudi Arabia which runs on Solar time. 292158Seric * 302158Seric * asctime(tvec)) 312158Seric * where tvec is produced by localtime 322158Seric * returns a ptr to a character string 332158Seric * that has the ascii time in the form 342158Seric * Thu Jan 01 00:00:00 1970n0\\ 352158Seric * 01234567890123456789012345 362158Seric * 0 1 2 372158Seric * 382158Seric * ctime(t) just calls localtime, then asctime. 392158Seric */ 402158Seric 41*13743Ssam #include <sys/time.h> 422158Seric #include <sys/types.h> 432158Seric #include <sys/timeb.h> 442158Seric 452158Seric static char cbuf[26]; 462158Seric int dmsize[12] = 472158Seric { 482158Seric 31, 492158Seric 28, 502158Seric 31, 512158Seric 30, 522158Seric 31, 532158Seric 30, 542158Seric 31, 552158Seric 31, 562158Seric 30, 572158Seric 31, 582158Seric 30, 592158Seric 31 602158Seric }; 612158Seric 622158Seric /* 632158Seric * The following table is used for 1974 and 1975 and 642158Seric * gives the day number of the first day after the Sunday of the 652158Seric * change. 662158Seric */ 672158Seric static struct { 682158Seric int daylb; 692158Seric int dayle; 702158Seric } daytab[] = { 712158Seric 5, 333, /* 1974: Jan 6 - last Sun. in Nov */ 722158Seric 58, 303, /* 1975: Last Sun. in Feb - last Sun in Oct */ 732158Seric }; 742158Seric 752158Seric struct tm *gmtime(); 762158Seric char *ct_numb(); 772158Seric struct tm *localtime(); 782158Seric char *ctime(); 792158Seric char *ct_num(); 802158Seric char *asctime(); 812158Seric 822158Seric char * 832158Seric ctime(t) 842158Seric long *t; 852158Seric { 862158Seric return(asctime(localtime(t))); 872158Seric } 882158Seric 892158Seric struct tm * 902158Seric localtime(tim) 912158Seric long *tim; 922158Seric { 932158Seric register int dayno; 942158Seric register struct tm *ct; 952158Seric register daylbegin, daylend; 962158Seric long copyt; 972158Seric struct timeb systime; 982158Seric 992158Seric ftime(&systime); 1002158Seric copyt = *tim - (long)systime.timezone*60; 1012158Seric ct = gmtime(©t); 1022158Seric dayno = ct->tm_yday; 1032158Seric daylbegin = 119; /* last Sun in Apr */ 1042158Seric daylend = 303; /* Last Sun in Oct */ 1052158Seric if (ct->tm_year==74 || ct->tm_year==75) { 1062158Seric daylbegin = daytab[ct->tm_year-74].daylb; 1072158Seric daylend = daytab[ct->tm_year-74].dayle; 1082158Seric } 1092158Seric daylbegin = sunday(ct, daylbegin); 1102158Seric daylend = sunday(ct, daylend); 1112158Seric if (systime.dstflag && 1122158Seric (dayno>daylbegin || (dayno==daylbegin && ct->tm_hour>=2)) && 1132158Seric (dayno<daylend || (dayno==daylend && ct->tm_hour<1))) { 1142158Seric copyt += 1*60*60; 1152158Seric ct = gmtime(©t); 1162158Seric ct->tm_isdst++; 1172158Seric } 1182158Seric return(ct); 1192158Seric } 1202158Seric 1212158Seric /* 1222158Seric * The argument is a 0-origin day number. 1232158Seric * The value is the day number of the first 1242158Seric * Sunday on or after the day. 1252158Seric */ 1262158Seric static 1272158Seric sunday(t, d) 1282158Seric register struct tm *t; 1292158Seric register int d; 1302158Seric { 1312158Seric if (d >= 58) 1322158Seric d += dysize(t->tm_year) - 365; 1332158Seric return(d - (d - t->tm_yday + t->tm_wday + 700) % 7); 1342158Seric } 1352158Seric 1362158Seric struct tm * 1372158Seric gmtime(tim) 1382158Seric long *tim; 1392158Seric { 1402158Seric register int d0, d1; 1412158Seric long hms, day; 1422158Seric register int *tp; 1432158Seric static struct tm xtime; 1442158Seric 1452158Seric /* 1462158Seric * break initial number into days 1472158Seric */ 1482158Seric hms = *tim % 86400; 1492158Seric day = *tim / 86400; 1502158Seric if (hms<0) { 1512158Seric hms += 86400; 1522158Seric day -= 1; 1532158Seric } 1542158Seric tp = (int *)&xtime; 1552158Seric 1562158Seric /* 1572158Seric * generate hours:minutes:seconds 1582158Seric */ 1592158Seric *tp++ = hms%60; 1602158Seric d1 = hms/60; 1612158Seric *tp++ = d1%60; 1622158Seric d1 /= 60; 1632158Seric *tp++ = d1; 1642158Seric 1652158Seric /* 1662158Seric * day is the day number. 1672158Seric * generate day of the week. 1682158Seric * The addend is 4 mod 7 (1/1/1970 was Thursday) 1692158Seric */ 1702158Seric 1712158Seric xtime.tm_wday = (day+7340036)%7; 1722158Seric 1732158Seric /* 1742158Seric * year number 1752158Seric */ 1762158Seric if (day>=0) for(d1=70; day >= dysize(d1); d1++) 1772158Seric day -= dysize(d1); 1782158Seric else for (d1=70; day<0; d1--) 1792158Seric day += dysize(d1-1); 1802158Seric xtime.tm_year = d1; 1812158Seric xtime.tm_yday = d0 = day; 1822158Seric 1832158Seric /* 1842158Seric * generate month 1852158Seric */ 1862158Seric 1872158Seric if (dysize(d1)==366) 1882158Seric dmsize[1] = 29; 1892158Seric for(d1=0; d0 >= dmsize[d1]; d1++) 1902158Seric d0 -= dmsize[d1]; 1912158Seric dmsize[1] = 28; 1922158Seric *tp++ = d0+1; 1932158Seric *tp++ = d1; 1942158Seric xtime.tm_isdst = 0; 1952158Seric return(&xtime); 1962158Seric } 1972158Seric 1982158Seric char * 1992158Seric asctime(t) 2002158Seric struct tm *t; 2012158Seric { 2022158Seric register char *cp, *ncp; 2032158Seric register int *tp; 2042158Seric 2052158Seric cp = cbuf; 2062158Seric for (ncp = "Day Mon 00 00:00:00 1900\n"; *cp++ = *ncp++;); 2072158Seric ncp = &"SunMonTueWedThuFriSat"[3*t->tm_wday]; 2082158Seric cp = cbuf; 2092158Seric *cp++ = *ncp++; 2102158Seric *cp++ = *ncp++; 2112158Seric *cp++ = *ncp++; 2122158Seric cp++; 2132158Seric tp = &t->tm_mon; 2142158Seric ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(*tp)*3]; 2152158Seric *cp++ = *ncp++; 2162158Seric *cp++ = *ncp++; 2172158Seric *cp++ = *ncp++; 2182158Seric cp = ct_numb(cp, *--tp); 2192158Seric cp = ct_numb(cp, *--tp+100); 2202158Seric cp = ct_numb(cp, *--tp+100); 2212158Seric cp = ct_numb(cp, *--tp+100); 2222158Seric if (t->tm_year>=100) { 2232158Seric cp[1] = '2'; 2242158Seric cp[2] = '0'; 2252158Seric } 2262158Seric cp += 2; 2272158Seric cp = ct_numb(cp, t->tm_year+100); 2282158Seric return(cbuf); 2292158Seric } 2302158Seric 2312158Seric dysize(y) 2322158Seric { 2332158Seric if((y%4) == 0) 2342158Seric return(366); 2352158Seric return(365); 2362158Seric } 2372158Seric 2382158Seric static char * 2392158Seric ct_numb(cp, n) 2402158Seric register char *cp; 2412158Seric { 2422158Seric cp++; 2432158Seric if (n>=10) 2442158Seric *cp++ = (n/10)%10 + '0'; 2452158Seric else 2462158Seric *cp++ = ' '; 2472158Seric *cp++ = n%10 + '0'; 2482158Seric return(cp); 2492158Seric } 250