xref: /illumos-gate/usr/src/head/tzfile.h (revision e496dfa829828890965fbb5999e68cd49e019aea)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 /*	Copyright (c) 1988 AT&T	*/
27 /*	  All Rights Reserved	*/
28 
29 #ifndef _TZFILE_H
30 #define	_TZFILE_H
31 
32 /*
33  * A part of this file comes from public domain source, so
34  * clarified as of June 5, 1996 by Arthur David Olson
35  */
36 
37 #include <sys/types.h>
38 
39 /*
40  * WARNING:
41  * The interfaces defined in this header file are for Sun private use only.
42  * The contents of this file are subject to change without notice for the
43  * future releases.
44  */
45 
46 /* For further information, see ctime(3C) and zic(8) man pages. */
47 
48 /*
49  * This file is in the public domain, so clarified as of
50  * 1996-06-05 by Arthur David Olson.
51  */
52 
53 /*
54  * This header is for use ONLY with the time conversion code.
55  * There is no guarantee that it will remain unchanged,
56  * or that it will remain at all.
57  * Do NOT copy it to any system include directory.
58  * Thank you!
59  */
60 
61 /*
62  * Note: Despite warnings from the authors of this code, Solaris has
63  * placed this header file in the system include directory.  This was
64  * probably done in order to build both zic and zdump which are in
65  * separate source directories, but both use this file.
66  */
67 
68 #ifdef	__cplusplus
69 extern "C" {
70 #endif
71 
72 /*
73  * Information about time zone files.
74  */
75 
76 #ifndef TZDIR
77 #define	TZDIR	"/usr/share/lib/zoneinfo" /* Time zone object file directory */
78 #endif /* !defined TZDIR */
79 
80 #ifndef TZDEFAULT
81 #define	TZDEFAULT	"localtime"
82 #endif /* !defined TZDEFAULT */
83 
84 #ifndef TZDEFRULES
85 #define	TZDEFRULES	"posixrules"
86 #endif /* !defined TZDEFRULES */
87 
88 
89 /* See Internet RFC 9636 for more details about the following format.  */
90 
91 /*
92  * Each file begins with. . .
93  */
94 
95 #define	TZ_MAGIC	"TZif"
96 
97 struct tzhead {
98 	char	tzh_magic[4];		/* TZ_MAGIC */
99 	char	tzh_version[1];		/* '\0' or '2'-'4' as of 2021 */
100 	char	tzh_reserved[15];	/* reserved; must be zero */
101 	char	tzh_ttisutcnt[4];	/* coded number of trans. time flags */
102 	char	tzh_ttisstdcnt[4];	/* coded number of trans. time flags */
103 	char	tzh_leapcnt[4];		/* coded number of leap seconds */
104 	char	tzh_timecnt[4];		/* coded number of transition times */
105 	char	tzh_typecnt[4];		/* coded number of local time types */
106 	char	tzh_charcnt[4];		/* coded number of abbr. chars */
107 };
108 
109 /*
110  * . . .followed by. . .
111  *
112  *	tzh_timecnt (char [4])s		coded transition times a la time(2)
113  *	tzh_timecnt (unsigned char)s	types of local time starting at above
114  *	tzh_typecnt repetitions of
115  *		one (char [4])		coded UT offset in seconds
116  *		one (unsigned char)	used to set tm_isdst
117  *		one (unsigned char)	that's an abbreviation list index
118  *	tzh_charcnt (char)s		'\0'-terminated zone abbreviations
119  *	tzh_leapcnt repetitions of
120  *		one (char [4])		coded leap second transition times
121  *		one (char [4])		total correction after above
122  *	tzh_ttisstdcnt (char)s		indexed by type; if 1, transition
123  *					time is standard time, if 0,
124  *					transition time is local (wall clock)
125  *					time; if absent, transition times are
126  *					assumed to be local time
127  *	tzh_ttisutcnt (char)s		indexed by type; if 1, transition
128  *					time is UT, if 0, transition time is
129  *					local time; if absent, transition
130  *					times are assumed to be local time.
131  *					When this is 1, the corresponding
132  *					std/wall indicator must also be 1.
133  */
134 
135 /*
136  * If tzh_version is '2' or greater, the above is followed by a second instance
137  * of tzhead and a second instance of the data in which each coded transition
138  * time uses 8 rather than 4 chars,
139  * then a POSIX.1-2017 proleptic TZ string for use in handling
140  * instants after the last transition time stored in the file
141  * (with nothing between the newlines if there is no POSIX.1-2017
142  * representation for such instants).
143  *
144  * If tz_version is '3' or greater, the TZ string can be any POSIX.1-2024
145  * proleptic TZ string, which means the above is extended as follows.
146  * First, the TZ string's hour offset may range from -167
147  * through 167 as compared to the range 0 through 24 required
148  * by POSIX.1-2017 and earlier.
149  * Second, its DST start time may be January 1 at 00:00 and its stop
150  * time December 31 at 24:00 plus the difference between DST and
151  * standard time, indicating DST all year.
152  */
153 
154 /*
155  * In the current implementation, "tzset()" refuses to deal with files that
156  * exceed any of the limits below.
157  */
158 
159 #ifndef TZ_MAX_TIMES
160 /*
161  * The TZ_MAX_TIMES value below is enough to handle a bit more than a
162  * year's worth of solar time (corrected daily to the nearest second) or
163  * 138 years of Pacific Presidential Election time
164  * (where there are three time zone transitions every fourth year).
165  */
166 #define	TZ_MAX_TIMES 370
167 #endif /* !defined TZ_MAX_TIMES */
168 
169 #ifndef TZ_MAX_TYPES
170 /* This must be at least 18 for Europe/Vilnius with 'zic -b fat'.  */
171 #define	TZ_MAX_TYPES 256 /* Limited by what (unsigned char)'s can hold */
172 #endif /* !defined TZ_MAX_TYPES */
173 
174 #ifndef TZ_MAX_CHARS
175 /* This must be at least 40 for America/Anchorage.  */
176 #define	TZ_MAX_CHARS	50	/* Maximum number of abbreviation characters */
177 				/* (limited by what unsigned chars can hold) */
178 #endif /* !defined TZ_MAX_CHARS */
179 
180 #ifndef TZ_MAX_LEAPS
181 /* This must be at least 27 for leap seconds from 1972 through mid-2023. */
182 /* There's a plan to discontinue leap seconds by 2035.  */
183 #define	TZ_MAX_LEAPS 50	/* Maximum number of leap second corrections */
184 #endif /* !defined TZ_MAX_LEAPS */
185 
186 /* Handy macros that are independent of tzfile implementation.  */
187 
188 enum {
189 	SECSPERMIN = 60,
190 	MINSPERHOUR = 60,
191 	SECSPERHOUR = SECSPERMIN * MINSPERHOUR,
192 	HOURSPERDAY = 24,
193 	DAYSPERWEEK = 7,
194 	DAYSPERNYEAR = 365,
195 	DAYSPERLYEAR = DAYSPERNYEAR + 1,
196 	MONSPERYEAR = 12,
197 	YEARSPERREPEAT = 400	/* years before a Gregorian repeat */
198 };
199 
200 #define	SECSPERDAY	((int_fast32_t)SECSPERHOUR * HOURSPERDAY)
201 
202 #define	DAYSPERREPEAT		((int_fast32_t)400 * 365 + 100 - 4 + 1)
203 #define	SECSPERREPEAT		((int_fast64_t)DAYSPERREPEAT * SECSPERDAY)
204 #define	AVGSECSPERYEAR		(SECSPERREPEAT / YEARSPERREPEAT)
205 
206 /*
207  * How many years to generate (in zic.c) or search through (in localtime.c).
208  * This is two years larger than the obvious 400, to avoid edge cases.
209  * E.g., suppose a rule applies from 2012 on with transitions
210  * in March and September, plus one-off transitions in November 2013,
211  * and suppose the rule cannot be expressed as a proleptic TZ string.
212  * If zic looked only at the last 400 years, it would set max_year=2413,
213  * with the intent that the 400 years 2014 through 2413 will be repeated.
214  * The last transition listed in the tzfile would be in 2413-09,
215  * less than 400 years after the last one-off transition in 2013-11.
216  * Two years is not overkill for localtime.c, as a one-year bump
217  * would mishandle 2023d's America/Ciudad_Juarez for November 2422.
218  */
219 enum { years_of_observations = YEARSPERREPEAT + 2 };
220 
221 enum {
222 	TM_SUNDAY,
223 	TM_MONDAY,
224 	TM_TUESDAY,
225 	TM_WEDNESDAY,
226 	TM_THURSDAY,
227 	TM_FRIDAY,
228 	TM_SATURDAY
229 };
230 
231 enum {
232 	TM_JANUARY,
233 	TM_FEBRUARY,
234 	TM_MARCH,
235 	TM_APRIL,
236 	TM_MAY,
237 	TM_JUNE,
238 	TM_JULY,
239 	TM_AUGUST,
240 	TM_SEPTEMBER,
241 	TM_OCTOBER,
242 	TM_NOVEMBER,
243 	TM_DECEMBER
244 };
245 
246 enum {
247 	TM_YEAR_BASE = 1900,
248 	TM_WDAY_BASE = TM_MONDAY,
249 	EPOCH_YEAR = 1970,
250 	EPOCH_WDAY = TM_THURSDAY
251 };
252 
253 #define	isleap(y) (((y) % 4) == 0 && (((y) % 100) != 0 || ((y) % 400) == 0))
254 
255 /*
256  * Since everything in isleap is modulo 400 (or a factor of 400), we know that
257  *	isleap(y) == isleap(y % 400)
258  * and so
259  *	isleap(a + b) == isleap((a + b) % 400)
260  * or
261  *	isleap(a + b) == isleap(a % 400 + b % 400)
262  * This is true even if % means modulo rather than Fortran remainder
263  * (which is allowed by C89 but not by C99 or later).
264  * We use this to avoid addition overflow problems.
265  */
266 
267 #define	isleap_sum(a, b)	isleap((a) % 400 + (b) % 400)
268 
269 #ifdef	__cplusplus
270 }
271 #endif
272 
273 #endif	/* _TZFILE_H */
274