Blame src/lib/libast/tm/tmxmake.c

Packit Service a8c26c
/***********************************************************************
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*               This software is part of the ast package               *
Packit Service a8c26c
*          Copyright (c) 1985-2011 AT&T Intellectual Property          *
Packit Service a8c26c
*                      and is licensed under the                       *
Packit Service a8c26c
*                 Eclipse Public License, Version 1.0                  *
Packit Service a8c26c
*                    by AT&T Intellectual Property                     *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*                A copy of the License is available at                 *
Packit Service a8c26c
*          http://www.eclipse.org/org/documents/epl-v10.html           *
Packit Service a8c26c
*         (with md5 checksum b35adb5213ca9657e911e9befb180842)         *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*              Information and Software Systems Research               *
Packit Service a8c26c
*                            AT&T Research                             *
Packit Service a8c26c
*                           Florham Park NJ                            *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
*                 Glenn Fowler <gsf@research.att.com>                  *
Packit Service a8c26c
*                  David Korn <dgk@research.att.com>                   *
Packit Service a8c26c
*                   Phong Vo <kpv@research.att.com>                    *
Packit Service a8c26c
*                                                                      *
Packit Service a8c26c
***********************************************************************/
Packit Service a8c26c
#pragma prototyped
Packit Service a8c26c
/*
Packit Service a8c26c
 * Glenn Fowler
Packit Service a8c26c
 * AT&T Research
Packit Service a8c26c
 *
Packit Service a8c26c
 * Time_t conversion support
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
#include <tmx.h>
Packit Service a8c26c
Packit Service a8c26c
#include "FEATURE/tmlib"
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * return Tm_t for t
Packit Service a8c26c
 * time zone and leap seconds accounted for in return value
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
Tm_t*
Packit Service a8c26c
tmxtm(register Tm_t* tm, Time_t t, Tm_zone_t* zone)
Packit Service a8c26c
{
Packit Service a8c26c
	register struct tm*	tp;
Packit Service a8c26c
	register Tm_leap_t*	lp;
Packit Service a8c26c
	Time_t			x;
Packit Service a8c26c
	time_t			now;
Packit Service a8c26c
	int			leapsec;
Packit Service a8c26c
	int			y;
Packit Service a8c26c
	uint32_t		n;
Packit Service a8c26c
	int32_t			o;
Packit Service a8c26c
#if TMX_FLOAT
Packit Service a8c26c
	Time_t			z;
Packit Service a8c26c
	uint32_t		i;
Packit Service a8c26c
#endif
Packit Service a8c26c
Packit Service a8c26c
	tmset(tm_info.zone);
Packit Service a8c26c
	leapsec = 0;
Packit Service a8c26c
	if ((tm_info.flags & (TM_ADJUST|TM_LEAP)) == (TM_ADJUST|TM_LEAP) && (n = tmxsec(t)))
Packit Service a8c26c
	{
Packit Service a8c26c
		for (lp = &tm_data.leap[0]; n < lp->time; lp++);
Packit Service a8c26c
		if (lp->total)
Packit Service a8c26c
		{
Packit Service a8c26c
			if (n == lp->time && (leapsec = (lp->total - (lp+1)->total)) < 0)
Packit Service a8c26c
				leapsec = 0;
Packit Service a8c26c
			t = tmxsns(n - lp->total, tmxnsec(t));
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
	x = tmxsec(t);
Packit Service a8c26c
	if (!(tm->tm_zone = zone))
Packit Service a8c26c
	{
Packit Service a8c26c
		if (tm_info.flags & TM_UTC)
Packit Service a8c26c
			tm->tm_zone = &tm_data.zone[2];
Packit Service a8c26c
		else
Packit Service a8c26c
			tm->tm_zone = tm_info.zone;
Packit Service a8c26c
	}
Packit Service a8c26c
	if ((o = 60 * tm->tm_zone->west) && x > o)
Packit Service a8c26c
	{
Packit Service a8c26c
		x -= o;
Packit Service a8c26c
		o = 0;
Packit Service a8c26c
	}
Packit Service a8c26c
#if TMX_FLOAT
Packit Service a8c26c
	i = x / (24 * 60 * 60);
Packit Service a8c26c
	z = i;
Packit Service a8c26c
	n = x - z * (24 * 60 * 60);
Packit Service a8c26c
	tm->tm_sec = n % 60 + leapsec;
Packit Service a8c26c
	n /= 60;
Packit Service a8c26c
	tm->tm_min = n % 60;
Packit Service a8c26c
	n /= 60;
Packit Service a8c26c
	tm->tm_hour = n % 24;
Packit Service a8c26c
#define x	i
Packit Service a8c26c
#else
Packit Service a8c26c
	tm->tm_sec = x % 60 + leapsec;
Packit Service a8c26c
	x /= 60;
Packit Service a8c26c
	tm->tm_min = x % 60;
Packit Service a8c26c
	x /= 60;
Packit Service a8c26c
	tm->tm_hour = x % 24;
Packit Service a8c26c
	x /= 24;
Packit Service a8c26c
#endif
Packit Service a8c26c
	tm->tm_wday = (x + 4) % 7;
Packit Service a8c26c
	tm->tm_year = (400 * (x + 25202)) / 146097 + 1;
Packit Service a8c26c
	n = tm->tm_year - 1;
Packit Service a8c26c
	x -= n * 365 + n / 4 - n / 100 + (n + (1900 - 1600)) / 400 - (1970 - 1901) * 365 - (1970 - 1901) / 4;
Packit Service a8c26c
	tm->tm_mon = 0;
Packit Service a8c26c
	tm->tm_mday = x + 1;
Packit Service a8c26c
	tm->tm_nsec = tmxnsec(t);
Packit Service a8c26c
	tmfix(tm);
Packit Service a8c26c
	n += 1900;
Packit Service a8c26c
	tm->tm_isdst = 0;
Packit Service a8c26c
	if (tm->tm_zone->daylight)
Packit Service a8c26c
	{
Packit Service a8c26c
		if ((y = tmequiv(tm) - 1900) == tm->tm_year)
Packit Service a8c26c
			now = tmxsec(t);
Packit Service a8c26c
		else
Packit Service a8c26c
		{
Packit Service a8c26c
			Tm_t	te;
Packit Service a8c26c
Packit Service a8c26c
			te = *tm;
Packit Service a8c26c
			te.tm_year = y;
Packit Service a8c26c
			now = tmxsec(tmxtime(&te, tm->tm_zone->west));
Packit Service a8c26c
		}
Packit Service a8c26c
		if ((tp = tmlocaltime(&now)) && ((tm->tm_isdst = tp->tm_isdst) || o))
Packit Service a8c26c
		{
Packit Service a8c26c
			tm->tm_min -= o / 60 + (tm->tm_isdst ? tm->tm_zone->dst : 0);
Packit Service a8c26c
			tmfix(tm);
Packit Service a8c26c
		}
Packit Service a8c26c
	}
Packit Service a8c26c
	return tm;
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
/*
Packit Service a8c26c
 * return Tm_t for t
Packit Service a8c26c
 * time zone and leap seconds accounted for in return value
Packit Service a8c26c
 */
Packit Service a8c26c
Packit Service a8c26c
Tm_t*
Packit Service a8c26c
tmxmake(Time_t t)
Packit Service a8c26c
{
Packit Service a8c26c
	static Tm_t		ts;
Packit Service a8c26c
Packit Service a8c26c
	return tmxtm(&ts, t, NiL);
Packit Service a8c26c
}