OLD | NEW |
(Empty) | |
| 1 /* |
| 2 ********************************************************************** |
| 3 * Copyright (c) 2003-2010, International Business Machines |
| 4 * Corporation and others. All Rights Reserved. |
| 5 ********************************************************************** |
| 6 * Author: Alan Liu |
| 7 * Created: July 21 2003 |
| 8 * Since: ICU 2.8 |
| 9 ********************************************************************** |
| 10 */ |
| 11 #ifndef OLSONTZ_H |
| 12 #define OLSONTZ_H |
| 13 |
| 14 #include "unicode/utypes.h" |
| 15 |
| 16 #if !UCONFIG_NO_FORMATTING |
| 17 |
| 18 #include "unicode/basictz.h" |
| 19 |
| 20 struct UResourceBundle; |
| 21 |
| 22 U_NAMESPACE_BEGIN |
| 23 |
| 24 class SimpleTimeZone; |
| 25 |
| 26 /** |
| 27 * A time zone based on the Olson tz database. Olson time zones change |
| 28 * behavior over time. The raw offset, rules, presence or absence of |
| 29 * daylight savings time, and even the daylight savings amount can all |
| 30 * vary. |
| 31 * |
| 32 * This class uses a resource bundle named "zoneinfo". Zoneinfo is a |
| 33 * table containing different kinds of resources. In several places, |
| 34 * zones are referred to using integers. A zone's integer is a number |
| 35 * from 0..n-1, where n is the number of zones, with the zones sorted |
| 36 * in lexicographic order. |
| 37 * |
| 38 * 1. Zones. These have keys corresponding to the Olson IDs, e.g., |
| 39 * "Asia/Shanghai". Each resource describes the behavior of the given |
| 40 * zone. Zones come in two different formats. |
| 41 * |
| 42 * a. Zone (table). A zone is a table resource contains several |
| 43 * type of resources below: |
| 44 * |
| 45 * - typeOffsets:intvector (Required) |
| 46 * |
| 47 * Sets of UTC raw/dst offset pairs in seconds. Entries at |
| 48 * 2n represents raw offset and 2n+1 represents dst offset |
| 49 * paired with the raw offset at 2n. The very first pair represents |
| 50 * the initial zone offset (before the first transition) always. |
| 51 * |
| 52 * - trans:intvector (Optional) |
| 53 * |
| 54 * List of transition times represented by 32bit seconds from the |
| 55 * epoch (1970-01-01T00:00Z) in ascending order. |
| 56 * |
| 57 * - transPre32/transPost32:intvector (Optional) |
| 58 * |
| 59 * List of transition times before/after 32bit minimum seconds. |
| 60 * Each time is represented by a pair of 32bit integer. |
| 61 * |
| 62 * - typeMap:bin (Optional) |
| 63 * |
| 64 * Array of bytes representing the mapping between each transition |
| 65 * time (transPre32/trans/transPost32) and its corresponding offset |
| 66 * data (typeOffsets). |
| 67 * |
| 68 * - finalRule:string (Optional) |
| 69 * |
| 70 * If a recurrent transition rule is applicable to a zone forever |
| 71 * after the final transition time, finalRule represents the rule |
| 72 * in Rules data. |
| 73 * |
| 74 * - finalRaw:int (Optional) |
| 75 * |
| 76 * When finalRule is available, finalRaw is required and specifies |
| 77 * the raw (base) offset of the rule. |
| 78 * |
| 79 * - finalYear:int (Optional) |
| 80 * |
| 81 * When finalRule is available, finalYear is required and specifies |
| 82 * the start year of the rule. |
| 83 * |
| 84 * - links:intvector (Optional) |
| 85 * |
| 86 * When this zone data is shared with other zones, links specifies |
| 87 * all zones including the zone itself. Each zone is referenced by |
| 88 * integer index. |
| 89 * |
| 90 * b. Link (int, length 1). A link zone is an int resource. The |
| 91 * integer is the zone number of the target zone. The key of this |
| 92 * resource is an alternate name for the target zone. This data |
| 93 * is corresponding to Link data in the tz database. |
| 94 * |
| 95 * |
| 96 * 2. Rules. These have keys corresponding to the Olson rule IDs, |
| 97 * with an underscore prepended, e.g., "_EU". Each resource describes |
| 98 * the behavior of the given rule using an intvector, containing the |
| 99 * onset list, the cessation list, and the DST savings. The onset and |
| 100 * cessation lists consist of the month, dowim, dow, time, and time |
| 101 * mode. The end result is that the 11 integers describing the rule |
| 102 * can be passed directly into the SimpleTimeZone 13-argument |
| 103 * constructor (the other two arguments will be the raw offset, taken |
| 104 * from the complex zone element 5, and the ID string, which is not |
| 105 * used), with the times and the DST savings multiplied by 1000 to |
| 106 * scale from seconds to milliseconds. |
| 107 * |
| 108 * 3. Regions. An array specifies mapping between zones and regions. |
| 109 * Each item is either a 2-letter ISO country code or "001" |
| 110 * (UN M.49 - World). This data is generated from "zone.tab" |
| 111 * in the tz database. |
| 112 */ |
| 113 class U_I18N_API OlsonTimeZone: public BasicTimeZone { |
| 114 public: |
| 115 /** |
| 116 * Construct from a resource bundle. |
| 117 * @param top the top-level zoneinfo resource bundle. This is used |
| 118 * to lookup the rule that `res' may refer to, if there is one. |
| 119 * @param res the resource bundle of the zone to be constructed |
| 120 * @param ec input-output error code |
| 121 */ |
| 122 OlsonTimeZone(const UResourceBundle* top, |
| 123 const UResourceBundle* res, UErrorCode& ec); |
| 124 |
| 125 /** |
| 126 * Copy constructor |
| 127 */ |
| 128 OlsonTimeZone(const OlsonTimeZone& other); |
| 129 |
| 130 /** |
| 131 * Destructor |
| 132 */ |
| 133 virtual ~OlsonTimeZone(); |
| 134 |
| 135 /** |
| 136 * Assignment operator |
| 137 */ |
| 138 OlsonTimeZone& operator=(const OlsonTimeZone& other); |
| 139 |
| 140 /** |
| 141 * Returns true if the two TimeZone objects are equal. |
| 142 */ |
| 143 virtual UBool operator==(const TimeZone& other) const; |
| 144 |
| 145 /** |
| 146 * TimeZone API. |
| 147 */ |
| 148 virtual TimeZone* clone() const; |
| 149 |
| 150 /** |
| 151 * TimeZone API. |
| 152 */ |
| 153 static UClassID U_EXPORT2 getStaticClassID(); |
| 154 |
| 155 /** |
| 156 * TimeZone API. |
| 157 */ |
| 158 virtual UClassID getDynamicClassID() const; |
| 159 |
| 160 /** |
| 161 * TimeZone API. Do not call this; prefer getOffset(UDate,...). |
| 162 */ |
| 163 virtual int32_t getOffset(uint8_t era, int32_t year, int32_t month, |
| 164 int32_t day, uint8_t dayOfWeek, |
| 165 int32_t millis, UErrorCode& ec) const; |
| 166 |
| 167 /** |
| 168 * TimeZone API. Do not call this; prefer getOffset(UDate,...). |
| 169 */ |
| 170 virtual int32_t getOffset(uint8_t era, int32_t year, int32_t month, |
| 171 int32_t day, uint8_t dayOfWeek, |
| 172 int32_t millis, int32_t monthLength, |
| 173 UErrorCode& ec) const; |
| 174 |
| 175 /** |
| 176 * TimeZone API. |
| 177 */ |
| 178 virtual void getOffset(UDate date, UBool local, int32_t& rawOffset, |
| 179 int32_t& dstOffset, UErrorCode& ec) const; |
| 180 |
| 181 /** |
| 182 * BasicTimeZone API. |
| 183 */ |
| 184 virtual void getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int3
2_t duplicatedTimeOpt, |
| 185 int32_t& rawoff, int32_t& dstoff, UErrorCode& ec) /*const*/; |
| 186 |
| 187 /** |
| 188 * TimeZone API. This method has no effect since objects of this |
| 189 * class are quasi-immutable (the base class allows the ID to be |
| 190 * changed). |
| 191 */ |
| 192 virtual void setRawOffset(int32_t offsetMillis); |
| 193 |
| 194 /** |
| 195 * TimeZone API. For a historical zone, the raw offset can change |
| 196 * over time, so this API is not useful. In order to approximate |
| 197 * expected behavior, this method returns the raw offset for the |
| 198 * current moment in time. |
| 199 */ |
| 200 virtual int32_t getRawOffset() const; |
| 201 |
| 202 /** |
| 203 * TimeZone API. For a historical zone, whether DST is used or |
| 204 * not varies over time. In order to approximate expected |
| 205 * behavior, this method returns TRUE if DST is observed at any |
| 206 * point in the current year. |
| 207 */ |
| 208 virtual UBool useDaylightTime() const; |
| 209 |
| 210 /** |
| 211 * TimeZone API. |
| 212 */ |
| 213 virtual UBool inDaylightTime(UDate date, UErrorCode& ec) const; |
| 214 |
| 215 /** |
| 216 * TimeZone API. |
| 217 */ |
| 218 virtual int32_t getDSTSavings() const; |
| 219 |
| 220 /** |
| 221 * TimeZone API. Also comare historic transitions. |
| 222 */ |
| 223 virtual UBool hasSameRules(const TimeZone& other) const; |
| 224 |
| 225 /** |
| 226 * BasicTimeZone API. |
| 227 * Gets the first time zone transition after the base time. |
| 228 * @param base The base time. |
| 229 * @param inclusive Whether the base time is inclusive or not. |
| 230 * @param result Receives the first transition after the base time. |
| 231 * @return TRUE if the transition is found. |
| 232 */ |
| 233 virtual UBool getNextTransition(UDate base, UBool inclusive, TimeZoneTransit
ion& result) /*const*/; |
| 234 |
| 235 /** |
| 236 * BasicTimeZone API. |
| 237 * Gets the most recent time zone transition before the base time. |
| 238 * @param base The base time. |
| 239 * @param inclusive Whether the base time is inclusive or not. |
| 240 * @param result Receives the most recent transition before the base time
. |
| 241 * @return TRUE if the transition is found. |
| 242 */ |
| 243 virtual UBool getPreviousTransition(UDate base, UBool inclusive, TimeZoneTra
nsition& result) /*const*/; |
| 244 |
| 245 /** |
| 246 * BasicTimeZone API. |
| 247 * Returns the number of <code>TimeZoneRule</code>s which represents time tr
ansitions, |
| 248 * for this time zone, that is, all <code>TimeZoneRule</code>s for this time
zone except |
| 249 * <code>InitialTimeZoneRule</code>. The return value range is 0 or any pos
itive value. |
| 250 * @param status Receives error status code. |
| 251 * @return The number of <code>TimeZoneRule</code>s representing time transi
tions. |
| 252 */ |
| 253 virtual int32_t countTransitionRules(UErrorCode& status) /*const*/; |
| 254 |
| 255 /** |
| 256 * Gets the <code>InitialTimeZoneRule</code> and the set of <code>TimeZoneRu
le</code> |
| 257 * which represent time transitions for this time zone. On successful retur
n, |
| 258 * the argument initial points to non-NULL <code>InitialTimeZoneRule</code>
and |
| 259 * the array trsrules is filled with 0 or multiple <code>TimeZoneRule</code> |
| 260 * instances up to the size specified by trscount. The results are referenc
ing the |
| 261 * rule instance held by this time zone instance. Therefore, after this tim
e zone |
| 262 * is destructed, they are no longer available. |
| 263 * @param initial Receives the initial timezone rule |
| 264 * @param trsrules Receives the timezone transition rules |
| 265 * @param trscount On input, specify the size of the array 'transitions
' receiving |
| 266 * the timezone transition rules. On output, actual nu
mber of |
| 267 * rules filled in the array will be set. |
| 268 * @param status Receives error status code. |
| 269 * @draft ICU 3.8 |
| 270 */ |
| 271 virtual void getTimeZoneRules(const InitialTimeZoneRule*& initial, |
| 272 const TimeZoneRule* trsrules[], int32_t& trscount, UErrorCode& status) /
*const*/; |
| 273 |
| 274 private: |
| 275 /** |
| 276 * Default constructor. Creates a time zone with an empty ID and |
| 277 * a fixed GMT offset of zero. |
| 278 */ |
| 279 OlsonTimeZone(); |
| 280 |
| 281 private: |
| 282 |
| 283 void constructEmpty(); |
| 284 |
| 285 void getHistoricalOffset(UDate date, UBool local, |
| 286 int32_t NonExistingTimeOpt, int32_t DuplicatedTimeOpt, |
| 287 int32_t& rawoff, int32_t& dstoff) const; |
| 288 |
| 289 int16_t transitionCount() const; |
| 290 |
| 291 int64_t transitionTimeInSeconds(int16_t transIdx) const; |
| 292 double transitionTime(int16_t transIdx) const; |
| 293 |
| 294 /* |
| 295 * Following 3 methods return an offset at the given transition time index. |
| 296 * When the index is negative, return the initial offset. |
| 297 */ |
| 298 int32_t zoneOffsetAt(int16_t transIdx) const; |
| 299 int32_t rawOffsetAt(int16_t transIdx) const; |
| 300 int32_t dstOffsetAt(int16_t transIdx) const; |
| 301 |
| 302 /* |
| 303 * Following methods return the initial offset. |
| 304 */ |
| 305 int32_t initialRawOffset() const; |
| 306 int32_t initialDstOffset() const; |
| 307 |
| 308 /** |
| 309 * Number of transitions in each time range |
| 310 */ |
| 311 int16_t transitionCountPre32; |
| 312 int16_t transitionCount32; |
| 313 int16_t transitionCountPost32; |
| 314 |
| 315 /** |
| 316 * Time of each transition in seconds from 1970 epoch before 32bit second ra
nge (<= 1900). |
| 317 * Each transition in this range is represented by a pair of int32_t. |
| 318 * Length is transitionCount int32_t's. NULL if no transitions in this rang
e. |
| 319 */ |
| 320 const int32_t *transitionTimesPre32; // alias into res; do not delete |
| 321 |
| 322 /** |
| 323 * Time of each transition in seconds from 1970 epoch in 32bit second range. |
| 324 * Length is transitionCount int32_t's. NULL if no transitions in this rang
e. |
| 325 */ |
| 326 const int32_t *transitionTimes32; // alias into res; do not delete |
| 327 |
| 328 /** |
| 329 * Time of each transition in seconds from 1970 epoch after 32bit second ran
ge (>= 2038). |
| 330 * Each transition in this range is represented by a pair of int32_t. |
| 331 * Length is transitionCount int32_t's. NULL if no transitions in this rang
e. |
| 332 */ |
| 333 const int32_t *transitionTimesPost32; // alias into res; do not delete |
| 334 |
| 335 /** |
| 336 * Number of types, 1..255 |
| 337 */ |
| 338 int16_t typeCount; |
| 339 |
| 340 /** |
| 341 * Offset from GMT in seconds for each type. |
| 342 * Length is typeCount int32_t's. At least one type (a pair of int32_t) |
| 343 * is required. |
| 344 */ |
| 345 const int32_t *typeOffsets; // alias into res; do not delete |
| 346 |
| 347 /** |
| 348 * Type description data, consisting of transitionCount uint8_t |
| 349 * type indices (from 0..typeCount-1). |
| 350 * Length is transitionCount int16_t's. NULL if no transitions. |
| 351 */ |
| 352 const uint8_t *typeMapData; // alias into res; do not delete |
| 353 |
| 354 /** |
| 355 * A SimpleTimeZone that governs the behavior for date >= finalMillis. |
| 356 */ |
| 357 SimpleTimeZone *finalZone; // owned, may be NULL |
| 358 |
| 359 /** |
| 360 * For date >= finalMillis, the finalZone will be used. |
| 361 */ |
| 362 double finalStartMillis; |
| 363 |
| 364 /** |
| 365 * For year >= finalYear, the finalZone will be used. |
| 366 */ |
| 367 int32_t finalStartYear; |
| 368 |
| 369 /* BasicTimeZone support */ |
| 370 void clearTransitionRules(void); |
| 371 void deleteTransitionRules(void); |
| 372 void initTransitionRules(UErrorCode& status); |
| 373 |
| 374 InitialTimeZoneRule *initialRule; |
| 375 TimeZoneTransition *firstTZTransition; |
| 376 int16_t firstTZTransitionIdx; |
| 377 TimeZoneTransition *firstFinalTZTransition; |
| 378 TimeArrayTimeZoneRule **historicRules; |
| 379 int16_t historicRuleCount; |
| 380 SimpleTimeZone *finalZoneWithStartYear; // hack |
| 381 UBool transitionRulesInitialized; |
| 382 }; |
| 383 |
| 384 inline int16_t |
| 385 OlsonTimeZone::transitionCount() const { |
| 386 return transitionCountPre32 + transitionCount32 + transitionCountPost32; |
| 387 } |
| 388 |
| 389 inline double |
| 390 OlsonTimeZone::transitionTime(int16_t transIdx) const { |
| 391 return (double)transitionTimeInSeconds(transIdx) * U_MILLIS_PER_SECOND; |
| 392 } |
| 393 |
| 394 inline int32_t |
| 395 OlsonTimeZone::zoneOffsetAt(int16_t transIdx) const { |
| 396 int16_t typeIdx = (transIdx >= 0 ? typeMapData[transIdx] : 0) << 1; |
| 397 return typeOffsets[typeIdx] + typeOffsets[typeIdx + 1]; |
| 398 } |
| 399 |
| 400 inline int32_t |
| 401 OlsonTimeZone::rawOffsetAt(int16_t transIdx) const { |
| 402 int16_t typeIdx = (transIdx >= 0 ? typeMapData[transIdx] : 0) << 1; |
| 403 return typeOffsets[typeIdx]; |
| 404 } |
| 405 |
| 406 inline int32_t |
| 407 OlsonTimeZone::dstOffsetAt(int16_t transIdx) const { |
| 408 int16_t typeIdx = (transIdx >= 0 ? typeMapData[transIdx] : 0) << 1; |
| 409 return typeOffsets[typeIdx + 1]; |
| 410 } |
| 411 |
| 412 inline int32_t |
| 413 OlsonTimeZone::initialRawOffset() const { |
| 414 return typeOffsets[0]; |
| 415 } |
| 416 |
| 417 inline int32_t |
| 418 OlsonTimeZone::initialDstOffset() const { |
| 419 return typeOffsets[1]; |
| 420 } |
| 421 |
| 422 U_NAMESPACE_END |
| 423 |
| 424 #endif // !UCONFIG_NO_FORMATTING |
| 425 #endif // OLSONTZ_H |
| 426 |
| 427 //eof |
OLD | NEW |