1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru********************************************************************** 38393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius* Copyright (c) 2003-2013, International Business Machines 4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Corporation and others. All Rights Reserved. 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru********************************************************************** 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Author: Alan Liu 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Created: July 21 2003 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru* Since: ICU 2.8 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru********************************************************************** 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru*/ 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "utypeinfo.h" // for 'typeid' to work 1327f654740f2a26ad62a5c155af9199af9e69b889claireho 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "olsontz.h" 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ures.h" 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/simpletz.h" 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/gregocal.h" 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "gregoimp.h" 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uassert.h" 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uvector.h" 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <float.h> // DBL_MAX 2650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "uresimp.h" // struct UResourceBundle 27b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "zonemeta.h" 288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include "umutex.h" 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef U_DEBUG_TZ 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# include <stdio.h> 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# include "uresimp.h" // for debugging 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void debug_tz_loc(const char *f, int32_t l) 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fprintf(stderr, "%s:%d: ", f, l); 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 38b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic void debug_tz_msg(const char *pat, ...) 40b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 41b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru va_list ap; 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru va_start(ap, pat); 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru vfprintf(stderr, pat, ap); 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fflush(stderr); 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// must use double parens, i.e.: U_DEBUG_TZ_MSG(("four is: %d",4)); 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define U_DEBUG_TZ_MSG(x) {debug_tz_loc(__FILE__,__LINE__);debug_tz_msg x;} 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define U_DEBUG_TZ_MSG(x) 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 5250294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehostatic UBool arrayEqual(const void *a1, const void *a2, int32_t size) { 5350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (a1 == NULL && a2 == NULL) { 5450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return TRUE; 5550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 5627f654740f2a26ad62a5c155af9199af9e69b889claireho if ((a1 != NULL && a2 == NULL) || (a1 == NULL && a2 != NULL)) { 5750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 5850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 5950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (a1 == a2) { 6050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return TRUE; 6150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 6250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 6350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return (uprv_memcmp(a1, a2, size) == 0); 6450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 6550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_BEGIN 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 6850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define kTRANS "trans" 6950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define kTRANSPRE32 "transPre32" 7050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define kTRANSPOST32 "transPost32" 7150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define kTYPEOFFSETS "typeOffsets" 7250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define kTYPEMAP "typeMap" 7350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define kLINKS "links" 7450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define kFINALRULE "finalRule" 7550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define kFINALRAW "finalRaw" 7650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#define kFINALYEAR "finalYear" 7750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define SECONDS_PER_DAY (24*60*60) 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const int32_t ZEROS[] = {0,0}; 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUOBJECT_DEFINE_RTTI_IMPLEMENTATION(OlsonTimeZone) 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Default constructor. Creates a time zone with an empty ID and 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * a fixed GMT offset of zero. 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/*OlsonTimeZone::OlsonTimeZone() : finalYear(INT32_MAX), finalMillis(DBL_MAX), finalZone(0), transitionRulesInitialized(FALSE) { 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru clearTransitionRules(); 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru constructEmpty(); 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}*/ 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Construct a GMT+0 zone with no transitions. This is done when a 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * constructor fails so the resultant object is well-behaved. 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid OlsonTimeZone::constructEmpty() { 98b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho canonicalID = NULL; 99b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 10050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionCountPre32 = transitionCount32 = transitionCountPost32 = 0; 10150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionTimesPre32 = transitionTimes32 = transitionTimesPost32 = NULL; 10250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 10350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho typeMapData = NULL; 10450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru typeCount = 1; 10650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho typeOffsets = ZEROS; 10750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 10850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho finalZone = NULL; 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Construct from a resource bundle 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param top the top-level zoneinfo resource bundle. This is used 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * to lookup the rule that `res' may refer to, if there is one. 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param res the resource bundle of the zone to be constructed 116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * @param ec input-output error code 117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruOlsonTimeZone::OlsonTimeZone(const UResourceBundle* top, 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UResourceBundle* res, 120b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const UnicodeString& tzid, 121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode& ec) : 12259d709d503bab6e2b61931737e662dd293b40578ccornelius BasicTimeZone(tzid), finalZone(NULL) 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru clearTransitionRules(); 125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_DEBUG_TZ_MSG(("OlsonTimeZone(%s)\n", ures_getKey((UResourceBundle*)res))); 126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((top == NULL || res == NULL) && U_SUCCESS(ec)) { 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ec = U_ILLEGAL_ARGUMENT_ERROR; 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(ec)) { 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // TODO -- clean up -- Doesn't work if res points to an alias 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // // TODO remove nonconst casts below when ures_* API is fixed 132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // setID(ures_getKey((UResourceBundle*) res)); // cast away const 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 13450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t len; 13550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UResourceBundle r; 13650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_initStackObject(&r); 13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 13850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Pre-32bit second transitions 13950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_getByKey(res, kTRANSPRE32, &r, &ec); 14050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionTimesPre32 = ures_getIntVector(&r, &len, &ec); 14150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionCountPre32 = len >> 1; 14250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (ec == U_MISSING_RESOURCE_ERROR) { 14350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // No pre-32bit transitions 14450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionTimesPre32 = NULL; 14550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionCountPre32 = 0; 14650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ec = U_ZERO_ERROR; 14750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (U_SUCCESS(ec) && (len < 0 || len > 0x7FFF || (len & 1) != 0) /* len must be even */) { 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ec = U_INVALID_FORMAT_ERROR; 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 15150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // 32bit second transitions 15250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_getByKey(res, kTRANS, &r, &ec); 15350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionTimes32 = ures_getIntVector(&r, &len, &ec); 15450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionCount32 = len; 15550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (ec == U_MISSING_RESOURCE_ERROR) { 15650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // No 32bit transitions 15750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionTimes32 = NULL; 15850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionCount32 = 0; 15950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ec = U_ZERO_ERROR; 16050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (U_SUCCESS(ec) && (len < 0 || len > 0x7FFF)) { 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ec = U_INVALID_FORMAT_ERROR; 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 16350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 16450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Post-32bit second transitions 16550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_getByKey(res, kTRANSPOST32, &r, &ec); 16650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionTimesPost32 = ures_getIntVector(&r, &len, &ec); 16750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionCountPost32 = len >> 1; 16850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (ec == U_MISSING_RESOURCE_ERROR) { 16950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // No pre-32bit transitions 17050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionTimesPost32 = NULL; 17150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionCountPost32 = 0; 17250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ec = U_ZERO_ERROR; 17350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (U_SUCCESS(ec) && (len < 0 || len > 0x7FFF || (len & 1) != 0) /* len must be even */) { 174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ec = U_INVALID_FORMAT_ERROR; 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 17750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Type offsets list must be of even size, with size >= 2 17850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_getByKey(res, kTYPEOFFSETS, &r, &ec); 17950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho typeOffsets = ures_getIntVector(&r, &len, &ec); 18050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_SUCCESS(ec) && (len < 2 || len > 0x7FFE || (len & 1) != 0)) { 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ec = U_INVALID_FORMAT_ERROR; 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 18350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho typeCount = (int16_t) len >> 1; 18450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 18550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Type map data must be of the same size as the transition count 18650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho typeMapData = NULL; 18750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (transitionCount() > 0) { 18850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_getByKey(res, kTYPEMAP, &r, &ec); 18950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho typeMapData = ures_getBinary(&r, &len, &ec); 19050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (ec == U_MISSING_RESOURCE_ERROR) { 19150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // no type mapping data 19250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ec = U_INVALID_FORMAT_ERROR; 19350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (U_SUCCESS(ec) && len != transitionCount()) { 19450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ec = U_INVALID_FORMAT_ERROR; 19550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Process final rule and data, if any 19950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const UChar *ruleIdUStr = ures_getStringByKey(res, kFINALRULE, &len, &ec); 20050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_getByKey(res, kFINALRAW, &r, &ec); 20150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t ruleRaw = ures_getInt(&r, &ec); 20250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_getByKey(res, kFINALYEAR, &r, &ec); 20350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t ruleYear = ures_getInt(&r, &ec); 20450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_SUCCESS(ec)) { 20550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UnicodeString ruleID(TRUE, ruleIdUStr, len); 20650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UResourceBundle *rule = TimeZone::loadRule(top, ruleID, NULL, ec); 20750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho const int32_t *ruleData = ures_getIntVector(rule, &len, &ec); 20850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (U_SUCCESS(ec) && len == 11) { 20950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UnicodeString emptyStr; 21050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho finalZone = new SimpleTimeZone( 21150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ruleRaw * U_MILLIS_PER_SECOND, 21250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho emptyStr, 21350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (int8_t)ruleData[0], (int8_t)ruleData[1], (int8_t)ruleData[2], 21450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ruleData[3] * U_MILLIS_PER_SECOND, 21550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (SimpleTimeZone::TimeMode) ruleData[4], 21650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (int8_t)ruleData[5], (int8_t)ruleData[6], (int8_t)ruleData[7], 21750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ruleData[8] * U_MILLIS_PER_SECOND, 21850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho (SimpleTimeZone::TimeMode) ruleData[9], 21950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ruleData[10] * U_MILLIS_PER_SECOND, ec); 22050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (finalZone == NULL) { 22150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ec = U_MEMORY_ALLOCATION_ERROR; 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 22350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho finalStartYear = ruleYear; 22450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 22550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Note: Setting finalStartYear to the finalZone is problematic. When a date is around 22650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // year boundary, SimpleTimeZone may return false result when DST is observed at the 22750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // beginning of year. We could apply safe margin (day or two), but when one of recurrent 22850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // rules falls around year boundary, it could return false result. Without setting the 22950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // start year, finalZone works fine around the year boundary of the start year. 23050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 23150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // finalZone->setStartYear(finalStartYear); 23250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 23350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 23450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Compute the millis for Jan 1, 0:00 GMT of the finalYear 23550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 23650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Note: finalStartMillis is used for detecting either if 23750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // historic transition data or finalZone to be used. In an 23850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // extreme edge case - for example, two transitions fall into 23950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // small windows of time around the year boundary, this may 24050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // result incorrect offset computation. But I think it will 24150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // never happen practically. Yoshito - Feb 20, 2010 24250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho finalStartMillis = Grego::fieldsToDay(finalStartYear, 0, 1) * U_MILLIS_PER_DAY; 243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 24450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 24550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ec = U_INVALID_FORMAT_ERROR; 246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 24750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_close(rule); 24850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (ec == U_MISSING_RESOURCE_ERROR) { 24950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // No final zone 25050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ec = U_ZERO_ERROR; 251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 25250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho ures_close(&r); 253b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 254b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho // initialize canonical ID 255b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho canonicalID = ZoneMeta::getCanonicalCLDRID(tzid, ec); 256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(ec)) { 259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru constructEmpty(); 260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Copy constructor 265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruOlsonTimeZone::OlsonTimeZone(const OlsonTimeZone& other) : 267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru BasicTimeZone(other), finalZone(0) { 268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *this = other; 269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Assignment operator 273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruOlsonTimeZone& OlsonTimeZone::operator=(const OlsonTimeZone& other) { 275b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho canonicalID = other.canonicalID; 276b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 27750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionTimesPre32 = other.transitionTimesPre32; 27850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionTimes32 = other.transitionTimes32; 27950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionTimesPost32 = other.transitionTimesPost32; 28050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 28150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionCountPre32 = other.transitionCountPre32; 28250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionCount32 = other.transitionCount32; 28350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transitionCountPost32 = other.transitionCountPost32; 28450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru typeCount = other.typeCount; 286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru typeOffsets = other.typeOffsets; 28750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho typeMapData = other.typeMapData; 28850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete finalZone; 290b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru finalZone = (other.finalZone != 0) ? 291b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (SimpleTimeZone*) other.finalZone->clone() : 0; 29250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 29350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho finalStartYear = other.finalStartYear; 29450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho finalStartMillis = other.finalStartMillis; 29550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 296b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru clearTransitionRules(); 29750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return *this; 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Destructor 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruOlsonTimeZone::~OlsonTimeZone() { 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru deleteTransitionRules(); 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete finalZone; 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 310b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Returns true if the two TimeZone objects are equal. 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 312b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool OlsonTimeZone::operator==(const TimeZone& other) const { 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return ((this == &other) || 31427f654740f2a26ad62a5c155af9199af9e69b889claireho (typeid(*this) == typeid(other) && 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TimeZone::operator==(other) && 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru hasSameRules(other))); 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * TimeZone API. 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruTimeZone* OlsonTimeZone::clone() const { 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return new OlsonTimeZone(*this); 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * TimeZone API. 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t OlsonTimeZone::getOffset(uint8_t era, int32_t year, int32_t month, 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dom, uint8_t dow, 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t millis, UErrorCode& ec) const { 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (month < UCAL_JANUARY || month > UCAL_DECEMBER) { 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_SUCCESS(ec)) { 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ec = U_ILLEGAL_ARGUMENT_ERROR; 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getOffset(era, year, month, dom, dow, millis, 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Grego::monthLength(year, month), 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ec); 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * TimeZone API. 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t OlsonTimeZone::getOffset(uint8_t era, int32_t year, int32_t month, 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t dom, uint8_t dow, 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t millis, int32_t monthLength, 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode& ec) const { 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(ec)) { 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((era != GregorianCalendar::AD && era != GregorianCalendar::BC) 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru || month < UCAL_JANUARY 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru || month > UCAL_DECEMBER 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru || dom < 1 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru || dom > monthLength 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru || dow < UCAL_SUNDAY 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru || dow > UCAL_SATURDAY 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru || millis < 0 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru || millis >= U_MILLIS_PER_DAY 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru || monthLength < 28 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru || monthLength > 31) { 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ec = U_ILLEGAL_ARGUMENT_ERROR; 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (era == GregorianCalendar::BC) { 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru year = -year; 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 37450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (finalZone != NULL && year >= finalStartYear) { 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return finalZone->getOffset(era, year, month, dom, dow, 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru millis, monthLength, ec); 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Compute local epoch millis from input fields 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UDate date = (UDate)(Grego::fieldsToDay(year, month, dom) * U_MILLIS_PER_DAY + millis); 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t rawoff, dstoff; 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getHistoricalOffset(date, TRUE, kDaylight, kStandard, rawoff, dstoff); 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return rawoff + dstoff; 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * TimeZone API. 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid OlsonTimeZone::getOffset(UDate date, UBool local, int32_t& rawoff, 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t& dstoff, UErrorCode& ec) const { 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(ec)) { 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 39450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (finalZone != NULL && date >= finalStartMillis) { 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru finalZone->getOffset(date, local, rawoff, dstoff, ec); 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getHistoricalOffset(date, local, kFormer, kLatter, rawoff, dstoff); 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruOlsonTimeZone::getOffsetFromLocal(UDate date, int32_t nonExistingTimeOpt, int32_t duplicatedTimeOpt, 4038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t& rawoff, int32_t& dstoff, UErrorCode& ec) const { 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(ec)) { 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 40750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (finalZone != NULL && date >= finalStartMillis) { 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru finalZone->getOffsetFromLocal(date, nonExistingTimeOpt, duplicatedTimeOpt, rawoff, dstoff, ec); 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getHistoricalOffset(date, TRUE, nonExistingTimeOpt, duplicatedTimeOpt, rawoff, dstoff); 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * TimeZone API. 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid OlsonTimeZone::setRawOffset(int32_t /*offsetMillis*/) { 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We don't support this operation, since OlsonTimeZones are 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // immutable (except for the ID, which is in the base class). 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Nothing to do! 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * TimeZone API. 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t OlsonTimeZone::getRawOffset() const { 429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode ec = U_ZERO_ERROR; 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t raw, dst; 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getOffset((double) uprv_getUTCtime() * U_MILLIS_PER_SECOND, 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FALSE, raw, dst, ec); 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return raw; 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined U_DEBUG_TZ 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid printTime(double ms) { 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t year, month, dom, dow; 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double millis=0; 440b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru double days = ClockMath::floorDivide(((double)ms), (double)U_MILLIS_PER_DAY, millis); 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Grego::dayToFields(days, year, month, dom, dow); 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_DEBUG_TZ_MSG((" getHistoricalOffset: time %.1f (%04d.%02d.%02d+%.1fh)\n", ms, 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru year, month+1, dom, (millis/kOneHour))); 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 44850294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoint64_t 44950294ead5e5d23f5bbfed76e00e6b510bd41eee1clairehoOlsonTimeZone::transitionTimeInSeconds(int16_t transIdx) const { 45050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho U_ASSERT(transIdx >= 0 && transIdx < transitionCount()); 45150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 45250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (transIdx < transitionCountPre32) { 45350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return (((int64_t)((uint32_t)transitionTimesPre32[transIdx << 1])) << 32) 45450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho | ((int64_t)((uint32_t)transitionTimesPre32[(transIdx << 1) + 1])); 45550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 45650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 45750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transIdx -= transitionCountPre32; 45850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (transIdx < transitionCount32) { 45950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return (int64_t)transitionTimes32[transIdx]; 46050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 46150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 46250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transIdx -= transitionCount32; 46350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return (((int64_t)((uint32_t)transitionTimesPost32[transIdx << 1])) << 32) 46450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho | ((int64_t)((uint32_t)transitionTimesPost32[(transIdx << 1) + 1])); 46550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho} 46650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 46759d709d503bab6e2b61931737e662dd293b40578ccornelius// Maximum absolute offset in seconds (86400 seconds = 1 day) 46859d709d503bab6e2b61931737e662dd293b40578ccornelius// getHistoricalOffset uses this constant as safety margin of 46959d709d503bab6e2b61931737e662dd293b40578ccornelius// quick zone transition checking. 47059d709d503bab6e2b61931737e662dd293b40578ccornelius#define MAX_OFFSET_SECONDS 86400 47159d709d503bab6e2b61931737e662dd293b40578ccornelius 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruOlsonTimeZone::getHistoricalOffset(UDate date, UBool local, 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t NonExistingTimeOpt, int32_t DuplicatedTimeOpt, 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t& rawoff, int32_t& dstoff) const { 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_DEBUG_TZ_MSG(("getHistoricalOffset(%.1f, %s, %d, %d, raw, dst)\n", 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru date, local?"T":"F", NonExistingTimeOpt, DuplicatedTimeOpt)); 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined U_DEBUG_TZ 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru printTime(date*1000.0); 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 48150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int16_t transCount = transitionCount(); 48250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 48350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (transCount > 0) { 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double sec = uprv_floor(date / U_MILLIS_PER_SECOND); 48550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (!local && sec < transitionTimeInSeconds(0)) { 48650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Before the first transition time 48750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho rawoff = initialRawOffset() * U_MILLIS_PER_SECOND; 48850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho dstoff = initialDstOffset() * U_MILLIS_PER_SECOND; 48950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 49050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Linear search from the end is the fastest approach, since 49150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // most lookups will happen at/near the end. 49250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int16_t transIdx; 49350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (transIdx = transCount - 1; transIdx >= 0; transIdx--) { 49450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int64_t transition = transitionTimeInSeconds(transIdx); 49550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 49659d709d503bab6e2b61931737e662dd293b40578ccornelius if (local && (sec >= (transition - MAX_OFFSET_SECONDS))) { 49750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t offsetBefore = zoneOffsetAt(transIdx - 1); 49850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool dstBefore = dstOffsetAt(transIdx - 1) != 0; 49950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 50050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t offsetAfter = zoneOffsetAt(transIdx); 50150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool dstAfter = dstOffsetAt(transIdx) != 0; 50250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 50350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool dstToStd = dstBefore && !dstAfter; 50450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UBool stdToDst = !dstBefore && dstAfter; 50550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 50650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (offsetAfter - offsetBefore >= 0) { 50750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Positive transition, which makes a non-existing local time range 50850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (((NonExistingTimeOpt & kStdDstMask) == kStandard && dstToStd) 50950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho || ((NonExistingTimeOpt & kStdDstMask) == kDaylight && stdToDst)) { 51050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transition += offsetBefore; 51150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (((NonExistingTimeOpt & kStdDstMask) == kStandard && stdToDst) 51250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho || ((NonExistingTimeOpt & kStdDstMask) == kDaylight && dstToStd)) { 51350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transition += offsetAfter; 51450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if ((NonExistingTimeOpt & kFormerLatterMask) == kLatter) { 51550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transition += offsetBefore; 51650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 51750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Interprets the time with rule before the transition, 51850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // default for non-existing time range 51950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transition += offsetAfter; 52050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 52250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Negative transition, which makes a duplicated local time range 52350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (((DuplicatedTimeOpt & kStdDstMask) == kStandard && dstToStd) 52450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho || ((DuplicatedTimeOpt & kStdDstMask) == kDaylight && stdToDst)) { 52550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transition += offsetAfter; 52650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if (((DuplicatedTimeOpt & kStdDstMask) == kStandard && stdToDst) 52750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho || ((DuplicatedTimeOpt & kStdDstMask) == kDaylight && dstToStd)) { 52850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transition += offsetBefore; 52950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else if ((DuplicatedTimeOpt & kFormerLatterMask) == kFormer) { 53050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transition += offsetBefore; 53150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } else { 53250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Interprets the time with rule after the transition, 53350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // default for duplicated local time range 53450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho transition += offsetAfter; 53550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 53850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (sec >= transition) { 53950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho break; 54050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 54250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // transIdx could be -1 when local=true 54350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho rawoff = rawOffsetAt(transIdx) * U_MILLIS_PER_SECOND; 54450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho dstoff = dstOffsetAt(transIdx) * U_MILLIS_PER_SECOND; 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // No transitions, single pair of offsets only 54850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho rawoff = initialRawOffset() * U_MILLIS_PER_SECOND; 54950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho dstoff = initialDstOffset() * U_MILLIS_PER_SECOND; 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru U_DEBUG_TZ_MSG(("getHistoricalOffset(%.1f, %s, %d, %d, raw, dst) - raw=%d, dst=%d\n", 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru date, local?"T":"F", NonExistingTimeOpt, DuplicatedTimeOpt, rawoff, dstoff)); 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * TimeZone API. 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool OlsonTimeZone::useDaylightTime() const { 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If DST was observed in 1942 (for example) but has never been 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // observed from 1943 to the present, most clients will expect 561b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // this method to return FALSE. This method determines whether 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // DST is in use in the current year (at any point in the year) 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // and returns TRUE if so. 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 56550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UDate current = uprv_getUTCtime(); 56650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (finalZone != NULL && current >= finalStartMillis) { 56750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return finalZone->useDaylightTime(); 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 57050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t year, month, dom, dow, doy, mid; 57150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho Grego::timeToFields(current, year, month, dom, dow, doy, mid); 57250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Find start of this year, and start of next year 57450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho double start = Grego::fieldsToDay(year, 0, 1) * SECONDS_PER_DAY; 57550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho double limit = Grego::fieldsToDay(year+1, 0, 1) * SECONDS_PER_DAY; 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Return TRUE if DST is observed at any time during the current 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // year. 57950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (int16_t i = 0; i < transitionCount(); ++i) { 5808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius double transition = (double)transitionTimeInSeconds(i); 58150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (transition >= limit) { 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 58450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if ((transition >= start && dstOffsetAt(i) != 0) 58550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho || (transition > start && dstOffsetAt(i - 1) != 0)) { 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 588b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 589b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruOlsonTimeZone::getDSTSavings() const{ 59350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (finalZone != NULL){ 594b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return finalZone->getDSTSavings(); 595b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TimeZone::getDSTSavings(); 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/** 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * TimeZone API. 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool OlsonTimeZone::inDaylightTime(UDate date, UErrorCode& ec) const { 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t raw, dst; 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getOffset(date, FALSE, raw, dst, ec); 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return dst != 0; 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 607b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruOlsonTimeZone::hasSameRules(const TimeZone &other) const { 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (this == &other) { 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 61227f654740f2a26ad62a5c155af9199af9e69b889claireho const OlsonTimeZone* z = dynamic_cast<const OlsonTimeZone*>(&other); 61327f654740f2a26ad62a5c155af9199af9e69b889claireho if (z == NULL) { 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 61750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // [sic] pointer comparison: typeMapData points into 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // memory-mapped or DLL space, so if two zones have the same 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // pointer, they are equal. 62050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (typeMapData == z->typeMapData) { 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 62450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // If the pointers are not equal, the zones may still 62550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // be equal if their rules and transitions are equal 62627f654740f2a26ad62a5c155af9199af9e69b889claireho if ((finalZone == NULL && z->finalZone != NULL) 62727f654740f2a26ad62a5c155af9199af9e69b889claireho || (finalZone != NULL && z->finalZone == NULL) 62827f654740f2a26ad62a5c155af9199af9e69b889claireho || (finalZone != NULL && z->finalZone != NULL && *finalZone != *z->finalZone)) { 62950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 63050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 63150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 63250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (finalZone != NULL) { 63350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (finalStartYear != z->finalStartYear || finalStartMillis != z->finalStartMillis) { 63450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 63550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 63650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 63750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (typeCount != z->typeCount 63850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho || transitionCountPre32 != z->transitionCountPre32 63950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho || transitionCount32 != z->transitionCount32 64050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho || transitionCountPost32 != z->transitionCountPost32) { 64150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return FALSE; 64250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 64350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 64550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho arrayEqual(transitionTimesPre32, z->transitionTimesPre32, sizeof(transitionTimesPre32[0]) * transitionCountPre32 << 1) 64650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho && arrayEqual(transitionTimes32, z->transitionTimes32, sizeof(transitionTimes32[0]) * transitionCount32) 64750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho && arrayEqual(transitionTimesPost32, z->transitionTimesPost32, sizeof(transitionTimesPost32[0]) * transitionCountPost32 << 1) 64850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho && arrayEqual(typeOffsets, z->typeOffsets, sizeof(typeOffsets[0]) * typeCount << 1) 64950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho && arrayEqual(typeMapData, z->typeMapData, sizeof(typeMapData[0]) * transitionCount()); 650b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruOlsonTimeZone::clearTransitionRules(void) { 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru initialRule = NULL; 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru firstTZTransition = NULL; 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru firstFinalTZTransition = NULL; 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru historicRules = NULL; 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru historicRuleCount = 0; 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru finalZoneWithStartYear = NULL; 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru firstTZTransitionIdx = 0; 66159d709d503bab6e2b61931737e662dd293b40578ccornelius transitionRulesInitOnce.reset(); 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruOlsonTimeZone::deleteTransitionRules(void) { 666b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (initialRule != NULL) { 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete initialRule; 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (firstTZTransition != NULL) { 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete firstTZTransition; 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (firstFinalTZTransition != NULL) { 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete firstFinalTZTransition; 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (finalZoneWithStartYear != NULL) { 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete finalZoneWithStartYear; 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (historicRules != NULL) { 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int i = 0; i < historicRuleCount; i++) { 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (historicRules[i] != NULL) { 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete historicRules[i]; 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(historicRules); 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru clearTransitionRules(); 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 688b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 6898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/* 6908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius * Lazy transition rules initializer 6918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius */ 6928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 69359d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void U_CALLCONV initRules(OlsonTimeZone *This, UErrorCode &status) { 69459d709d503bab6e2b61931737e662dd293b40578ccornelius This->initTransitionRules(status); 69559d709d503bab6e2b61931737e662dd293b40578ccornelius} 69659d709d503bab6e2b61931737e662dd293b40578ccornelius 6978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusvoid 6988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusOlsonTimeZone::checkTransitionRules(UErrorCode& status) const { 69959d709d503bab6e2b61931737e662dd293b40578ccornelius OlsonTimeZone *ncThis = const_cast<OlsonTimeZone *>(this); 70059d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_initOnce(ncThis->transitionRulesInitOnce, &initRules, ncThis, status); 7018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 7028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 703b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 704b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruOlsonTimeZone::initTransitionRules(UErrorCode& status) { 705b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) { 706b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 707b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 708b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru deleteTransitionRules(); 709b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString tzid; 710b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getID(tzid); 711b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 712b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString stdName = tzid + UNICODE_STRING_SIMPLE("(STD)"); 713b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString dstName = tzid + UNICODE_STRING_SIMPLE("(DST)"); 714b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 715b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t raw, dst; 716b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 71750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Create initial rule 71850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho raw = initialRawOffset() * U_MILLIS_PER_SECOND; 71950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho dst = initialDstOffset() * U_MILLIS_PER_SECOND; 72050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho initialRule = new InitialTimeZoneRule((dst == 0 ? stdName : dstName), raw, dst); 72150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Check to make sure initialRule was created 72250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (initialRule == NULL) { 72350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho status = U_MEMORY_ALLOCATION_ERROR; 72450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho deleteTransitionRules(); 72550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 72650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 727b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 72850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int32_t transCount = transitionCount(); 72950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (transCount > 0) { 73050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int16_t transitionIdx, typeIdx; 731b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 73250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // We probably no longer need to check the first "real" transition 73350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // here, because the new tzcode remove such transitions already. 73450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // For now, keeping this code for just in case. Feb 19, 2010 Yoshito 735b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru firstTZTransitionIdx = 0; 73650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (transitionIdx = 0; transitionIdx < transCount; transitionIdx++) { 73750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (typeMapData[transitionIdx] != 0) { // type 0 is the initial type 738b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 739b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 74050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho firstTZTransitionIdx++; 741b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 74250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (transitionIdx == transCount) { 743b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Actually no transitions... 744b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 745b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Build historic rule array 74650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UDate* times = (UDate*)uprv_malloc(sizeof(UDate)*transCount); /* large enough to store all transition times */ 747b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (times == NULL) { 748b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 749b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru deleteTransitionRules(); 750b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 751b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 752b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (typeIdx = 0; typeIdx < typeCount; typeIdx++) { 753b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Gather all start times for each pair of offsets 754b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t nTimes = 0; 75550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho for (transitionIdx = firstTZTransitionIdx; transitionIdx < transCount; transitionIdx++) { 75650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (typeIdx == (int16_t)typeMapData[transitionIdx]) { 75750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UDate tt = (UDate)transitionTime(transitionIdx); 75850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (finalZone == NULL || tt <= finalStartMillis) { 759b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Exclude transitions after finalMillis 760b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru times[nTimes++] = tt; 761b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 762b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 763b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 764b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (nTimes > 0) { 765b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Create a TimeArrayTimeZoneRule 76650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho raw = typeOffsets[typeIdx << 1] * U_MILLIS_PER_SECOND; 76750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho dst = typeOffsets[(typeIdx << 1) + 1] * U_MILLIS_PER_SECOND; 768b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (historicRules == NULL) { 769b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru historicRuleCount = typeCount; 770b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru historicRules = (TimeArrayTimeZoneRule**)uprv_malloc(sizeof(TimeArrayTimeZoneRule*)*historicRuleCount); 771b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (historicRules == NULL) { 772b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 773b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru deleteTransitionRules(); 774b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(times); 775b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 776b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 777b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int i = 0; i < historicRuleCount; i++) { 778b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Initialize TimeArrayTimeZoneRule pointers as NULL 779b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru historicRules[i] = NULL; 780b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 781b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 782b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru historicRules[typeIdx] = new TimeArrayTimeZoneRule((dst == 0 ? stdName : dstName), 783b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru raw, dst, times, nTimes, DateTimeRule::UTC_TIME); 784c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // Check for memory allocation error 785c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (historicRules[typeIdx] == NULL) { 786c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 787c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru deleteTransitionRules(); 788c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return; 789c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 790b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 791b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 792b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uprv_free(times); 793b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 794b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Create initial transition 79550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho typeIdx = (int16_t)typeMapData[firstTZTransitionIdx]; 79650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho firstTZTransition = new TimeZoneTransition((UDate)transitionTime(firstTZTransitionIdx), 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *initialRule, *historicRules[typeIdx]); 798c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // Check to make sure firstTZTransition was created. 799c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (firstTZTransition == NULL) { 800c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 801c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru deleteTransitionRules(); 802c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return; 803c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (finalZone != NULL) { 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Get the first occurence of final rule starts 80850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UDate startTime = (UDate)finalStartMillis; 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TimeZoneRule *firstFinalRule = NULL; 81050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (finalZone->useDaylightTime()) { 812b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 813b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * Note: When an OlsonTimeZone is constructed, we should set the final year 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * as the start year of finalZone. However, the bounday condition used for 81550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * getting offset from finalZone has some problems. 81650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * For now, we do not set the valid start year when the construction time 81750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho * and create a clone and set the start year when extracting rules. 818b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru finalZoneWithStartYear = (SimpleTimeZone*)finalZone->clone(); 820c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // Check to make sure finalZone was actually cloned. 821c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (finalZoneWithStartYear == NULL) { 822c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 823c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru deleteTransitionRules(); 824c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return; 825c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 82650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho finalZoneWithStartYear->setStartYear(finalStartYear); 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TimeZoneTransition tzt; 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru finalZoneWithStartYear->getNextTransition(startTime, false, tzt); 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru firstFinalRule = tzt.getTo()->clone(); 831c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // Check to make sure firstFinalRule received proper clone. 832c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (firstFinalRule == NULL) { 833c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 834c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru deleteTransitionRules(); 835c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return; 836c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 837b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startTime = tzt.getTime(); 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 83950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // final rule with no transitions 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru finalZoneWithStartYear = (SimpleTimeZone*)finalZone->clone(); 84150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Check to make sure finalZone was actually cloned. 842c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (finalZoneWithStartYear == NULL) { 843c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 844c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru deleteTransitionRules(); 845c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return; 846c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru finalZone->getID(tzid); 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru firstFinalRule = new TimeArrayTimeZoneRule(tzid, 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru finalZone->getRawOffset(), 0, &startTime, 1, DateTimeRule::UTC_TIME); 850c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // Check firstFinalRule was properly created. 851c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (firstFinalRule == NULL) { 852c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 853c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru deleteTransitionRules(); 854c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return; 855c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TimeZoneRule *prevRule = NULL; 85850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (transCount > 0) { 85950294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho prevRule = historicRules[typeMapData[transCount - 1]]; 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (prevRule == NULL) { 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // No historic transitions, but only finalZone available 863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru prevRule = initialRule; 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru firstFinalTZTransition = new TimeZoneTransition(); 866c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru // Check to make sure firstFinalTZTransition was created before dereferencing 867c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru if (firstFinalTZTransition == NULL) { 868c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru status = U_MEMORY_ALLOCATION_ERROR; 869c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru deleteTransitionRules(); 870c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru return; 871c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru } 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru firstFinalTZTransition->setTime(startTime); 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru firstFinalTZTransition->adoptFrom(prevRule->clone()); 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru firstFinalTZTransition->adoptTo(firstFinalRule); 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 8798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusOlsonTimeZone::getNextTransition(UDate base, UBool inclusive, TimeZoneTransition& result) const { 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 8818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius checkTransitionRules(status); 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status)) { 883b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (finalZone != NULL) { 887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (inclusive && base == firstFinalTZTransition->getTime()) { 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = *firstFinalTZTransition; 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (base >= firstFinalTZTransition->getTime()) { 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (finalZone->useDaylightTime()) { 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //return finalZone->getNextTransition(base, inclusive, result); 893b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return finalZoneWithStartYear->getNextTransition(base, inclusive, result); 894b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // No more transitions 896b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (historicRules != NULL) { 901b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Find a historical transition 90250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int16_t transCount = transitionCount(); 90350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int16_t ttidx = transCount - 1; 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (; ttidx >= firstTZTransitionIdx; ttidx--) { 90550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UDate t = (UDate)transitionTime(ttidx); 906b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (base > t || (!inclusive && base == t)) { 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 908b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 91050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho if (ttidx == transCount - 1) { 911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (firstFinalTZTransition != NULL) { 912b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = *firstFinalTZTransition; 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 915b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 916b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (ttidx < firstTZTransitionIdx) { 918b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = *firstTZTransition; 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 921b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Create a TimeZoneTransition 92250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho TimeZoneRule *to = historicRules[typeMapData[ttidx + 1]]; 92350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho TimeZoneRule *from = historicRules[typeMapData[ttidx]]; 92450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UDate startTime = (UDate)transitionTime(ttidx+1); 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 926b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // The transitions loaded from zoneinfo.res may contain non-transition data 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString fromName, toName; 928b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru from->getName(fromName); 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru to->getName(toName); 930b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fromName == toName && from->getRawOffset() == to->getRawOffset() 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru && from->getDSTSavings() == to->getDSTSavings()) { 932b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getNextTransition(startTime, false, result); 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result.setTime(startTime); 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result.adoptFrom(from->clone()); 936b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result.adoptTo(to->clone()); 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 940b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool 9448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusOlsonTimeZone::getPreviousTransition(UDate base, UBool inclusive, TimeZoneTransition& result) const { 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 9468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius checkTransitionRules(status); 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status)) { 948b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 949b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (finalZone != NULL) { 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (inclusive && base == firstFinalTZTransition->getTime()) { 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = *firstFinalTZTransition; 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (base > firstFinalTZTransition->getTime()) { 956b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (finalZone->useDaylightTime()) { 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //return finalZone->getPreviousTransition(base, inclusive, result); 958b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return finalZoneWithStartYear->getPreviousTransition(base, inclusive, result); 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = *firstFinalTZTransition; 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 96250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho } 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (historicRules != NULL) { 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Find a historical transition 96850294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho int16_t ttidx = transitionCount() - 1; 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (; ttidx >= firstTZTransitionIdx; ttidx--) { 97050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UDate t = (UDate)transitionTime(ttidx); 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (base > t || (inclusive && base == t)) { 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (ttidx < firstTZTransitionIdx) { 976b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // No more transitions 977b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (ttidx == firstTZTransitionIdx) { 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result = *firstTZTransition; 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 981b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 982b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Create a TimeZoneTransition 98350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho TimeZoneRule *to = historicRules[typeMapData[ttidx]]; 98450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho TimeZoneRule *from = historicRules[typeMapData[ttidx-1]]; 98550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho UDate startTime = (UDate)transitionTime(ttidx); 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // The transitions loaded from zoneinfo.res may contain non-transition data 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString fromName, toName; 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru from->getName(fromName); 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru to->getName(toName); 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (fromName == toName && from->getRawOffset() == to->getRawOffset() 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru && from->getDSTSavings() == to->getDSTSavings()) { 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return getPreviousTransition(startTime, false, result); 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result.setTime(startTime); 996b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result.adoptFrom(from->clone()); 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru result.adoptTo(to->clone()); 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 999b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return FALSE; 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruint32_t 10058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusOlsonTimeZone::countTransitionRules(UErrorCode& status) const { 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status)) { 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 10098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius checkTransitionRules(status); 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status)) { 1011b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return 0; 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t count = 0; 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (historicRules != NULL) { 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // historicRules may contain null entries when original zoneinfo data 1017b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // includes non transition data. 1018b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int32_t i = 0; i < historicRuleCount; i++) { 1019b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (historicRules[i] != NULL) { 1020b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count++; 1021b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1022b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1024b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (finalZone != NULL) { 1025b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (finalZone->useDaylightTime()) { 1026b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count += 2; 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count++; 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1031b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return count; 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruOlsonTimeZone::getTimeZoneRules(const InitialTimeZoneRule*& initial, 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const TimeZoneRule* trsrules[], 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t& trscount, 10388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UErrorCode& status) const { 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status)) { 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 10428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius checkTransitionRules(status); 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status)) { 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1045b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1046b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1047b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Initial rule 1048b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru initial = initialRule; 1049b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Transition rules 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t cnt = 0; 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (historicRules != NULL && trscount > cnt) { 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // historicRules may contain null entries when original zoneinfo data 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // includes non transition data. 1055b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int32_t i = 0; i < historicRuleCount; i++) { 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (historicRules[i] != NULL) { 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru trsrules[cnt++] = historicRules[i]; 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (cnt >= trscount) { 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1062b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (finalZoneWithStartYear != NULL && trscount > cnt) { 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const InitialTimeZoneRule *tmpini; 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t tmpcnt = trscount - cnt; 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru finalZoneWithStartYear->getTimeZoneRules(tmpini, &trsrules[cnt], tmpcnt, status); 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status)) { 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru cnt += tmpcnt; 1072b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Set the result length 1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru trscount = cnt; 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1077b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruU_NAMESPACE_END 1078b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif // !UCONFIG_NO_FORMATTING 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1081b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//eof 1082