[alt.sources] Looking for a tool to make UNIX-Time

boyd@necisa.ho.necisa.oz (Boyd Roberts) (11/26/90)

Here's a mktime() sort of thing based on calling localtime(3) and
binary chopping on a guessed UNIX time long.  Ok?


Boyd Roberts			boyd@necisa.ho.necisa.oz.au

``When the going gets wierd, the weird turn pro...''

<---cut-here--->
/*
 *	Convert a struct tm to a number of seconds.
 */
#include	<time.h>

/*
 *	Compare two ints.
 */
int
cmp(a, b)	
register int	a;
register int	b;
{
	register int	x;

	if ((x = a - b) == 0)
		return 0;

	return x > 0 ? 1 : -1;
}

/*
 *	Compare two struct tm's.  Only the year, month, day of the
 *	month, hour, minute and second fields are used.
 */
int
tmcmp(t1p, t2p)
register struct tm	*t1p;
register struct tm	*t2p;
{
	register int	x;

	if
	(
		(x = cmp(t1p->tm_year, t2p->tm_year)) == 0
		&&
		(x = cmp(t1p->tm_mon, t2p->tm_mon)) == 0
		&&
		(x = cmp(t1p->tm_mday, t2p->tm_mday)) == 0
		&&
		(x = cmp(t1p->tm_hour, t2p->tm_hour)) == 0
		&&
		(x = cmp(t1p->tm_min, t2p->tm_min)) == 0
		&&
		(x = cmp(t1p->tm_sec, t2p->tm_sec)) == 0
	)
		return 0;

	return x;
}

/*
 *	Take a struct tm and return the associated number of seconds.
 */
long
gmsecs(tp)
register struct tm	*tp;
{
	register struct tm	*ltp;
	register int		bit;
	long			t;

	t = 0;

	/*
	 *	Binary chop by formulating a guess at what the time may be.
	 *	Avoid negative times, as localtime() loses its mind.
	 */
	for (bit = 30; bit >= 0; bit--)
	{
		/* guess */
		t |= 1 << bit;

		ltp = localtime(&t);

		switch (tmcmp(tp, ltp))
		{
		case -1:
			/* guess > time -- unset this guess bit */
			t ^= 1 << bit;
			break;

		case 0:
			/* found it */
			return t;

		case 1:
			/* time > guess -- guess was in the right direction */
			break;
		}
	}

	return t;
}