/*
 *			c t i m e . c
 */

/*)LIBRARY
*/

#ifdef	DOCUMENTATION

title	ctime	Convert time value to ascii
index		Convert time value to ascii
index	asctime	Convert time buffer to ascii
index	localtime Convert time() to time buffer

Usage
	.s.nf
	#include <time.h>

	char *
	ctime(tloc)
	long		*tloc;	/* Time value pointer	*/

	char *
	asctime(tm)
	struct tm	*tm;	/* Time buffer pointer	*/

	struct tm *
	localtime(tloc)
	.s.f
Description

	ctime() converts a time value, as returned by time()
	to an ascii string.  For compatibility with previous
	versions, ctime(NULL) obtains and converts the current
	time of day and removes the trailing newline. Note,
	however, that ctime(NULL) is not portable.

	asctime() converts a time vector, as returned by localtime()
	to an ascii string which is statically allocated.  It has
	the format
 
		Sun Sep 16 01:03:52 1973\n\0
		012345678901234567890123 4 5
		0         1         2

	All the fields have constant width.  To remove the trailing
	newline, just:

	    char	*tp;
	    extern char	*ctime();
	    long	tloc;

	    time(&tloc);		/* Get time	*/
	    tp = ctime(&tloc);		/* in Ascii	*/
	    tp[24] = '\0';		/* Fix newline	*/

	localtime() converts the time() value (seconds since Jan. 1,
	1970) to a structure containing the components:

	    struct tm {
		int  tm_sec;	/* Seconds		*/
		int  tm_min;	/* Minutes		*/
		int  tm_hour;	/* Hours		*/
		int  tm_mday;	/* Day in month		*/
		int  tm_mon;	/* Month, Jan = 0	*/
		int  tm_year;	/* Year - 1900		*/
		int  tm_wday;	/* Day in week, Sun = 0	*/
		int  tm_yday;	/* Days since Jan 1	*/
		int  tm_isdst;	/* Daylight savings	*/
	    }

Bugs

	There is no range checking on the information passed.

#endif

#include	<stdio.h>
#include	<time.h>
#ifdef	M68000
#include	<nanoc.h>
#endif
#define	EOS	0
#define	FALSE	0
#define	TRUE	1

char *
ctime(tloc)
register long	*tloc;
/*
 * Convert time() value to ascii string.
 */
{
	long			temptime;
	register char		*result;
	extern char		*asctime();
	extern struct tm	*localtime();

	if (tloc == (long *)NULL) {
	    time(&temptime);
	    result = ctime(&temptime);
	    result[24] = EOS;
	}
	else return (asctime(localtime(tloc)));
}

#ifdef		M68000
RAM_SECT(ram00)
#endif

static char	ctime_work[25];

#ifdef		M68000
ROM_SECT(rom00)
#endif

char	dayname[] = "SunMonTueWedThuFriSat";
char	monname[] = "JanFebMarAprMayJunJulAugSepOctNovDec";

#ifdef	M68000
IRAM_SECT(iram00)
#endif

static short montab[] = {
	31, 28, 31, 30, 31, 30,	/* Thirty days hath September		*/
	31, 31, 30, 31, 30, 31,	/* All the rest I don't remember	*/
};

#ifdef	M68000
ROM_SECT(strings)
#endif

char *
asctime(tm)
register struct tm	*tm;
/*
 * Format the time buffer
 */
{
	sprintf(ctime_work, "%.3s %.3s %2d %02d:%02d:%02d %4d\n",
	    &dayname[tm->tm_wday * 3],
	    &monname[tm->tm_mon  * 3],
	    tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec,
	    tm->tm_year + 1900);
	return (ctime_work);
}

static struct tm tbuf;

struct tm *
localtime(tloc)
long		*tloc;
/*
 * Break time() value into its component parts.
 */
{
	register long		tod;
	register short		todi;		/* For year.day		*/
	register short		diy;		/* Days in this year	*/
	register short		temp;

	if ((tod = *tloc) < 0)
	    tod = 0;
	tbuf.tm_sec  = tod % 60;	tod /= 60;
	tbuf.tm_min  = tod % 60;	tod /= 60;
	tbuf.tm_hour = tod % 24;	todi = tod / 24;
	tbuf.tm_wday = (todi + 4) % 7;
	for (temp = 70; (diy = 365 + (((temp & 3) == 0) ? 1 : 0)) < todi;) {
	    temp++;
	    todi -= diy;
	}
	tbuf.tm_year = temp;
	tbuf.tm_yday = todi;
	for (temp = 0; todi >= montab[temp]; temp++) {
	    todi -= montab[temp];
	    if (temp == 1 && (tbuf.tm_year & 3) == 0)
		todi--;
	}
	tbuf.tm_mon = temp;
	tbuf.tm_mday = todi + 1;
	return (&tbuf);
}

#ifdef	M68000
ROM_SECT(const)
#endif

#ifdef	TESTING

main() {
	long		tvec;

	time(&tvec);
	printf(ctime(&tvec));
}
#endif
