113743Ssam #include "../hdr/macros.h"
22158Seric
3*19922Ssam SCCSID(@(#)ctime.c 4.3);
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*19922Ssam #ifdef notdef
42*19922Ssam #include <sys/types.h> /* included by macros.h above */
43*19922Ssam #endif
4413743Ssam #include <sys/time.h>
452158Seric #include <sys/timeb.h>
462158Seric
472158Seric static char cbuf[26];
482158Seric int dmsize[12] =
492158Seric {
502158Seric 31,
512158Seric 28,
522158Seric 31,
532158Seric 30,
542158Seric 31,
552158Seric 30,
562158Seric 31,
572158Seric 31,
582158Seric 30,
592158Seric 31,
602158Seric 30,
612158Seric 31
622158Seric };
632158Seric
642158Seric /*
652158Seric * The following table is used for 1974 and 1975 and
662158Seric * gives the day number of the first day after the Sunday of the
672158Seric * change.
682158Seric */
692158Seric static struct {
702158Seric int daylb;
712158Seric int dayle;
722158Seric } daytab[] = {
732158Seric 5, 333, /* 1974: Jan 6 - last Sun. in Nov */
742158Seric 58, 303, /* 1975: Last Sun. in Feb - last Sun in Oct */
752158Seric };
762158Seric
772158Seric struct tm *gmtime();
782158Seric char *ct_numb();
792158Seric struct tm *localtime();
802158Seric char *ctime();
812158Seric char *ct_num();
822158Seric char *asctime();
832158Seric
842158Seric char *
ctime(t)852158Seric ctime(t)
862158Seric long *t;
872158Seric {
882158Seric return(asctime(localtime(t)));
892158Seric }
902158Seric
912158Seric struct tm *
localtime(tim)922158Seric localtime(tim)
932158Seric long *tim;
942158Seric {
952158Seric register int dayno;
962158Seric register struct tm *ct;
972158Seric register daylbegin, daylend;
982158Seric long copyt;
992158Seric struct timeb systime;
1002158Seric
1012158Seric ftime(&systime);
1022158Seric copyt = *tim - (long)systime.timezone*60;
1032158Seric ct = gmtime(©t);
1042158Seric dayno = ct->tm_yday;
1052158Seric daylbegin = 119; /* last Sun in Apr */
1062158Seric daylend = 303; /* Last Sun in Oct */
1072158Seric if (ct->tm_year==74 || ct->tm_year==75) {
1082158Seric daylbegin = daytab[ct->tm_year-74].daylb;
1092158Seric daylend = daytab[ct->tm_year-74].dayle;
1102158Seric }
1112158Seric daylbegin = sunday(ct, daylbegin);
1122158Seric daylend = sunday(ct, daylend);
1132158Seric if (systime.dstflag &&
1142158Seric (dayno>daylbegin || (dayno==daylbegin && ct->tm_hour>=2)) &&
1152158Seric (dayno<daylend || (dayno==daylend && ct->tm_hour<1))) {
1162158Seric copyt += 1*60*60;
1172158Seric ct = gmtime(©t);
1182158Seric ct->tm_isdst++;
1192158Seric }
1202158Seric return(ct);
1212158Seric }
1222158Seric
1232158Seric /*
1242158Seric * The argument is a 0-origin day number.
1252158Seric * The value is the day number of the first
1262158Seric * Sunday on or after the day.
1272158Seric */
1282158Seric static
sunday(t,d)1292158Seric sunday(t, d)
1302158Seric register struct tm *t;
1312158Seric register int d;
1322158Seric {
1332158Seric if (d >= 58)
1342158Seric d += dysize(t->tm_year) - 365;
1352158Seric return(d - (d - t->tm_yday + t->tm_wday + 700) % 7);
1362158Seric }
1372158Seric
1382158Seric struct tm *
gmtime(tim)1392158Seric gmtime(tim)
1402158Seric long *tim;
1412158Seric {
1422158Seric register int d0, d1;
1432158Seric long hms, day;
1442158Seric register int *tp;
1452158Seric static struct tm xtime;
1462158Seric
1472158Seric /*
1482158Seric * break initial number into days
1492158Seric */
1502158Seric hms = *tim % 86400;
1512158Seric day = *tim / 86400;
1522158Seric if (hms<0) {
1532158Seric hms += 86400;
1542158Seric day -= 1;
1552158Seric }
1562158Seric tp = (int *)&xtime;
1572158Seric
1582158Seric /*
1592158Seric * generate hours:minutes:seconds
1602158Seric */
1612158Seric *tp++ = hms%60;
1622158Seric d1 = hms/60;
1632158Seric *tp++ = d1%60;
1642158Seric d1 /= 60;
1652158Seric *tp++ = d1;
1662158Seric
1672158Seric /*
1682158Seric * day is the day number.
1692158Seric * generate day of the week.
1702158Seric * The addend is 4 mod 7 (1/1/1970 was Thursday)
1712158Seric */
1722158Seric
1732158Seric xtime.tm_wday = (day+7340036)%7;
1742158Seric
1752158Seric /*
1762158Seric * year number
1772158Seric */
1782158Seric if (day>=0) for(d1=70; day >= dysize(d1); d1++)
1792158Seric day -= dysize(d1);
1802158Seric else for (d1=70; day<0; d1--)
1812158Seric day += dysize(d1-1);
1822158Seric xtime.tm_year = d1;
1832158Seric xtime.tm_yday = d0 = day;
1842158Seric
1852158Seric /*
1862158Seric * generate month
1872158Seric */
1882158Seric
1892158Seric if (dysize(d1)==366)
1902158Seric dmsize[1] = 29;
1912158Seric for(d1=0; d0 >= dmsize[d1]; d1++)
1922158Seric d0 -= dmsize[d1];
1932158Seric dmsize[1] = 28;
1942158Seric *tp++ = d0+1;
1952158Seric *tp++ = d1;
1962158Seric xtime.tm_isdst = 0;
1972158Seric return(&xtime);
1982158Seric }
1992158Seric
2002158Seric char *
asctime(t)2012158Seric asctime(t)
2022158Seric struct tm *t;
2032158Seric {
2042158Seric register char *cp, *ncp;
2052158Seric register int *tp;
2062158Seric
2072158Seric cp = cbuf;
2082158Seric for (ncp = "Day Mon 00 00:00:00 1900\n"; *cp++ = *ncp++;);
2092158Seric ncp = &"SunMonTueWedThuFriSat"[3*t->tm_wday];
2102158Seric cp = cbuf;
2112158Seric *cp++ = *ncp++;
2122158Seric *cp++ = *ncp++;
2132158Seric *cp++ = *ncp++;
2142158Seric cp++;
2152158Seric tp = &t->tm_mon;
2162158Seric ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[(*tp)*3];
2172158Seric *cp++ = *ncp++;
2182158Seric *cp++ = *ncp++;
2192158Seric *cp++ = *ncp++;
2202158Seric cp = ct_numb(cp, *--tp);
2212158Seric cp = ct_numb(cp, *--tp+100);
2222158Seric cp = ct_numb(cp, *--tp+100);
2232158Seric cp = ct_numb(cp, *--tp+100);
2242158Seric if (t->tm_year>=100) {
2252158Seric cp[1] = '2';
2262158Seric cp[2] = '0';
2272158Seric }
2282158Seric cp += 2;
2292158Seric cp = ct_numb(cp, t->tm_year+100);
2302158Seric return(cbuf);
2312158Seric }
2322158Seric
dysize(y)2332158Seric dysize(y)
2342158Seric {
2352158Seric if((y%4) == 0)
2362158Seric return(366);
2372158Seric return(365);
2382158Seric }
2392158Seric
2402158Seric static char *
ct_numb(cp,n)2412158Seric ct_numb(cp, n)
2422158Seric register char *cp;
2432158Seric {
2442158Seric cp++;
2452158Seric if (n>=10)
2462158Seric *cp++ = (n/10)%10 + '0';
2472158Seric else
2482158Seric *cp++ = ' ';
2492158Seric *cp++ = n%10 + '0';
2502158Seric return(cp);
2512158Seric }
252