xref: /titanic_51/usr/src/lib/libast/common/tm/tmxtime.c (revision 3e14f97f673e8a630f076077de35afdd43dc1587)
1da2e3ebdSchin /***********************************************************************
2da2e3ebdSchin *                                                                      *
3da2e3ebdSchin *               This software is part of the ast package               *
4*3e14f97fSRoger A. Faulkner *          Copyright (c) 1985-2010 AT&T Intellectual Property          *
5da2e3ebdSchin *                      and is licensed under the                       *
6da2e3ebdSchin *                  Common Public License, Version 1.0                  *
77c2fbfb3SApril Chin *                    by AT&T Intellectual Property                     *
8da2e3ebdSchin *                                                                      *
9da2e3ebdSchin *                A copy of the License is available at                 *
10da2e3ebdSchin *            http://www.opensource.org/licenses/cpl1.0.txt             *
11da2e3ebdSchin *         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
12da2e3ebdSchin *                                                                      *
13da2e3ebdSchin *              Information and Software Systems Research               *
14da2e3ebdSchin *                            AT&T Research                             *
15da2e3ebdSchin *                           Florham Park NJ                            *
16da2e3ebdSchin *                                                                      *
17da2e3ebdSchin *                 Glenn Fowler <gsf@research.att.com>                  *
18da2e3ebdSchin *                  David Korn <dgk@research.att.com>                   *
19da2e3ebdSchin *                   Phong Vo <kpv@research.att.com>                    *
20da2e3ebdSchin *                                                                      *
21da2e3ebdSchin ***********************************************************************/
22da2e3ebdSchin #pragma prototyped
23da2e3ebdSchin /*
24da2e3ebdSchin  * Glenn Fowler
25da2e3ebdSchin  * AT&T Research
26da2e3ebdSchin  *
27da2e3ebdSchin  * Time_t conversion support
28da2e3ebdSchin  */
29da2e3ebdSchin 
30da2e3ebdSchin #include <tmx.h>
31da2e3ebdSchin 
32da2e3ebdSchin #include "FEATURE/tmlib"
33da2e3ebdSchin 
34da2e3ebdSchin /*
35da2e3ebdSchin  * convert Tm_t to Time_t
36da2e3ebdSchin  *
37da2e3ebdSchin  * if west==TM_LOCALZONE then the local timezone is used
38da2e3ebdSchin  * otherwise west is the number of minutes west
39da2e3ebdSchin  * of GMT with DST taken into account
40da2e3ebdSchin  *
41da2e3ebdSchin  * this routine works with a copy of Tm_t to avoid clashes
42da2e3ebdSchin  * with other tm*() that may return static Tm_t*
43da2e3ebdSchin  */
44da2e3ebdSchin 
45da2e3ebdSchin Time_t
tmxtime(register Tm_t * tm,int west)46da2e3ebdSchin tmxtime(register Tm_t* tm, int west)
47da2e3ebdSchin {
48da2e3ebdSchin 	register Time_t		t;
49da2e3ebdSchin 	register Tm_leap_t*	lp;
50da2e3ebdSchin 	register int32_t	y;
51da2e3ebdSchin 	int			n;
52da2e3ebdSchin 	int			sec;
53da2e3ebdSchin 	time_t			now;
54da2e3ebdSchin 	struct tm*		tl;
55da2e3ebdSchin 	Tm_t*			to;
56da2e3ebdSchin 	Tm_t			ts;
57da2e3ebdSchin 
58da2e3ebdSchin 	ts = *tm;
59da2e3ebdSchin 	to = tm;
60da2e3ebdSchin 	tm = &ts;
61da2e3ebdSchin 	tmset(tm_info.zone);
62da2e3ebdSchin 	tmfix(tm);
63da2e3ebdSchin 	y = tm->tm_year;
64da2e3ebdSchin 	if (y < 69 || y > (TMX_MAXYEAR - 1900))
65da2e3ebdSchin 		return TMX_NOTIME;
66da2e3ebdSchin 	y--;
67da2e3ebdSchin 	t = y * 365 + y / 4 - y / 100 + (y + (1900 - 1600)) / 400 - (1970 - 1901) * 365 - (1970 - 1901) / 4;
68da2e3ebdSchin 	if ((n = tm->tm_mon) > 11)
69da2e3ebdSchin 		n = 11;
70da2e3ebdSchin 	y += 1901;
71da2e3ebdSchin 	if (n > 1 && tmisleapyear(y))
72da2e3ebdSchin 		t++;
73da2e3ebdSchin 	t += tm_data.sum[n] + tm->tm_mday - 1;
74da2e3ebdSchin 	t *= 24;
75da2e3ebdSchin 	t += tm->tm_hour;
76da2e3ebdSchin 	t *= 60;
77da2e3ebdSchin 	t += tm->tm_min;
78da2e3ebdSchin 	t *= 60;
79da2e3ebdSchin 	t += sec = tm->tm_sec;
80da2e3ebdSchin 	if (west != TM_UTCZONE && !(tm_info.flags & TM_UTC))
81da2e3ebdSchin 	{
82da2e3ebdSchin 		/*
83da2e3ebdSchin 		 * time zone adjustments
84da2e3ebdSchin 		 */
85da2e3ebdSchin 
86da2e3ebdSchin 		if (west == TM_LOCALZONE)
87da2e3ebdSchin 		{
88da2e3ebdSchin 			t += tm_info.zone->west * 60;
89da2e3ebdSchin 			if (!tm_info.zone->daylight)
90da2e3ebdSchin 				tm->tm_isdst = 0;
91da2e3ebdSchin 			else
92da2e3ebdSchin 			{
93da2e3ebdSchin 				y = tm->tm_year;
94da2e3ebdSchin 				tm->tm_year = tmequiv(tm) - 1900;
95da2e3ebdSchin 				now = tmxsec(tmxtime(tm, tm_info.zone->west));
96da2e3ebdSchin 				tm->tm_year = y;
97da2e3ebdSchin 				if (!(tl = tmlocaltime(&now)))
98da2e3ebdSchin 					return TMX_NOTIME;
99da2e3ebdSchin 				if (tm->tm_isdst = tl->tm_isdst)
100da2e3ebdSchin 					t += tm_info.zone->dst * 60;
101da2e3ebdSchin 			}
102da2e3ebdSchin 		}
103da2e3ebdSchin 		else
104da2e3ebdSchin 		{
105da2e3ebdSchin 			t += west * 60;
106da2e3ebdSchin 			if (!tm_info.zone->daylight)
107da2e3ebdSchin 				tm->tm_isdst = 0;
108da2e3ebdSchin 			else if (tm->tm_isdst < 0)
109da2e3ebdSchin 			{
110da2e3ebdSchin 				y = tm->tm_year;
111da2e3ebdSchin 				tm->tm_year = tmequiv(tm) - 1900;
112da2e3ebdSchin 				tm->tm_isdst = 0;
113da2e3ebdSchin 				now = tmxsec(tmxtime(tm, tm_info.zone->west));
114da2e3ebdSchin 				tm->tm_year = y;
115da2e3ebdSchin 				if (!(tl = tmlocaltime(&now)))
116da2e3ebdSchin 					return TMX_NOTIME;
117da2e3ebdSchin 				tm->tm_isdst = tl->tm_isdst;
118da2e3ebdSchin 			}
119da2e3ebdSchin 		}
120da2e3ebdSchin 	}
121da2e3ebdSchin 	else if (tm->tm_isdst)
122da2e3ebdSchin 		tm->tm_isdst = 0;
123da2e3ebdSchin 	*to = *tm;
124da2e3ebdSchin 	if (tm_info.flags & TM_LEAP)
125da2e3ebdSchin 	{
126da2e3ebdSchin 		/*
127da2e3ebdSchin 		 * leap second adjustments
128da2e3ebdSchin 		 */
129da2e3ebdSchin 
130da2e3ebdSchin 		for (lp = &tm_data.leap[0]; t < lp->time - (lp+1)->total; lp++);
131da2e3ebdSchin 		t += lp->total;
132da2e3ebdSchin 		n = lp->total - (lp+1)->total;
133da2e3ebdSchin 		if (t <= (lp->time + n) && (n > 0 && sec > 59 || n < 0 && sec > (59 + n) && sec <= 59))
134da2e3ebdSchin 			t -= n;
135da2e3ebdSchin 	}
136da2e3ebdSchin 	return tmxsns(t, tm->tm_nsec);
137da2e3ebdSchin }
138