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