FW: environment independent time functions...

Christos Zoulas christos at zoulas.com
Fri Oct 1 14:53:40 UTC 2010


On Oct 1,  9:29am, abbotti at mev.co.uk (Ian Abbott) wrote:
-- Subject: Re: FW: environment independent time functions...

| > Has anyone done this work or similar?
| 
| There are some functions and data structures in the latest stable GNOME
| GLib library (GLib 2.26) for handling time zones and time conversions:
| 
| http://library.gnome.org/devel/glib/unstable/glib-GTimeZone.html

I apologize if I did not make myself clear in the previous message.
My goal was not to re-think and redesign the posix time interfaces,
but to make reentrant and thread-safe in an orthogonal manner,
minimizing code changes and re-using as much code as possible.
Also I wanted to make things fail on unknown timezones on the new
interfaces, not fall back to GMT. Here's my current diff. Most of
it has to do with ansifying, removing register, and making timezone_t
the first argument for orthogonality. Comments are welcome.
[the ifdef HIDE stuff should be removed; I just have it here so I can
 use the new functions without collisions with libc]

Best,

christos

Index: localtime.c
===================================================================
RCS file: /src/twosigma/cvsroot/external/public/tzcode/localtime.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -u -r1.1.1.1 -r1.3
--- localtime.c	30 Sep 2010 20:38:51 -0000	1.1.1.1
+++ localtime.c	30 Sep 2010 21:44:22 -0000	1.3
@@ -16,10 +16,31 @@
 
 /*LINTLIBRARY*/
 
+#ifdef HIDE
+#define ctime __ctime
+#define ctime_r __ctime_r
+#define gmtime __gmtime
+#define gmtime_r __gmtime_r
+#define localtime __localtime
+#define localtime_r __localtime_r
+#define tzset __tzset
+#define tzsetwall __tzsetwall
+#define offtime __offtime
+#define offtime_r __offtime_r
+#define mktime __mktime
+#define timelocal __timelocal
+#define timegm	__timegm
+#define timeoff __timeoff
+#define posix2time __posix2time
+#define time2posix __time2posix
+#define tzname	__tzname
+#endif
+
 #include "private.h"
 #include "tzfile.h"
 #include "fcntl.h"
 #include "float.h"	/* for FLT_MAX and DBL_MAX */
+#include "timeextra.h"
 
 #ifndef TZ_ABBR_MAX_LEN
 #define TZ_ABBR_MAX_LEN	16
@@ -70,7 +91,7 @@
 
 static char		wildabbr[] = WILDABBR;
 
-static const char	gmt[] = "GMT";
+static char		gmt[] = "GMT";
 
 /*
 ** The DST rules to use if TZ has no rules and we can't load TZDEFRULES.
@@ -105,7 +126,7 @@
 #define MY_TZNAME_MAX	255
 #endif /* !defined TZNAME_MAX */
 
-struct state {
+struct __state {
 	int		leapcnt;
 	int		timecnt;
 	int		typecnt;
@@ -132,6 +153,8 @@
 #define DAY_OF_YEAR		1	/* n - day of year */
 #define MONTH_NTH_DAY_OF_WEEK	2	/* Mm.n.d - month, week, day of week */
 
+typedef struct tm *(*subfun_t)(const timezone_t sp, const time_t *timep,
+			       long offset, struct tm *tmp);
 /*
 ** Prototypes for static functions.
 */
@@ -146,11 +169,11 @@
 static const char *	getsecs(const char * strp, long * secsp);
 static const char *	getoffset(const char * strp, long * offsetp);
 static const char *	getrule(const char * strp, struct rule * rulep);
-static void		gmtload(struct state * sp);
-static struct tm *	gmtsub(const time_t * timep, long offset,
-				struct tm * tmp);
-static struct tm *	localsub(const time_t * timep, long offset,
-				struct tm * tmp);
+static void		gmtload(timezone_t sp);
+static struct tm *	gmtsub(const timezone_t sp, const time_t *timep,
+				long offset, struct tm * tmp);
+static struct tm *	localsub(const timezone_t sp, const time_t *timep,
+				long offset, struct tm *tmp);
 static int		increment_overflow(int * number, int delta);
 static int		leaps_thru_end_of(int y);
 static int		long_increment_overflow(long * number, int delta);
@@ -159,41 +182,27 @@
 static int		normalize_overflow(int * tensptr, int * unitsptr,
 				int base);
 static void		settzname(void);
-static time_t		time1(struct tm * tmp,
-				struct tm * (*funcp)(const time_t *,
-				long, struct tm *),
-				long offset);
-static time_t		time2(struct tm *tmp,
-				struct tm * (*funcp)(const time_t *,
-				long, struct tm*),
-				long offset, int * okayp);
-static time_t		time2sub(struct tm *tmp,
-				struct tm * (*funcp)(const time_t *,
-				long, struct tm*),
+static time_t		time1(const timezone_t sp, struct tm *tmp,
+				subfun_t funcp, long offset);
+static time_t		time2(const timezone_t sp, struct tm *tmp,
+				subfun_t funcp, long offset, int *okayp);
+static time_t		time2sub(const timezone_t sp, struct tm *tmp,
+				subfun_t funcp,
 				long offset, int * okayp, int do_norm_secs);
-static struct tm *	timesub(const time_t * timep, long offset,
-				const struct state * sp, struct tm * tmp);
+static struct tm *	timesub(const timezone_t sp, const time_t * timep,
+				long offset, struct tm * tmp);
 static int		tmcomp(const struct tm * atmp,
 				const struct tm * btmp);
 static time_t		transtime(time_t janfirst, int year,
 				const struct rule * rulep, long offset);
-static int		typesequiv(const struct state * sp, int a, int b);
-static int		tzload(const char * name, struct state * sp,
+static int		typesequiv(const timezone_t sp, int a, int b);
+static int		tzload(timezone_t sp, const char * name,
 				int doextend);
-static int		tzparse(const char * name, struct state * sp,
+static int		tzparse(timezone_t sp, const char *name,
 				int lastditch);
 
-#ifdef ALL_STATE
-static struct state *	lclptr;
-static struct state *	gmtptr;
-#endif /* defined ALL_STATE */
-
-#ifndef ALL_STATE
-static struct state	lclmem;
-static struct state	gmtmem;
-#define lclptr		(&lclmem)
-#define gmtptr		(&gmtmem)
-#endif /* State Farm */
+static timezone_t	lclptr;
+static timezone_t	gmtptr;
 
 #ifndef TZ_STRLEN_MAX
 #define TZ_STRLEN_MAX 255
@@ -228,11 +237,10 @@
 #endif /* defined ALTZONE */
 
 static long
-detzcode(codep)
-const char * const	codep;
+detzcode(const char *const codep)
 {
-	register long	result;
-	register int	i;
+	long	result;
+	int	i;
 
 	result = (codep[0] & 0x80) ? ~0L : 0;
 	for (i = 0; i < 4; ++i)
@@ -241,11 +249,10 @@
 }
 
 static time_t
-detzcode64(codep)
-const char * const	codep;
+detzcode64(const char *const codep)
 {
-	register time_t	result;
-	register int	i;
+	time_t	result;
+	int	i;
 
 	result = (codep[0] & 0x80) ?  (~(int_fast64_t) 0) : 0;
 	for (i = 0; i < 8; ++i)
@@ -253,11 +260,49 @@
 	return result;
 }
 
+const char *
+tzgetname(const timezone_t sp, int isdst)
+{
+	int i;
+	for (i = 0; i < sp->timecnt; ++i) {
+		const struct ttinfo *const ttisp = &sp->ttis[sp->types[i]];
+
+		if (ttisp->tt_isdst == isdst)
+			return &sp->chars[ttisp->tt_abbrind];
+	}
+	return NULL;
+}
+
+static void
+settzname_z(timezone_t sp)
+{
+	int			i;
+
+	/*
+	** Scrub the abbreviations.
+	** First, replace bogus characters.
+	*/
+	for (i = 0; i < sp->charcnt; ++i)
+		if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
+			sp->chars[i] = TZ_ABBR_ERR_CHAR;
+	/*
+	** Second, truncate long abbreviations.
+	*/
+	for (i = 0; i < sp->typecnt; ++i) {
+		const struct ttinfo * const	ttisp = &sp->ttis[i];
+		char *				cp = &sp->chars[ttisp->tt_abbrind];
+
+		if (strlen(cp) > TZ_ABBR_MAX_LEN &&
+			strcmp(cp, GRANDPARENTED) != 0)
+				*(cp + TZ_ABBR_MAX_LEN) = '\0';
+	}
+}
+
 static void
 settzname(void)
 {
-	register struct state * const	sp = lclptr;
-	register int			i;
+	timezone_t const	sp = lclptr;
+	int			i;
 
 	tzname[0] = wildabbr;
 	tzname[1] = wildabbr;
@@ -268,17 +313,15 @@
 #ifdef ALTZONE
 	altzone = 0;
 #endif /* defined ALTZONE */
-#ifdef ALL_STATE
 	if (sp == NULL) {
 		tzname[0] = tzname[1] = gmt;
 		return;
 	}
-#endif /* defined ALL_STATE */
 	/*
 	** And to get the latest zone names into tzname. . .
 	*/
 	for (i = 0; i < sp->timecnt; ++i) {
-		register const struct ttinfo * const	ttisp =
+		const struct ttinfo * const	ttisp =
 							&sp->ttis[
 								sp->types[i]];
 
@@ -295,30 +338,11 @@
 			altzone = -(ttisp->tt_gmtoff);
 #endif /* defined ALTZONE */
 	}
-	/*
-	** Finally, scrub the abbreviations.
-	** First, replace bogus characters.
-	*/
-	for (i = 0; i < sp->charcnt; ++i)
-		if (strchr(TZ_ABBR_CHAR_SET, sp->chars[i]) == NULL)
-			sp->chars[i] = TZ_ABBR_ERR_CHAR;
-	/*
-	** Second, truncate long abbreviations.
-	*/
-	for (i = 0; i < sp->typecnt; ++i) {
-		register const struct ttinfo * const	ttisp = &sp->ttis[i];
-		register char *				cp = &sp->chars[ttisp->tt_abbrind];
-
-		if (strlen(cp) > TZ_ABBR_MAX_LEN &&
-			strcmp(cp, GRANDPARENTED) != 0)
-				*(cp + TZ_ABBR_MAX_LEN) = '\0';
-	}
+	settzname_z(sp);
 }
 
 static int
-differ_by_repeat(t1, t0)
-const time_t	t1;
-const time_t	t0;
+differ_by_repeat(const time_t t1, const time_t t0)
 {
 	if (TYPE_INTEGRAL(time_t) &&
 		TYPE_BIT(time_t) - TYPE_SIGNED(time_t) < SECSPERREPEAT_BITS)
@@ -327,16 +351,13 @@
 }
 
 static int
-tzload(name, sp, doextend)
-register const char *		name;
-register struct state * const	sp;
-register const int		doextend;
-{
-	register const char *		p;
-	register int			i;
-	register int			fid;
-	register int			stored;
-	register int			nread;
+tzload(timezone_t sp, const char *name, const int doextend)
+{
+	const char *		p;
+	int			i;
+	int			fid;
+	int			stored;
+	int			nread;
 	union {
 		struct tzhead	tzhead;
 		char		buf[2 * sizeof(struct tzhead) +
@@ -348,7 +369,7 @@
 	if (name == NULL && (name = TZDEFAULT) == NULL)
 		return -1;
 	{
-		register int	doaccess;
+		int	doaccess;
 		/*
 		** Section 4.9.1 of the C standard says that
 		** "FILENAME_MAX expands to an integral constant expression
@@ -422,7 +443,7 @@
 				return -1;
 		}
 		for (i = 0; i < sp->typecnt; ++i) {
-			register struct ttinfo *	ttisp;
+			struct ttinfo *	ttisp;
 
 			ttisp = &sp->ttis[i];
 			ttisp->tt_gmtoff = detzcode(p);
@@ -439,7 +460,7 @@
 			sp->chars[i] = *p++;
 		sp->chars[i] = '\0';	/* ensure '\0' at end */
 		for (i = 0; i < sp->leapcnt; ++i) {
-			register struct lsinfo *	lsisp;
+			struct lsinfo *	lsisp;
 
 			lsisp = &sp->lsis[i];
 			lsisp->ls_trans = (stored == 4) ?
@@ -449,7 +470,7 @@
 			p += 4;
 		}
 		for (i = 0; i < sp->typecnt; ++i) {
-			register struct ttinfo *	ttisp;
+			struct ttinfo *	ttisp;
 
 			ttisp = &sp->ttis[i];
 			if (ttisstdcnt == 0)
@@ -462,7 +483,7 @@
 			}
 		}
 		for (i = 0; i < sp->typecnt; ++i) {
-			register struct ttinfo *	ttisp;
+			struct ttinfo *	ttisp;
 
 			ttisp = &sp->ttis[i];
 			if (ttisgmtcnt == 0)
@@ -491,7 +512,7 @@
 					/*
 					** Ignore the beginning (harder).
 					*/
-					register int	j;
+					int	j;
 
 					for (j = 0; j + i < sp->timecnt; ++j) {
 						sp->ats[j] = sp->ats[j + i];
@@ -518,11 +539,11 @@
 	if (doextend && nread > 2 &&
 		u.buf[0] == '\n' && u.buf[nread - 1] == '\n' &&
 		sp->typecnt + 2 <= TZ_MAX_TYPES) {
-			struct state	ts;
-			register int	result;
+			struct __state ts;
+			int	result;
 
 			u.buf[nread - 1] = '\0';
-			result = tzparse(&u.buf[1], &ts, FALSE);
+			result = tzparse(&ts, &u.buf[1], FALSE);
 			if (result == 0 && ts.typecnt == 2 &&
 				sp->charcnt + ts.charcnt <= TZ_MAX_CHARS) {
 					for (i = 0; i < 2; ++i)
@@ -570,20 +591,17 @@
 }
 
 static int
-typesequiv(sp, a, b)
-const struct state * const	sp;
-const int			a;
-const int			b;
+typesequiv(const timezone_t sp, const int a, const int b)
 {
-	register int	result;
+	int	result;
 
 	if (sp == NULL ||
 		a < 0 || a >= sp->typecnt ||
 		b < 0 || b >= sp->typecnt)
 			result = FALSE;
 	else {
-		register const struct ttinfo *	ap = &sp->ttis[a];
-		register const struct ttinfo *	bp = &sp->ttis[b];
+		const struct ttinfo *	ap = &sp->ttis[a];
+		const struct ttinfo *	bp = &sp->ttis[b];
 		result = ap->tt_gmtoff == bp->tt_gmtoff &&
 			ap->tt_isdst == bp->tt_isdst &&
 			ap->tt_ttisstd == bp->tt_ttisstd &&
@@ -611,9 +629,9 @@
 
 static const char *
 getzname(strp)
-register const char *	strp;
+const char *	strp;
 {
-	register char	c;
+	char	c;
 
 	while ((c = *strp) != '\0' && !is_digit(c) && c != ',' && c != '-' &&
 		c != '+')
@@ -631,9 +649,9 @@
 */
 
 static const char *
-getqzname(register const char *strp, const int delim)
+getqzname(const char *strp, const int delim)
 {
-	register int	c;
+	int	c;
 
 	while ((c = *strp) != '\0' && c != delim)
 		++strp;
@@ -649,13 +667,13 @@
 
 static const char *
 getnum(strp, nump, min, max)
-register const char *	strp;
+const char *	strp;
 int * const		nump;
 const int		min;
 const int		max;
 {
-	register char	c;
-	register int	num;
+	char	c;
+	int	num;
 
 	if (strp == NULL || !is_digit(c = *strp))
 		return NULL;
@@ -681,9 +699,7 @@
 */
 
 static const char *
-getsecs(strp, secsp)
-register const char *	strp;
-long * const		secsp;
+getsecs(const char *strp, long *const secsp)
 {
 	int	num;
 
@@ -723,11 +739,9 @@
 */
 
 static const char *
-getoffset(strp, offsetp)
-register const char *	strp;
-long * const		offsetp;
+getoffset(const char *strp, long *const offsetp)
 {
-	register int	neg = 0;
+	int	neg = 0;
 
 	if (*strp == '-') {
 		neg = 1;
@@ -750,9 +764,7 @@
 */
 
 static const char *
-getrule(strp, rulep)
-const char *			strp;
-register struct rule * const	rulep;
+getrule(const char *strp, struct rule *const rulep)
 {
 	if (*strp == 'J') {
 		/*
@@ -804,15 +816,12 @@
 */
 
 static time_t
-transtime(janfirst, year, rulep, offset)
-const time_t				janfirst;
-const int				year;
-register const struct rule * const	rulep;
-const long				offset;
-{
-	register int	leapyear;
-	register time_t	value;
-	register int	i;
+transtime(const time_t janfirst, const int year, const struct rule *const rulep,
+    const long offset)
+{
+	int	leapyear;
+	time_t	value;
+	int	i;
 	int		d, m1, yy0, yy1, yy2, dow;
 
 	INITIALIZE(value);
@@ -899,10 +908,7 @@
 */
 
 static int
-tzparse(name, sp, lastditch)
-const char *			name;
-register struct state * const	sp;
-const int			lastditch;
+tzparse(timezone_t sp, const char *name, const int lastditch)
 {
 	const char *			stdname;
 	const char *			dstname;
@@ -910,10 +916,10 @@
 	size_t				dstlen;
 	long				stdoffset;
 	long				dstoffset;
-	register time_t *		atp;
-	register unsigned char *	typep;
-	register char *			cp;
-	register int			load_result;
+	time_t *		atp;
+	unsigned char *	typep;
+	char *			cp;
+	int			load_result;
 
 	INITIALIZE(dstname);
 	stdname = name;
@@ -942,7 +948,7 @@
 		if (name == NULL)
 			return -1;
 	}
-	load_result = tzload(TZDEFRULES, sp, FALSE);
+	load_result = tzload(sp, TZDEFRULES, FALSE);
 	if (load_result != 0)
 		sp->leapcnt = 0;		/* so, we're off a little */
 	if (*name != '\0') {
@@ -968,8 +974,8 @@
 		if (*name == ',' || *name == ';') {
 			struct rule	start;
 			struct rule	end;
-			register int	year;
-			register time_t	janfirst;
+			int	year;
+			time_t	janfirst;
 			time_t		starttime;
 			time_t		endtime;
 
@@ -1025,12 +1031,12 @@
 				janfirst = newfirst;
 			}
 		} else {
-			register long	theirstdoffset;
-			register long	theirdstoffset;
-			register long	theiroffset;
-			register int	isdst;
-			register int	i;
-			register int	j;
+			long	theirstdoffset;
+			long	theirdstoffset;
+			long	theiroffset;
+			int	isdst;
+			int	i;
+			int	j;
 
 			if (*name != '\0')
 				return -1;
@@ -1134,11 +1140,30 @@
 }
 
 static void
-gmtload(sp)
-struct state * const	sp;
+gmtload(timezone_t sp)
+{
+	if (tzload(sp, gmt, TRUE) != 0)
+		(void) tzparse(sp, gmt, TRUE);
+}
+
+const timezone_t
+tzalloc(const char *name)
+{
+	timezone_t sp = calloc(1, sizeof *sp);
+	if (sp == NULL)
+		return NULL;
+	if (tzload(sp, name, TRUE) != 0) {
+		free(sp);
+		return NULL;
+	}
+	settzname_z(sp);
+	return sp;
+}
+
+void
+tzfree(const timezone_t sp)
 {
-	if (tzload(gmt, sp, TRUE) != 0)
-		(void) tzparse(gmt, sp, TRUE);
+	free((void *)(intptr_t)sp);
 }
 
 #ifndef STD_INSPIRED
@@ -1155,16 +1180,14 @@
 		return;
 	lcl_is_set = -1;
 
-#ifdef ALL_STATE
 	if (lclptr == NULL) {
-		lclptr = (struct state *) calloc(1, sizeof *lclptr);
+		lclptr = calloc(1, sizeof *lclptr);
 		if (lclptr == NULL) {
 			settzname();	/* all we can do */
 			return;
 		}
 	}
-#endif /* defined ALL_STATE */
-	if (tzload((char *) NULL, lclptr, TRUE) != 0)
+	if (tzload(lclptr, NULL, TRUE) != 0)
 		gmtload(lclptr);
 	settzname();
 }
@@ -1172,7 +1195,7 @@
 void
 tzset(void)
 {
-	register const char *	name;
+	const char *	name;
 
 	name = getenv("TZ");
 	if (name == NULL) {
@@ -1186,15 +1209,13 @@
 	if (lcl_is_set)
 		(void) strcpy(lcl_TZname, name);
 
-#ifdef ALL_STATE
 	if (lclptr == NULL) {
-		lclptr = (struct state *) calloc(1, sizeof *lclptr);
+		lclptr = calloc(1, sizeof *lclptr);
 		if (lclptr == NULL) {
 			settzname();	/* all we can do */
 			return;
 		}
 	}
-#endif /* defined ALL_STATE */
 	if (*name == '\0') {
 		/*
 		** User wants it fast rather than right.
@@ -1206,8 +1227,8 @@
 		lclptr->ttis[0].tt_gmtoff = 0;
 		lclptr->ttis[0].tt_abbrind = 0;
 		(void) strcpy(lclptr->chars, gmt);
-	} else if (tzload(name, lclptr, TRUE) != 0)
-		if (name[0] == ':' || tzparse(name, lclptr, FALSE) != 0)
+	} else if (tzload(lclptr, name, TRUE) != 0)
+		if (name[0] == ':' || tzparse(lclptr, name, FALSE) != 0)
 			(void) gmtload(lclptr);
 	settzname();
 }
@@ -1223,28 +1244,20 @@
 
 /*ARGSUSED*/
 static struct tm *
-localsub(timep, offset, tmp)
-const time_t * const	timep;
-const long		offset;
-struct tm * const	tmp;
-{
-	register struct state *		sp;
-	register const struct ttinfo *	ttisp;
-	register int			i;
-	register struct tm *		result;
+localsub(const timezone_t sp, const time_t * const timep, const long offset,
+    struct tm *const tmp)
+{
+	const struct ttinfo *	ttisp;
+	int			i;
+	struct tm *		result;
 	const time_t			t = *timep;
 
-	sp = lclptr;
-#ifdef ALL_STATE
-	if (sp == NULL)
-		return gmtsub(timep, offset, tmp);
-#endif /* defined ALL_STATE */
 	if ((sp->goback && t < sp->ats[0]) ||
 		(sp->goahead && t > sp->ats[sp->timecnt - 1])) {
 			time_t			newt = t;
-			register time_t		seconds;
-			register time_t		tcycles;
-			register int_fast64_t	icycles;
+			time_t		seconds;
+			time_t		tcycles;
+			int_fast64_t	icycles;
 
 			if (t < sp->ats[0])
 				seconds = sp->ats[0] - t;
@@ -1264,9 +1277,9 @@
 			if (newt < sp->ats[0] ||
 				newt > sp->ats[sp->timecnt - 1])
 					return NULL;	/* "cannot happen" */
-			result = localsub(&newt, offset, tmp);
+			result = localsub(sp, &newt, offset, tmp);
 			if (result == tmp) {
-				register time_t	newy;
+				time_t	newy;
 
 				newy = tmp->tm_year;
 				if (t < sp->ats[0])
@@ -1286,11 +1299,11 @@
 				break;
 			}
 	} else {
-		register int	lo = 1;
-		register int	hi = sp->timecnt;
+		int	lo = 1;
+		int	hi = sp->timecnt;
 
 		while (lo < hi) {
-			register int	mid = (lo + hi) >> 1;
+			int	mid = (lo + hi) >> 1;
 
 			if (t < sp->ats[mid])
 				hi = mid;
@@ -1305,7 +1318,7 @@
 	**	t += ttisp->tt_gmtoff;
 	**	timesub(&t, 0L, sp, tmp);
 	*/
-	result = timesub(&t, ttisp->tt_gmtoff, sp, tmp);
+	result = timesub(sp, &t, ttisp->tt_gmtoff, tmp);
 	tmp->tm_isdst = ttisp->tt_isdst;
 	tzname[tmp->tm_isdst] = &sp->chars[ttisp->tt_abbrind];
 #ifdef TM_ZONE
@@ -1315,46 +1328,48 @@
 }
 
 struct tm *
-localtime(timep)
-const time_t * const	timep;
+localtime_r(const time_t *const	timep, struct tm *tmp)
+{
+	if (lclptr == NULL)
+		return gmtsub(NULL, timep, 0L, tmp);
+	return localtime_z(lclptr, timep, tmp);
+}
+
+struct tm *
+localtime(const time_t *const timep)
 {
 	tzset();
-	return localsub(timep, 0L, &tm);
+	return localtime_r(timep, &tm);
 }
 
 /*
 ** Re-entrant version of localtime.
 */
-
 struct tm *
-localtime_r(timep, tmp)
-const time_t * const	timep;
-struct tm *		tmp;
+localtime_z(const timezone_t sp, const time_t *const timep, struct tm *tmp)
 {
-	return localsub(timep, 0L, tmp);
+	return localsub(sp, timep, 0L, tmp);
 }
 
+
+
 /*
 ** gmtsub is to gmtime as localsub is to localtime.
 */
 
 static struct tm *
-gmtsub(timep, offset, tmp)
-const time_t * const	timep;
-const long		offset;
-struct tm * const	tmp;
+gmtsub(const timezone_t sp, const time_t * const timep, const long offset,
+    struct tm *const tmp)
 {
-	register struct tm *	result;
+	struct tm *	result;
 
 	if (!gmt_is_set) {
 		gmt_is_set = TRUE;
-#ifdef ALL_STATE
-		gmtptr = (struct state *) calloc(1, sizeof *gmtptr);
+		gmtptr = calloc(1, sizeof *gmtptr);
 		if (gmtptr != NULL)
-#endif /* defined ALL_STATE */
 			gmtload(gmtptr);
 	}
-	result = timesub(timep, offset, gmtptr, tmp);
+	result = timesub(gmtptr, timep, offset, tmp);
 #ifdef TM_ZONE
 	/*
 	** Could get fancy here and deliver something such as
@@ -1364,24 +1379,18 @@
 	if (offset != 0)
 		tmp->TM_ZONE = wildabbr;
 	else {
-#ifdef ALL_STATE
 		if (gmtptr == NULL)
 			tmp->TM_ZONE = gmt;
 		else	tmp->TM_ZONE = gmtptr->chars;
-#endif /* defined ALL_STATE */
-#ifndef ALL_STATE
-		tmp->TM_ZONE = gmtptr->chars;
-#endif /* State Farm */
 	}
 #endif /* defined TM_ZONE */
 	return result;
 }
 
 struct tm *
-gmtime(timep)
-const time_t * const	timep;
+gmtime(const time_t *const timep)
 {
-	return gmtsub(timep, 0L, &tm);
+	return gmtsub(NULL, timep, 0L, &tm);
 }
 
 /*
@@ -1389,21 +1398,23 @@
 */
 
 struct tm *
-gmtime_r(timep, tmp)
-const time_t * const	timep;
-struct tm *		tmp;
+gmtime_r(const time_t * const timep, struct tm *tmp)
 {
-	return gmtsub(timep, 0L, tmp);
+	return gmtsub(NULL, timep, 0L, tmp);
 }
 
 #ifdef STD_INSPIRED
 
 struct tm *
-offtime(timep, offset)
-const time_t * const	timep;
-const long		offset;
+offtime(const time_t *const timep, const long offset)
+{
+	return gmtsub(timep, offset, &tm, NULL);
+}
+
+struct tm *
+offtime_r(const time_t *const timep, const long offset, struct tm *tmp)
 {
-	return gmtsub(timep, offset, &tm);
+	return gmtsub(timep, offset, tmp, NULL);
 }
 
 #endif /* defined STD_INSPIRED */
@@ -1414,38 +1425,29 @@
 */
 
 static int
-leaps_thru_end_of(y)
-register const int	y;
+leaps_thru_end_of(const int y)
 {
 	return (y >= 0) ? (y / 4 - y / 100 + y / 400) :
 		-(leaps_thru_end_of(-(y + 1)) + 1);
 }
 
 static struct tm *
-timesub(timep, offset, sp, tmp)
-const time_t * const			timep;
-const long				offset;
-register const struct state * const	sp;
-register struct tm * const		tmp;
-{
-	register const struct lsinfo *	lp;
-	register time_t			tdays;
-	register int			idays;	/* unsigned would be so 2003 */
-	register long			rem;
-	int				y;
-	register const int *		ip;
-	register long			corr;
-	register int			hit;
-	register int			i;
+timesub(const timezone_t sp, const time_t *const timep, const long offset,
+    struct tm *const tmp)
+{
+	const struct lsinfo *	lp;
+	time_t			tdays;
+	int			idays;	/* unsigned would be so 2003 */
+	long			rem;
+	int			y;
+	const int *		ip;
+	long			corr;
+	int			hit;
+	int			i;
 
 	corr = 0;
 	hit = 0;
-#ifdef ALL_STATE
 	i = (sp == NULL) ? 0 : sp->leapcnt;
-#endif /* defined ALL_STATE */
-#ifndef ALL_STATE
-	i = sp->leapcnt;
-#endif /* State Farm */
 	while (--i >= 0) {
 		lp = &sp->lsis[i];
 		if (*timep >= lp->ls_trans) {
@@ -1471,9 +1473,9 @@
 	rem = *timep - tdays * SECSPERDAY;
 	while (tdays < 0 || tdays >= year_lengths[isleap(y)]) {
 		int		newy;
-		register time_t	tdelta;
-		register int	idelta;
-		register int	leapdays;
+		time_t	tdelta;
+		int	idelta;
+		int	leapdays;
 
 		tdelta = tdays / DAYSPERLYEAR;
 		idelta = tdelta;
@@ -1491,7 +1493,7 @@
 		y = newy;
 	}
 	{
-		register long	seconds;
+		long	seconds;
 
 		seconds = tdays * SECSPERDAY + 0.5;
 		tdays = seconds / SECSPERDAY;
@@ -1556,8 +1558,7 @@
 }
 
 char *
-ctime(timep)
-const time_t * const	timep;
+ctime(const time_t *const timep)
 {
 /*
 ** Section 4.12.3.2 of X3.159-1989 requires that
@@ -1569,15 +1570,21 @@
 }
 
 char *
-ctime_r(timep, buf)
-const time_t * const	timep;
-char *			buf;
+ctime_r(const time_t *const timep, char *buf)
 {
 	struct tm	mytm;
 
 	return asctime_r(localtime_r(timep, &mytm), buf);
 }
 
+char *
+ctime_z(const timezone_t sp, const time_t *const timep, char *buf)
+{
+	struct tm	mytm;
+
+	return asctime_r(localtime_z(sp, timep, &mytm), buf);
+}
+
 /*
 ** Adapted from code provided by Robert Elz, who writes:
 **	The "best" way to do mktime I think is based on an idea of Bob
@@ -1596,9 +1603,7 @@
 */
 
 static int
-increment_overflow(number, delta)
-int *	number;
-int	delta;
+increment_overflow(int *number, int delta)
 {
 	int	number0;
 
@@ -1608,9 +1613,7 @@
 }
 
 static int
-long_increment_overflow(number, delta)
-long *	number;
-int	delta;
+long_increment_overflow(long *number, int delta)
 {
 	long	number0;
 
@@ -1620,12 +1623,9 @@
 }
 
 static int
-normalize_overflow(tensptr, unitsptr, base)
-int * const	tensptr;
-int * const	unitsptr;
-const int	base;
+normalize_overflow(int *const tensptr, int *const unitsptr, const int base)
 {
-	register int	tensdelta;
+	int	tensdelta;
 
 	tensdelta = (*unitsptr >= 0) ?
 		(*unitsptr / base) :
@@ -1635,12 +1635,10 @@
 }
 
 static int
-long_normalize_overflow(tensptr, unitsptr, base)
-long * const	tensptr;
-int * const	unitsptr;
-const int	base;
+long_normalize_overflow(long *const tensptr, int *const unitsptr,
+    const int base)
 {
-	register int	tensdelta;
+	int	tensdelta;
 
 	tensdelta = (*unitsptr >= 0) ?
 		(*unitsptr / base) :
@@ -1650,11 +1648,9 @@
 }
 
 static int
-tmcomp(atmp, btmp)
-register const struct tm * const atmp;
-register const struct tm * const btmp;
+tmcomp(const struct tm *const atmp, const struct tm *const btmp)
 {
-	register int	result;
+	int	result;
 
 	if ((result = (atmp->tm_year - btmp->tm_year)) == 0 &&
 		(result = (atmp->tm_mon - btmp->tm_mon)) == 0 &&
@@ -1666,20 +1662,15 @@
 }
 
 static time_t
-time2sub(tmp, funcp, offset, okayp, do_norm_secs)
-struct tm * const	tmp;
-struct tm * (* const	funcp)(const time_t*, long, struct tm*);
-const long		offset;
-int * const		okayp;
-const int		do_norm_secs;
-{
-	register const struct state *	sp;
-	register int			dir;
-	register int			i, j;
-	register int			saved_seconds;
-	register long			li;
-	register time_t			lo;
-	register time_t			hi;
+time2sub(const timezone_t sp, struct tm *const tmp, subfun_t funcp,
+    const long offset, int *const okayp, const int do_norm_secs)
+{
+	int			dir;
+	int			i, j;
+	int			saved_seconds;
+	long			li;
+	time_t			lo;
+	time_t			hi;
 	long				y;
 	time_t				newt;
 	time_t				t;
@@ -1775,7 +1766,7 @@
 			t = lo;
 		else if (t > hi)
 			t = hi;
-		if ((*funcp)(&t, offset, &mytm) == NULL) {
+		if ((*funcp)(sp, &t, offset, &mytm) == NULL) {
 			/*
 			** Assume that t is too extreme to be represented in
 			** a struct tm; arrange things so that it is less
@@ -1810,12 +1801,8 @@
 		** It's okay to guess wrong since the guess
 		** gets checked.
 		*/
-		sp = (const struct state *)
-			((funcp == localsub) ? lclptr : gmtptr);
-#ifdef ALL_STATE
 		if (sp == NULL)
 			return WRONG;
-#endif /* defined ALL_STATE */
 		for (i = sp->typecnt - 1; i >= 0; --i) {
 			if (sp->ttis[i].tt_isdst != yourtm.tm_isdst)
 				continue;
@@ -1824,7 +1811,7 @@
 					continue;
 				newt = t + sp->ttis[j].tt_gmtoff -
 					sp->ttis[i].tt_gmtoff;
-				if ((*funcp)(&newt, offset, &mytm) == NULL)
+				if ((*funcp)(sp, &newt, offset, &mytm) == NULL)
 					continue;
 				if (tmcomp(&mytm, &yourtm) != 0)
 					continue;
@@ -1844,17 +1831,14 @@
 	if ((newt < t) != (saved_seconds < 0))
 		return WRONG;
 	t = newt;
-	if ((*funcp)(&t, offset, tmp))
+	if ((*funcp)(sp, &t, offset, tmp))
 		*okayp = TRUE;
 	return t;
 }
 
 static time_t
-time2(tmp, funcp, offset, okayp)
-struct tm * const	tmp;
-struct tm * (* const	funcp)(const time_t*, long, struct tm*);
-const long		offset;
-int * const		okayp;
+time2(const timezone_t sp, struct tm *const tmp, subfun_t funcp,
+    const long offset, int *const okayp)
 {
 	time_t	t;
 
@@ -1863,22 +1847,19 @@
 	** (in case tm_sec contains a value associated with a leap second).
 	** If that fails, try with normalization of seconds.
 	*/
-	t = time2sub(tmp, funcp, offset, okayp, FALSE);
-	return *okayp ? t : time2sub(tmp, funcp, offset, okayp, TRUE);
+	t = time2sub(sp, tmp, funcp, offset, okayp, FALSE);
+	return *okayp ? t : time2sub(sp, tmp, funcp, offset, okayp, TRUE);
 }
 
 static time_t
-time1(tmp, funcp, offset)
-struct tm * const	tmp;
-struct tm * (* const	funcp)(const time_t *, long, struct tm *);
-const long		offset;
-{
-	register time_t			t;
-	register const struct state *	sp;
-	register int			samei, otheri;
-	register int			sameind, otherind;
-	register int			i;
-	register int			nseen;
+time1(const timezone_t sp, struct tm *const tmp, subfun_t funcp,
+    const long offset)
+{
+	time_t			t;
+	int			samei, otheri;
+	int			sameind, otherind;
+	int			i;
+	int			nseen;
 	int				seen[TZ_MAX_TYPES];
 	int				types[TZ_MAX_TYPES];
 	int				okay;
@@ -1889,7 +1870,7 @@
 	}
 	if (tmp->tm_isdst > 1)
 		tmp->tm_isdst = 1;
-	t = time2(tmp, funcp, offset, &okay);
+	t = time2(sp, tmp, funcp, offset, &okay);
 #ifdef PCTS
 	/*
 	** PCTS code courtesy Grant Sullivan.
@@ -1909,11 +1890,8 @@
 	** We try to divine the type they started from and adjust to the
 	** type they need.
 	*/
-	sp = (const struct state *) ((funcp == localsub) ?  lclptr : gmtptr);
-#ifdef ALL_STATE
 	if (sp == NULL)
 		return WRONG;
-#endif /* defined ALL_STATE */
 	for (i = 0; i < sp->typecnt; ++i)
 		seen[i] = FALSE;
 	nseen = 0;
@@ -1933,7 +1911,7 @@
 			tmp->tm_sec += sp->ttis[otheri].tt_gmtoff -
 					sp->ttis[samei].tt_gmtoff;
 			tmp->tm_isdst = !tmp->tm_isdst;
-			t = time2(tmp, funcp, offset, &okay);
+			t = time2(sp, tmp, funcp, offset, &okay);
 			if (okay)
 				return t;
 			tmp->tm_sec -= sp->ttis[otheri].tt_gmtoff -
@@ -1945,18 +1923,33 @@
 }
 
 time_t
-mktime(tmp)
-struct tm * const	tmp;
+mktime_z(const timezone_t sp, struct tm *const tmp)
+{
+	return time1(sp, tmp, localsub, 0L);
+}
+
+time_t
+mktime(struct tm *const	tmp)
 {
 	tzset();
-	return time1(tmp, localsub, 0L);
+	if (lclptr == NULL)
+		return time1(NULL, tmp, gmtsub, 0L);
+	else
+		return time1(lclptr, tmp, localsub, 0L);
 }
 
 #ifdef STD_INSPIRED
 
 time_t
-timelocal(tmp)
-struct tm * const	tmp;
+timelocal_z(const timezone_t sp, struct tm *const tmp)
+{
+	if (tmp != NULL)
+		tmp->tm_isdst = -1;	/* in case it wasn't initialized */
+	return mktime_z(tmp, sp);
+}
+
+time_t
+timelocal(struct tm *const tmp)
 {
 	if (tmp != NULL)
 		tmp->tm_isdst = -1;	/* in case it wasn't initialized */
@@ -1964,22 +1957,19 @@
 }
 
 time_t
-timegm(tmp)
-struct tm * const	tmp;
+timegm(struct tm *const tmp)
 {
 	if (tmp != NULL)
 		tmp->tm_isdst = 0;
-	return time1(tmp, gmtsub, 0L);
+	return time1(gmtptr, tmp, gmtsub, 0L);
 }
 
 time_t
-timeoff(tmp, offset)
-struct tm * const	tmp;
-const long		offset;
+timeoff(struct tm *const tmp, const long offset)
 {
 	if (tmp != NULL)
 		tmp->tm_isdst = 0;
-	return time1(tmp, gmtsub, offset);
+	return time1(gmtptr, tmp, gmtsub, offset);
 }
 
 #endif /* defined STD_INSPIRED */
@@ -1992,10 +1982,9 @@
 */
 
 long
-gtime(tmp)
-struct tm * const	tmp;
+gtime(struct tm *const tmp)
 {
-	const time_t	t = mktime(tmp);
+	const time_t t = mktime(tmp);
 
 	if (t == WRONG)
 		return -1;
@@ -2019,14 +2008,11 @@
 */
 
 static long
-leapcorr(timep)
-time_t *	timep;
+leapcorr(const timezone_t sp, time_t *timep)
 {
-	register struct state *		sp;
-	register struct lsinfo *	lp;
-	register int			i;
+	struct lsinfo * lp;
+	int		i;
 
-	sp = lclptr;
 	i = sp->leapcnt;
 	while (--i >= 0) {
 		lp = &sp->lsis[i];
@@ -2037,45 +2023,54 @@
 }
 
 time_t
-time2posix(t)
-time_t	t;
+time2posix_z(const timezone_t sp, time_t t)
 {
-	tzset();
-	return t - leapcorr(&t);
+	return t - leapcorr(sp, &t);
+}
+
+time_t
+time2posix(time_t t)
+{
+	return time2posix_z(lclptr, t);
 }
 
+
 time_t
-posix2time(t)
-time_t	t;
+posix2time_z(const timezone_t sp, time_t t)
 {
 	time_t	x;
 	time_t	y;
 
-	tzset();
 	/*
 	** For a positive leap second hit, the result
 	** is not unique. For a negative leap second
 	** hit, the corresponding time doesn't exist,
 	** so we return an adjacent second.
 	*/
-	x = t + leapcorr(&t);
-	y = x - leapcorr(&x);
+	x = t + leapcorr(sp, &t);
+	y = x - leapcorr(sp, &x);
 	if (y < t) {
 		do {
 			x++;
-			y = x - leapcorr(&x);
+			y = x - leapcorr(sp, &x);
 		} while (y < t);
 		if (t != y)
 			return x - 1;
 	} else if (y > t) {
 		do {
 			--x;
-			y = x - leapcorr(&x);
+			y = x - leapcorr(sp, &x);
 		} while (y > t);
 		if (t != y)
 			return x + 1;
 	}
 	return x;
+}
+
+time_t
+posix2time(time_t t)
+{
+	return posix2time_z(lclptr, t);
 }
 
 #endif /* defined STD_INSPIRED */
Index: strftime.c
===================================================================
RCS file: /src/twosigma/cvsroot/external/public/tzcode/strftime.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- strftime.c	30 Sep 2010 20:38:51 -0000	1.1.1.1
+++ strftime.c	30 Sep 2010 21:44:22 -0000	1.2
@@ -36,6 +36,11 @@
 #include "tzfile.h"
 #include "fcntl.h"
 #include "locale.h"
+#include "timeextra.h"
+
+#ifdef HIDE
+#define strftime __strftime
+#endif
 
 struct lc_time_T {
 	const char *	mon[MONSPERYEAR];
@@ -108,8 +113,8 @@
 
 static char *	_add(const char *, char *, const char *);
 static char *	_conv(int, const char *, char *, const char *);
-static char *	_fmt(const char *, const struct tm *, char *, const char *,
-			int *);
+static char *	_fmt(const timezone_t, const char *, const struct tm *, char *,
+			const char *, int *);
 static char *	_yconv(int, int, int, int, char *, const char *);
 
 extern char *	tzname[];
@@ -124,21 +129,18 @@
 #define IN_ALL	3
 
 size_t
-strftime(s, maxsize, format, t)
-char * const		s;
-const size_t		maxsize;
-const char * const	format;
-const struct tm * const	t;
+strftime_z(const timezone_t sp, char * const s, const size_t maxsize,
+    const char * const format, const struct tm * const	t)
 {
 	char *	p;
 	int	warn;
 
-	tzset();
 #ifdef LOCALE_HOME
 	localebuf.mon[0] = 0;
 #endif /* defined LOCALE_HOME */
 	warn = IN_NONE;
-	p = _fmt(((format == NULL) ? "%c" : format), t, s, s + maxsize, &warn);
+	p = _fmt(sp, ((format == NULL) ? "%c" : format), t, s, s + maxsize,
+	    &warn);
 #ifndef NO_RUN_TIME_WARNINGS_ABOUT_YEAR_2000_PROBLEMS_THANK_YOU
 	if (warn != IN_NONE && getenv(YEAR_2000_NAME) != NULL) {
 		(void) fprintf(stderr, "\n");
@@ -162,12 +164,8 @@
 }
 
 static char *
-_fmt(format, t, pt, ptlim, warnp)
-const char *		format;
-const struct tm * const	t;
-char *			pt;
-const char * const	ptlim;
-int *			warnp;
+_fmt(const timezone_t sp, const char *format, const struct tm * const t,
+	char *pt, const char *const ptlim, int *warnp)
 {
 	for ( ; *format; ++format) {
 		if (*format == '%') {
@@ -216,7 +214,7 @@
 				{
 				int warn2 = IN_SOME;
 
-				pt = _fmt(Locale->c_fmt, t, pt, ptlim, &warn2);
+				pt = _fmt(sp, Locale->c_fmt, t, pt, ptlim, &warn2);
 				if (warn2 == IN_ALL)
 					warn2 = IN_THIS;
 				if (warn2 > *warnp)
@@ -224,7 +222,7 @@
 				}
 				continue;
 			case 'D':
-				pt = _fmt("%m/%d/%y", t, pt, ptlim, warnp);
+				pt = _fmt(sp, "%m/%d/%y", t, pt, ptlim, warnp);
 				continue;
 			case 'd':
 				pt = _conv(t->tm_mday, "%02d", pt, ptlim);
@@ -245,7 +243,7 @@
 				pt = _conv(t->tm_mday, "%2d", pt, ptlim);
 				continue;
 			case 'F':
-				pt = _fmt("%Y-%m-%d", t, pt, ptlim, warnp);
+				pt = _fmt(sp, "%Y-%m-%d", t, pt, ptlim, warnp);
 				continue;
 			case 'H':
 				pt = _conv(t->tm_hour, "%02d", pt, ptlim);
@@ -309,10 +307,10 @@
 					pt, ptlim);
 				continue;
 			case 'R':
-				pt = _fmt("%H:%M", t, pt, ptlim, warnp);
+				pt = _fmt(sp, "%H:%M", t, pt, ptlim, warnp);
 				continue;
 			case 'r':
-				pt = _fmt("%I:%M:%S %p", t, pt, ptlim, warnp);
+				pt = _fmt(sp, "%I:%M:%S %p", t, pt, ptlim, warnp);
 				continue;
 			case 'S':
 				pt = _conv(t->tm_sec, "%02d", pt, ptlim);
@@ -335,7 +333,7 @@
 				}
 				continue;
 			case 'T':
-				pt = _fmt("%H:%M:%S", t, pt, ptlim, warnp);
+				pt = _fmt(sp, "%H:%M:%S", t, pt, ptlim, warnp);
 				continue;
 			case 't':
 				pt = _add("\t", pt, ptlim);
@@ -450,7 +448,7 @@
 				** "date as dd-bbb-YYYY"
 				** (ado, 1993-05-24)
 				*/
-				pt = _fmt("%e-%b-%Y", t, pt, ptlim, warnp);
+				pt = _fmt(sp, "%e-%b-%Y", t, pt, ptlim, warnp);
 				continue;
 			case 'W':
 				pt = _conv((t->tm_yday + DAYSPERWEEK -
@@ -463,13 +461,13 @@
 				pt = _conv(t->tm_wday, "%d", pt, ptlim);
 				continue;
 			case 'X':
-				pt = _fmt(Locale->X_fmt, t, pt, ptlim, warnp);
+				pt = _fmt(sp, Locale->X_fmt, t, pt, ptlim, warnp);
 				continue;
 			case 'x':
 				{
 				int	warn2 = IN_SOME;
 
-				pt = _fmt(Locale->x_fmt, t, pt, ptlim, &warn2);
+				pt = _fmt(sp, Locale->x_fmt, t, pt, ptlim, &warn2);
 				if (warn2 == IN_ALL)
 					warn2 = IN_THIS;
 				if (warn2 > *warnp)
@@ -492,8 +490,10 @@
 				else
 #endif /* defined TM_ZONE */
 				if (t->tm_isdst >= 0)
-					pt = _add(tzname[t->tm_isdst != 0],
-						pt, ptlim);
+					pt = _add((sp ?
+					    tzgetname(sp, t->tm_isdst) :
+					    tzname[t->tm_isdst != 0]),
+					    pt, ptlim);
 				/*
 				** C99 says that %Z must be replaced by the
 				** empty string if the time zone is not
@@ -554,7 +554,7 @@
 				}
 				continue;
 			case '+':
-				pt = _fmt(Locale->date_fmt, t, pt, ptlim,
+				pt = _fmt(sp, Locale->date_fmt, t, pt, ptlim,
 					warnp);
 				continue;
 			case '%':
@@ -572,6 +572,14 @@
 		*pt++ = *format;
 	}
 	return pt;
+}
+
+size_t
+strftime(char * const s, const size_t maxsize,
+    const char * const format, const struct tm * const	t)
+{
+	tzset();
+	return strftime_z(NULL, s, maxsize, format, t);
 }
 
 static char *
--- /dev/null	2005-11-17 13:47:49.000000000 -0500
+++ timeextra.h	2010-09-30 17:04:29.734633589 -0400
@@ -0,0 +1,23 @@
+
+#ifndef _TIMEEXTRA_H_
+#define _TIMEEXTRA_H_
+
+#include <time.h>
+
+__BEGIN_DECLS
+typedef struct __state *timezone_t;
+
+const timezone_t	tzalloc(const char *);
+void		tzfree(const timezone_t);
+const char *	tzgetname(const timezone_t, int);
+struct tm *	localtime_z(const timezone_t, const time_t *, struct tm *);
+char *		ctime_z(const timezone_t, const time_t *, char *);
+time_t		timelocal_z(const timezone_t, struct tm *);
+time_t		mktime_z(const timezone_t, struct tm *);
+time_t		time2posix_z(const timezone_t, time_t);
+time_t		posix2time_z(const timezone_t, time_t);
+size_t		strftime_z(const timezone_t, char *, size_t, const char *,
+			   const struct tm *);
+__END_DECLS
+
+#endif /* _TIMEEXTRA_H_ */



More information about the tz mailing list