1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/i18n/olsontz.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,451 @@ 1.4 +/* 1.5 +********************************************************************** 1.6 +* Copyright (c) 2003-2013, International Business Machines 1.7 +* Corporation and others. All Rights Reserved. 1.8 +********************************************************************** 1.9 +* Author: Alan Liu 1.10 +* Created: July 21 2003 1.11 +* Since: ICU 2.8 1.12 +********************************************************************** 1.13 +*/ 1.14 +#ifndef OLSONTZ_H 1.15 +#define OLSONTZ_H 1.16 + 1.17 +#include "unicode/utypes.h" 1.18 + 1.19 +#if !UCONFIG_NO_FORMATTING 1.20 + 1.21 +#include "unicode/basictz.h" 1.22 +#include "umutex.h" 1.23 + 1.24 +struct UResourceBundle; 1.25 + 1.26 +U_NAMESPACE_BEGIN 1.27 + 1.28 +class SimpleTimeZone; 1.29 + 1.30 +/** 1.31 + * A time zone based on the Olson tz database. Olson time zones change 1.32 + * behavior over time. The raw offset, rules, presence or absence of 1.33 + * daylight savings time, and even the daylight savings amount can all 1.34 + * vary. 1.35 + * 1.36 + * This class uses a resource bundle named "zoneinfo". Zoneinfo is a 1.37 + * table containing different kinds of resources. In several places, 1.38 + * zones are referred to using integers. A zone's integer is a number 1.39 + * from 0..n-1, where n is the number of zones, with the zones sorted 1.40 + * in lexicographic order. 1.41 + * 1.42 + * 1. Zones. These have keys corresponding to the Olson IDs, e.g., 1.43 + * "Asia/Shanghai". Each resource describes the behavior of the given 1.44 + * zone. Zones come in two different formats. 1.45 + * 1.46 + * a. Zone (table). A zone is a table resource contains several 1.47 + * type of resources below: 1.48 + * 1.49 + * - typeOffsets:intvector (Required) 1.50 + * 1.51 + * Sets of UTC raw/dst offset pairs in seconds. Entries at 1.52 + * 2n represents raw offset and 2n+1 represents dst offset 1.53 + * paired with the raw offset at 2n. The very first pair represents 1.54 + * the initial zone offset (before the first transition) always. 1.55 + * 1.56 + * - trans:intvector (Optional) 1.57 + * 1.58 + * List of transition times represented by 32bit seconds from the 1.59 + * epoch (1970-01-01T00:00Z) in ascending order. 1.60 + * 1.61 + * - transPre32/transPost32:intvector (Optional) 1.62 + * 1.63 + * List of transition times before/after 32bit minimum seconds. 1.64 + * Each time is represented by a pair of 32bit integer. 1.65 + * 1.66 + * - typeMap:bin (Optional) 1.67 + * 1.68 + * Array of bytes representing the mapping between each transition 1.69 + * time (transPre32/trans/transPost32) and its corresponding offset 1.70 + * data (typeOffsets). 1.71 + * 1.72 + * - finalRule:string (Optional) 1.73 + * 1.74 + * If a recurrent transition rule is applicable to a zone forever 1.75 + * after the final transition time, finalRule represents the rule 1.76 + * in Rules data. 1.77 + * 1.78 + * - finalRaw:int (Optional) 1.79 + * 1.80 + * When finalRule is available, finalRaw is required and specifies 1.81 + * the raw (base) offset of the rule. 1.82 + * 1.83 + * - finalYear:int (Optional) 1.84 + * 1.85 + * When finalRule is available, finalYear is required and specifies 1.86 + * the start year of the rule. 1.87 + * 1.88 + * - links:intvector (Optional) 1.89 + * 1.90 + * When this zone data is shared with other zones, links specifies 1.91 + * all zones including the zone itself. Each zone is referenced by 1.92 + * integer index. 1.93 + * 1.94 + * b. Link (int, length 1). A link zone is an int resource. The 1.95 + * integer is the zone number of the target zone. The key of this 1.96 + * resource is an alternate name for the target zone. This data 1.97 + * is corresponding to Link data in the tz database. 1.98 + * 1.99 + * 1.100 + * 2. Rules. These have keys corresponding to the Olson rule IDs, 1.101 + * with an underscore prepended, e.g., "_EU". Each resource describes 1.102 + * the behavior of the given rule using an intvector, containing the 1.103 + * onset list, the cessation list, and the DST savings. The onset and 1.104 + * cessation lists consist of the month, dowim, dow, time, and time 1.105 + * mode. The end result is that the 11 integers describing the rule 1.106 + * can be passed directly into the SimpleTimeZone 13-argument 1.107 + * constructor (the other two arguments will be the raw offset, taken 1.108 + * from the complex zone element 5, and the ID string, which is not 1.109 + * used), with the times and the DST savings multiplied by 1000 to 1.110 + * scale from seconds to milliseconds. 1.111 + * 1.112 + * 3. Regions. An array specifies mapping between zones and regions. 1.113 + * Each item is either a 2-letter ISO country code or "001" 1.114 + * (UN M.49 - World). This data is generated from "zone.tab" 1.115 + * in the tz database. 1.116 + */ 1.117 +class U_I18N_API OlsonTimeZone: public BasicTimeZone { 1.118 + public: 1.119 + /** 1.120 + * Construct from a resource bundle. 1.121 + * @param top the top-level zoneinfo resource bundle. This is used 1.122 + * to lookup the rule that `res' may refer to, if there is one. 1.123 + * @param res the resource bundle of the zone to be constructed 1.124 + * @param tzid the time zone ID 1.125 + * @param ec input-output error code 1.126 + */ 1.127 + OlsonTimeZone(const UResourceBundle* top, 1.128 + const UResourceBundle* res, 1.129 + const UnicodeString& tzid, 1.130 + UErrorCode& ec); 1.131 + 1.132 + /** 1.133 + * Copy constructor 1.134 + */ 1.135 + OlsonTimeZone(const OlsonTimeZone& other); 1.136 + 1.137 + /** 1.138 + * Destructor 1.139 + */ 1.140 + virtual ~OlsonTimeZone(); 1.141 + 1.142 + /** 1.143 + * Assignment operator 1.144 + */ 1.145 + OlsonTimeZone& operator=(const OlsonTimeZone& other); 1.146 + 1.147 + /** 1.148 + * Returns true if the two TimeZone objects are equal. 1.149 + */ 1.150 + virtual UBool operator==(const TimeZone& other) const; 1.151 + 1.152 + /** 1.153 + * TimeZone API. 1.154 + */ 1.155 + virtual TimeZone* clone() const; 1.156 + 1.157 + /** 1.158 + * TimeZone API. 1.159 + */ 1.160 + static UClassID U_EXPORT2 getStaticClassID(); 1.161 + 1.162 + /** 1.163 + * TimeZone API. 1.164 + */ 1.165 + virtual UClassID getDynamicClassID() const; 1.166 + 1.167 + /** 1.168 + * TimeZone API. Do not call this; prefer getOffset(UDate,...). 1.169 + */ 1.170 + virtual int32_t getOffset(uint8_t era, int32_t year, int32_t month, 1.171 + int32_t day, uint8_t dayOfWeek, 1.172 + int32_t millis, UErrorCode& ec) const; 1.173 + 1.174 + /** 1.175 + * TimeZone API. Do not call this; prefer getOffset(UDate,...). 1.176 + */ 1.177 + virtual int32_t getOffset(uint8_t era, int32_t year, int32_t month, 1.178 + int32_t day, uint8_t dayOfWeek, 1.179 + int32_t millis, int32_t monthLength, 1.180 + UErrorCode& ec) const; 1.181 + 1.182 + /** 1.183 + * TimeZone API. 1.184 + */ 1.185 + virtual void getOffset(UDate date, UBool local, int32_t& rawOffset, 1.186 + int32_t& dstOffset, UErrorCode& ec) const; 1.187 + 1.188 + /** 1.189 + * BasicTimeZone API. 1.190 + */ 1.191 + virtual void getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt, 1.192 + int32_t& rawoff, int32_t& dstoff, UErrorCode& ec) const; 1.193 + 1.194 + /** 1.195 + * TimeZone API. This method has no effect since objects of this 1.196 + * class are quasi-immutable (the base class allows the ID to be 1.197 + * changed). 1.198 + */ 1.199 + virtual void setRawOffset(int32_t offsetMillis); 1.200 + 1.201 + /** 1.202 + * TimeZone API. For a historical zone, the raw offset can change 1.203 + * over time, so this API is not useful. In order to approximate 1.204 + * expected behavior, this method returns the raw offset for the 1.205 + * current moment in time. 1.206 + */ 1.207 + virtual int32_t getRawOffset() const; 1.208 + 1.209 + /** 1.210 + * TimeZone API. For a historical zone, whether DST is used or 1.211 + * not varies over time. In order to approximate expected 1.212 + * behavior, this method returns TRUE if DST is observed at any 1.213 + * point in the current year. 1.214 + */ 1.215 + virtual UBool useDaylightTime() const; 1.216 + 1.217 + /** 1.218 + * TimeZone API. 1.219 + */ 1.220 + virtual UBool inDaylightTime(UDate date, UErrorCode& ec) const; 1.221 + 1.222 + /** 1.223 + * TimeZone API. 1.224 + */ 1.225 + virtual int32_t getDSTSavings() const; 1.226 + 1.227 + /** 1.228 + * TimeZone API. Also comare historic transitions. 1.229 + */ 1.230 + virtual UBool hasSameRules(const TimeZone& other) const; 1.231 + 1.232 + /** 1.233 + * BasicTimeZone API. 1.234 + * Gets the first time zone transition after the base time. 1.235 + * @param base The base time. 1.236 + * @param inclusive Whether the base time is inclusive or not. 1.237 + * @param result Receives the first transition after the base time. 1.238 + * @return TRUE if the transition is found. 1.239 + */ 1.240 + virtual UBool getNextTransition(UDate base, UBool inclusive, TimeZoneTransition& result) const; 1.241 + 1.242 + /** 1.243 + * BasicTimeZone API. 1.244 + * Gets the most recent time zone transition before the base time. 1.245 + * @param base The base time. 1.246 + * @param inclusive Whether the base time is inclusive or not. 1.247 + * @param result Receives the most recent transition before the base time. 1.248 + * @return TRUE if the transition is found. 1.249 + */ 1.250 + virtual UBool getPreviousTransition(UDate base, UBool inclusive, TimeZoneTransition& result) const; 1.251 + 1.252 + /** 1.253 + * BasicTimeZone API. 1.254 + * Returns the number of <code>TimeZoneRule</code>s which represents time transitions, 1.255 + * for this time zone, that is, all <code>TimeZoneRule</code>s for this time zone except 1.256 + * <code>InitialTimeZoneRule</code>. The return value range is 0 or any positive value. 1.257 + * @param status Receives error status code. 1.258 + * @return The number of <code>TimeZoneRule</code>s representing time transitions. 1.259 + */ 1.260 + virtual int32_t countTransitionRules(UErrorCode& status) const; 1.261 + 1.262 + /** 1.263 + * Gets the <code>InitialTimeZoneRule</code> and the set of <code>TimeZoneRule</code> 1.264 + * which represent time transitions for this time zone. On successful return, 1.265 + * the argument initial points to non-NULL <code>InitialTimeZoneRule</code> and 1.266 + * the array trsrules is filled with 0 or multiple <code>TimeZoneRule</code> 1.267 + * instances up to the size specified by trscount. The results are referencing the 1.268 + * rule instance held by this time zone instance. Therefore, after this time zone 1.269 + * is destructed, they are no longer available. 1.270 + * @param initial Receives the initial timezone rule 1.271 + * @param trsrules Receives the timezone transition rules 1.272 + * @param trscount On input, specify the size of the array 'transitions' receiving 1.273 + * the timezone transition rules. On output, actual number of 1.274 + * rules filled in the array will be set. 1.275 + * @param status Receives error status code. 1.276 + */ 1.277 + virtual void getTimeZoneRules(const InitialTimeZoneRule*& initial, 1.278 + const TimeZoneRule* trsrules[], int32_t& trscount, UErrorCode& status) const; 1.279 + 1.280 + /** 1.281 + * Internal API returning the canonical ID of this zone. 1.282 + * This ID won't be affected by setID(). 1.283 + */ 1.284 + const UChar *getCanonicalID() const; 1.285 + 1.286 +private: 1.287 + /** 1.288 + * Default constructor. Creates a time zone with an empty ID and 1.289 + * a fixed GMT offset of zero. 1.290 + */ 1.291 + OlsonTimeZone(); 1.292 + 1.293 +private: 1.294 + 1.295 + void constructEmpty(); 1.296 + 1.297 + void getHistoricalOffset(UDate date, UBool local, 1.298 + int32_t NonExistingTimeOpt, int32_t DuplicatedTimeOpt, 1.299 + int32_t& rawoff, int32_t& dstoff) const; 1.300 + 1.301 + int16_t transitionCount() const; 1.302 + 1.303 + int64_t transitionTimeInSeconds(int16_t transIdx) const; 1.304 + double transitionTime(int16_t transIdx) const; 1.305 + 1.306 + /* 1.307 + * Following 3 methods return an offset at the given transition time index. 1.308 + * When the index is negative, return the initial offset. 1.309 + */ 1.310 + int32_t zoneOffsetAt(int16_t transIdx) const; 1.311 + int32_t rawOffsetAt(int16_t transIdx) const; 1.312 + int32_t dstOffsetAt(int16_t transIdx) const; 1.313 + 1.314 + /* 1.315 + * Following methods return the initial offset. 1.316 + */ 1.317 + int32_t initialRawOffset() const; 1.318 + int32_t initialDstOffset() const; 1.319 + 1.320 + /** 1.321 + * Number of transitions in each time range 1.322 + */ 1.323 + int16_t transitionCountPre32; 1.324 + int16_t transitionCount32; 1.325 + int16_t transitionCountPost32; 1.326 + 1.327 + /** 1.328 + * Time of each transition in seconds from 1970 epoch before 32bit second range (<= 1900). 1.329 + * Each transition in this range is represented by a pair of int32_t. 1.330 + * Length is transitionCount int32_t's. NULL if no transitions in this range. 1.331 + */ 1.332 + const int32_t *transitionTimesPre32; // alias into res; do not delete 1.333 + 1.334 + /** 1.335 + * Time of each transition in seconds from 1970 epoch in 32bit second range. 1.336 + * Length is transitionCount int32_t's. NULL if no transitions in this range. 1.337 + */ 1.338 + const int32_t *transitionTimes32; // alias into res; do not delete 1.339 + 1.340 + /** 1.341 + * Time of each transition in seconds from 1970 epoch after 32bit second range (>= 2038). 1.342 + * Each transition in this range is represented by a pair of int32_t. 1.343 + * Length is transitionCount int32_t's. NULL if no transitions in this range. 1.344 + */ 1.345 + const int32_t *transitionTimesPost32; // alias into res; do not delete 1.346 + 1.347 + /** 1.348 + * Number of types, 1..255 1.349 + */ 1.350 + int16_t typeCount; 1.351 + 1.352 + /** 1.353 + * Offset from GMT in seconds for each type. 1.354 + * Length is typeCount int32_t's. At least one type (a pair of int32_t) 1.355 + * is required. 1.356 + */ 1.357 + const int32_t *typeOffsets; // alias into res; do not delete 1.358 + 1.359 + /** 1.360 + * Type description data, consisting of transitionCount uint8_t 1.361 + * type indices (from 0..typeCount-1). 1.362 + * Length is transitionCount int16_t's. NULL if no transitions. 1.363 + */ 1.364 + const uint8_t *typeMapData; // alias into res; do not delete 1.365 + 1.366 + /** 1.367 + * A SimpleTimeZone that governs the behavior for date >= finalMillis. 1.368 + */ 1.369 + SimpleTimeZone *finalZone; // owned, may be NULL 1.370 + 1.371 + /** 1.372 + * For date >= finalMillis, the finalZone will be used. 1.373 + */ 1.374 + double finalStartMillis; 1.375 + 1.376 + /** 1.377 + * For year >= finalYear, the finalZone will be used. 1.378 + */ 1.379 + int32_t finalStartYear; 1.380 + 1.381 + /* 1.382 + * Canonical (CLDR) ID of this zone 1.383 + */ 1.384 + const UChar *canonicalID; 1.385 + 1.386 + /* BasicTimeZone support */ 1.387 + void clearTransitionRules(void); 1.388 + void deleteTransitionRules(void); 1.389 + void checkTransitionRules(UErrorCode& status) const; 1.390 + 1.391 + public: // Internal, for access from plain C code 1.392 + void initTransitionRules(UErrorCode& status); 1.393 + private: 1.394 + 1.395 + InitialTimeZoneRule *initialRule; 1.396 + TimeZoneTransition *firstTZTransition; 1.397 + int16_t firstTZTransitionIdx; 1.398 + TimeZoneTransition *firstFinalTZTransition; 1.399 + TimeArrayTimeZoneRule **historicRules; 1.400 + int16_t historicRuleCount; 1.401 + SimpleTimeZone *finalZoneWithStartYear; // hack 1.402 + UInitOnce transitionRulesInitOnce; 1.403 +}; 1.404 + 1.405 +inline int16_t 1.406 +OlsonTimeZone::transitionCount() const { 1.407 + return transitionCountPre32 + transitionCount32 + transitionCountPost32; 1.408 +} 1.409 + 1.410 +inline double 1.411 +OlsonTimeZone::transitionTime(int16_t transIdx) const { 1.412 + return (double)transitionTimeInSeconds(transIdx) * U_MILLIS_PER_SECOND; 1.413 +} 1.414 + 1.415 +inline int32_t 1.416 +OlsonTimeZone::zoneOffsetAt(int16_t transIdx) const { 1.417 + int16_t typeIdx = (transIdx >= 0 ? typeMapData[transIdx] : 0) << 1; 1.418 + return typeOffsets[typeIdx] + typeOffsets[typeIdx + 1]; 1.419 +} 1.420 + 1.421 +inline int32_t 1.422 +OlsonTimeZone::rawOffsetAt(int16_t transIdx) const { 1.423 + int16_t typeIdx = (transIdx >= 0 ? typeMapData[transIdx] : 0) << 1; 1.424 + return typeOffsets[typeIdx]; 1.425 +} 1.426 + 1.427 +inline int32_t 1.428 +OlsonTimeZone::dstOffsetAt(int16_t transIdx) const { 1.429 + int16_t typeIdx = (transIdx >= 0 ? typeMapData[transIdx] : 0) << 1; 1.430 + return typeOffsets[typeIdx + 1]; 1.431 +} 1.432 + 1.433 +inline int32_t 1.434 +OlsonTimeZone::initialRawOffset() const { 1.435 + return typeOffsets[0]; 1.436 +} 1.437 + 1.438 +inline int32_t 1.439 +OlsonTimeZone::initialDstOffset() const { 1.440 + return typeOffsets[1]; 1.441 +} 1.442 + 1.443 +inline const UChar* 1.444 +OlsonTimeZone::getCanonicalID() const { 1.445 + return canonicalID; 1.446 +} 1.447 + 1.448 + 1.449 +U_NAMESPACE_END 1.450 + 1.451 +#endif // !UCONFIG_NO_FORMATTING 1.452 +#endif // OLSONTZ_H 1.453 + 1.454 +//eof