[comp.lang.c] System V-compatible ctime

wnp@iiasa.AT (wolf paul) (08/30/90)

In order to compile the recently-posted "ago" program, I am looking
for a System V or POSIX-compatible ctime(3) library. Specifically,
I need a cftime() or strftime() routine.

Thanks!
-- 
Wolf N. Paul, IIASA, A - 2361 Laxenburg, Austria, Europe
PHONE: +43-2236-71521-465     FAX: +43-2236-71313      UUCP: uunet!iiasa.at!wnp
INTERNET: wnp%iiasa.at@uunet.uu.net      BITNET: tuvie!iiasa!wnp@awiuni01.BITNET
       * * * * Kurt Waldheim for President (of Mars, of course!) * * * *

bdb@becker.UUCP (Bruce D. Becker) (09/01/90)

In article <862@iiasa.UUCP> wnp@iiasa.UUCP (wolf paul) writes:
>In order to compile the recently-posted "ago" program, I am looking
>for a System V or POSIX-compatible ctime(3) library. Specifically,
>I need a cftime() or strftime() routine.

	Although not perfect, the code included below
	ought to handle the situation OK...


 --------- 8< --------- 8< --------- 8< --------- 8< --------- 8< ---------

#ifdef BSD
#include	<sys/time.h>
#else
#include	<time.h>
#endif

static char	*amon[] = {	"Jan","Feb","Mar","Apr","May","Jun",
				"Jul","Aug","Sep","Oct","Nov","Dec" };
static char	*lmon[] = {	"January","February","March",
				"April","May","June",
				"July","August","September",
				"October","November","December" };
static char	*awkd[] = {	"Sun","Mon","Tue","Wed","Thu","Fri","Sat" };
static char	*lwkd[] = {	"Sunday","Monday","Tuesday","Wednesday",
				"Thursday","Friday","Saturday" };

int	cftime(buf, fmt, clock)
char	*buf, *fmt;
long	*clock;
{

	char		c, *ctmp, *bb;
	int		i;
	struct tm	*lt;

	if (fmt == (char *)0 || *fmt == '\0') fmt = "%a %b %d %T %Z %Y";
	lt = localtime(clock);
	bb = buf;
	while(c = *(fmt++)) {
		if (c != '%') *(buf++) = c;
		else switch(c = *(fmt++)) {
		case 'a':
			ctmp = awkd[lt->tm_wday];
			while (*(buf++) = *(ctmp++));
			--buf;
			break;
		case 'A':
			ctmp = lwkd[lt->tm_wday];
			while (*(buf++) = *(ctmp++));
			--buf;
			break;
		case 'b':
		case 'h':
			ctmp = amon[lt->tm_mon];
			while (*(buf++) = *(ctmp++));
			--buf;
			break;
		case 'B':
			ctmp = lmon[lt->tm_mon];
			while (*(buf++) = *(ctmp++));
			--buf;
			break;
		case 'd':
			sprintf(buf, "%02d", lt->tm_mday);
			buf += 2;
			break;
		case 'D':
		case 'x':
			sprintf(buf, "%02d/%02d/%02d",
			lt->tm_mon+1, lt->tm_mday, lt->tm_year);
			buf += 8;
			break;
		case 'e':
			sprintf(buf, "%2d", lt->tm_mday);
			buf += 2;
			break;
		case 'H':
			sprintf(buf, "%02d", lt->tm_hour);
			buf += 2;
			break;
		case 'I':
			i = lt->tm_hour % 12;
			sprintf(buf, "%02d", i?i:12);
			buf += 2;
			break;
		case 'j':
			sprintf(buf, "%03d", lt->tm_yday+1);
			buf += 3;
			break;
		case 'm':
			sprintf(buf, "%2d", lt->tm_mon+1);
			buf += 2;
			break;
		case 'M':
			sprintf(buf, "%02d", lt->tm_min);
			buf += 2;
			break;
		case 'n':
			*(buf++) = '\n';
			break;
		case 'r':
			i = lt->tm_hour % 12;
			sprintf(buf, "%02d:%02d:%02d ",
			i?i:12, lt->tm_min, lt->tm_sec);
			buf += 9;
		case 'p':
			if (lt->tm_hour <12 ) *(buf++) = 'A';
			else *(buf++) = 'P';
			*(buf++) = 'M';
			break;
		case 'R':
			sprintf(buf, "%02d:%02d",
			lt->tm_hour, lt->tm_min);
			buf += 5;
			break;
		case 'S':
			sprintf(buf, "%2d", lt->tm_sec);
			buf += 2;
			break;
		case 't':
			*(buf++) = '\t';
			break;
		case 'T':
		case 'X':
			sprintf(buf, "%02d:%02d:%02d",
			lt->tm_hour, lt->tm_min, lt->tm_sec);
			buf += 8;
			break;
		case 'U':
			sprintf(buf, "%2d", ((lt->tm_yday+7-lt->tm_wday)/7)+1);
			buf += 2;
			break;
		case 'w':
			sprintf(buf, "%1d", lt->tm_wday);
			buf += 1;
			break;
		case 'W':
			sprintf(buf, "%2d", ((lt->tm_yday+6-lt->tm_wday)/7)+1);
			buf += 2;
			break;
		case 'y':
			sprintf(buf, "%2d", lt->tm_year);
			buf += 2;
			break;
		case 'Y':
			if ((i = lt->tm_year) < 70) i += 100;
			i += 1900; 
			sprintf(buf, "%4d", i);
			buf += 4;
			break;
		case 'Z':
#ifdef BSD
			{
				struct timeval	tp;
				struct timezone	tz;

				gettimeofday(&tp, &tz);
				ctmp = (char *)timezone(tz.tz_minuteswest,
					lt->tm_isdst);
			}
#else
			tzset();
			i = (lt->tm_isdst)? 1: 0;
			ctmp = tzname[i];
#endif
			while (*(buf++) = *(ctmp++));
			--buf;
			break;
		case '%':
			*(buf++) = c;
			break;
		default:
			sprintf(buf, "bad format character - %c", c);
			return (-1);
		}
	}
	return (buf-bb);
}

 --------- 8< --------- 8< --------- 8< --------- 8< --------- 8< ---------

-- 
  ,u,	 Bruce Becker	Toronto, Ontario
a /i/	 Internet: bdb@becker.UUCP, bruce@gpu.utcs.toronto.edu
 `\o\-e	 UUCP: ...!uunet!mnetor!becker!bdb
 _< /_	 "I still have my phil-os-o-phy" - Meredith Monk