| /* | 
 |  * This routine converts time as follows. | 
 |  * The epoch is 0000 Jan 1 1970 GMT. | 
 |  * The argument time is in seconds since then. | 
 |  * The localtime(t) entry returns a pointer to an array | 
 |  * containing | 
 |  * | 
 |  *	seconds (0-59) | 
 |  *	minutes (0-59) | 
 |  *	hours (0-23) | 
 |  *	day of month (1-31) | 
 |  *	month (0-11) | 
 |  *	year-1970 | 
 |  *	weekday (0-6, Sun is 0) | 
 |  *	day of the year | 
 |  *	daylight savings flag | 
 |  * | 
 |  * The routine gets the daylight savings time from the environment. | 
 |  * | 
 |  * asctime(tvec)) | 
 |  * where tvec is produced by localtime | 
 |  * returns a ptr to a character string | 
 |  * that has the ascii time in the form | 
 |  * | 
 |  *	                            \\ | 
 |  *	Thu Jan 01 00:00:00 GMT 1970n0 | 
 |  *	012345678901234567890123456789 | 
 |  *	0	  1	    2 | 
 |  * | 
 |  * ctime(t) just calls localtime, then asctime. | 
 |  */ | 
 |  | 
 | #include <u.h> | 
 | #include <libc.h> | 
 |  | 
 | #include "zoneinfo.h" | 
 |  | 
 | static	char	dmsize[12] = | 
 | { | 
 | 	31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 | 
 | }; | 
 |  | 
 | #define dysize ctimedysize | 
 | static	int	dysize(int); | 
 | static	void	ct_numb(char*, int); | 
 |  | 
 | char* | 
 | ctime(long t) | 
 | { | 
 | 	return asctime(localtime(t)); | 
 | } | 
 |  | 
 | Tm* | 
 | localtime(long tim) | 
 | { | 
 | 	Tinfo ti; | 
 | 	Tm *ct; | 
 |  | 
 | 	if (zonelookuptinfo(&ti, tim)!=-1) { | 
 | 		ct = gmtime(tim+ti.tzoff); | 
 | 		strncpy(ct->zone, ti.zone, sizeof ct->zone); | 
 | 		ct->zone[sizeof ct->zone-1] = 0; | 
 | 		ct->tzoff = ti.tzoff; | 
 | 		return ct; | 
 | 	} | 
 | 	return gmtime(tim); | 
 | } | 
 |  | 
 | Tm* | 
 | gmtime(long tim) | 
 | { | 
 | 	int d0, d1; | 
 | 	long hms, day; | 
 | 	static Tm xtime; | 
 |  | 
 | 	/* | 
 | 	 * break initial number into days | 
 | 	 */ | 
 | 	hms = tim % 86400L; | 
 | 	day = tim / 86400L; | 
 | 	if(hms < 0) { | 
 | 		hms += 86400L; | 
 | 		day -= 1; | 
 | 	} | 
 |  | 
 | 	/* | 
 | 	 * generate hours:minutes:seconds | 
 | 	 */ | 
 | 	xtime.sec = hms % 60; | 
 | 	d1 = hms / 60; | 
 | 	xtime.min = d1 % 60; | 
 | 	d1 /= 60; | 
 | 	xtime.hour = d1; | 
 |  | 
 | 	/* | 
 | 	 * day is the day number. | 
 | 	 * generate day of the week. | 
 | 	 * The addend is 4 mod 7 (1/1/1970 was Thursday) | 
 | 	 */ | 
 |  | 
 | 	xtime.wday = (day + 7340036L) % 7; | 
 |  | 
 | 	/* | 
 | 	 * year number | 
 | 	 */ | 
 | 	if(day >= 0) | 
 | 		for(d1 = 1970; day >= dysize(d1); d1++) | 
 | 			day -= dysize(d1); | 
 | 	else | 
 | 		for (d1 = 1970; day < 0; d1--) | 
 | 			day += dysize(d1-1); | 
 | 	xtime.year = d1-1900; | 
 | 	xtime.yday = d0 = day; | 
 |  | 
 | 	/* | 
 | 	 * generate month | 
 | 	 */ | 
 |  | 
 | 	if(dysize(d1) == 366) | 
 | 		dmsize[1] = 29; | 
 | 	for(d1 = 0; d0 >= dmsize[d1]; d1++) | 
 | 		d0 -= dmsize[d1]; | 
 | 	dmsize[1] = 28; | 
 | 	xtime.mday = d0 + 1; | 
 | 	xtime.mon = d1; | 
 | 	strcpy(xtime.zone, "GMT"); | 
 | 	return &xtime; | 
 | } | 
 |  | 
 | char* | 
 | asctime(Tm *t) | 
 | { | 
 | 	const char *ncp; | 
 | 	static char cbuf[30]; | 
 |  | 
 | 	strcpy(cbuf, "Thu Jan 01 00:00:00 GMT 1970\n"); | 
 | 	ncp = &"SunMonTueWedThuFriSat"[t->wday*3]; | 
 | 	cbuf[0] = *ncp++; | 
 | 	cbuf[1] = *ncp++; | 
 | 	cbuf[2] = *ncp; | 
 | 	ncp = &"JanFebMarAprMayJunJulAugSepOctNovDec"[t->mon*3]; | 
 | 	cbuf[4] = *ncp++; | 
 | 	cbuf[5] = *ncp++; | 
 | 	cbuf[6] = *ncp; | 
 | 	ct_numb(cbuf+8, t->mday); | 
 | 	ct_numb(cbuf+11, t->hour+100); | 
 | 	ct_numb(cbuf+14, t->min+100); | 
 | 	ct_numb(cbuf+17, t->sec+100); | 
 | 	ncp = t->zone; | 
 | 	cbuf[20] = *ncp++; | 
 | 	cbuf[21] = *ncp++; | 
 | 	cbuf[22] = *ncp; | 
 | 	if(t->year >= 100) { | 
 | 		cbuf[24] = '2'; | 
 | 		cbuf[25] = '0'; | 
 | 	} | 
 | 	ct_numb(cbuf+26, t->year+100); | 
 | 	return cbuf; | 
 | } | 
 |  | 
 | static | 
 | int | 
 | dysize(int y) | 
 | { | 
 |  | 
 | 	if(y%4 == 0 && (y%100 != 0 || y%400 == 0)) | 
 | 		return 366; | 
 | 	return 365; | 
 | } | 
 |  | 
 | static | 
 | void | 
 | ct_numb(char *cp, int n) | 
 | { | 
 |  | 
 | 	cp[0] = ' '; | 
 | 	if(n >= 10) | 
 | 		cp[0] = (n/10)%10 + '0'; | 
 | 	cp[1] = n%10 + '0'; | 
 | } | 
 |  |