/*
*******************************************************************************
* Copyright (C) 1997-2015, International Business Machines Corporation and
* others. All Rights Reserved.
*******************************************************************************
*
* File TIMEZONE.CPP
*
* Modification History:
*
*   Date        Name        Description
*   12/05/96    clhuang     Creation.
*   04/21/97    aliu        General clean-up and bug fixing.
*   05/08/97    aliu        Fixed Hashtable code per code review.
*   07/09/97    helena      Changed createInstance to createDefault.
*   07/29/97    aliu        Updated with all-new list of 96 UNIX-derived
*                           TimeZones.  Changed mechanism to load from static
*                           array rather than resource bundle.
*   07/07/1998  srl         Bugfixes from the Java side: UTC GMT CAT NST
*                           Added getDisplayName API
*                           going to add custom parsing.
*
*                           ISSUES:
*                               - should getDisplayName cache something?
*                               - should custom time zones be cached? [probably]
*  08/10/98     stephen     Brought getDisplayName() API in-line w/ conventions
*  08/19/98     stephen     Changed createTimeZone() to never return 0
*  09/02/98     stephen     Added getOffset(monthLen) and hasSameRules()
*  09/15/98     stephen     Added getStaticClassID()
*  02/22/99     stephen     Removed character literals for EBCDIC safety
*  05/04/99     stephen     Changed initDefault() for Mutex issues
*  07/12/99     helena      HPUX 11 CC Port.
*  12/03/99     aliu        Moved data out of static table into icudata.dll.
*                           Substantial rewrite of zone lookup, default zone, and
*                           available IDs code.  Misc. cleanup.
*********************************************************************************/

#include "utypeinfo.h"  // for 'typeid' to work

#include "unicode/utypes.h"
#include "unicode/ustring.h"
#include "uassert.h"
#include "ustr_imp.h"

#ifdef U_DEBUG_TZ
# include <stdio.h>
# include "uresimp.h" // for debugging

static void debug_tz_loc(const char *f, int32_t l)
{
  fprintf(stderr, "%s:%d: ", f, l);
}

static void debug_tz_msg(const char *pat, ...)
{
  va_list ap;
  va_start(ap, pat);
  vfprintf(stderr, pat, ap);
  fflush(stderr);
}
static char gStrBuf[256];
#define U_DEBUG_TZ_STR(x) u_austrncpy(gStrBuf,x,sizeof(gStrBuf)-1)
// must use double parens, i.e.:  U_DEBUG_TZ_MSG(("four is: %d",4));
#define U_DEBUG_TZ_MSG(x) {debug_tz_loc(__FILE__,__LINE__);debug_tz_msg x;}
#else
#define U_DEBUG_TZ_MSG(x)
#endif

#if !UCONFIG_NO_FORMATTING

#include "unicode/simpletz.h"
#include "unicode/calendar.h"
#include "unicode/gregocal.h"
#include "unicode/ures.h"
#include "unicode/tzfmt.h"
#include "unicode/numfmt.h"
#include "gregoimp.h"
#include "uresimp.h" // struct UResourceBundle
#include "olsontz.h"
#include "mutex.h"
#include "unicode/udata.h"
#include "ucln_in.h"
#include "cstring.h"
#include "cmemory.h"
#include "unicode/strenum.h"
#include "uassert.h"
#include "zonemeta.h"

#define kZONEINFO "zoneinfo64"
#define kREGIONS  "Regions"
#define kZONES    "Zones"
#define kRULES    "Rules"
#define kNAMES    "Names"
#define kTZVERSION  "TZVersion"
#define kLINKS    "links"
#define kMAX_CUSTOM_HOUR    23
#define kMAX_CUSTOM_MIN     59
#define kMAX_CUSTOM_SEC     59
#define MINUS 0x002D
#define PLUS 0x002B
#define ZERO_DIGIT 0x0030
#define COLON 0x003A

// Static data and constants

static const UChar         WORLD[] = {0x30, 0x30, 0x31, 0x00}; /* "001" */

static const UChar         GMT_ID[] = {0x47, 0x4D, 0x54, 0x00}; /* "GMT" */
static const UChar         UNKNOWN_ZONE_ID[] = {0x45, 0x74, 0x63, 0x2F, 0x55, 0x6E, 0x6B, 0x6E, 0x6F, 0x77, 0x6E, 0x00}; /* "Etc/Unknown" */
static const int32_t       GMT_ID_LENGTH = 3;
static const int32_t       UNKNOWN_ZONE_ID_LENGTH = 11;

static icu::TimeZone* DEFAULT_ZONE = NULL;
static icu::UInitOnce gDefaultZoneInitOnce = U_INITONCE_INITIALIZER;

static icu::TimeZone* _GMT = NULL;
static icu::TimeZone* _UNKNOWN_ZONE = NULL;
static icu::UInitOnce gStaticZonesInitOnce = U_INITONCE_INITIALIZER;

static char TZDATA_VERSION[16];
static icu::UInitOnce gTZDataVersionInitOnce = U_INITONCE_INITIALIZER;

static int32_t* MAP_SYSTEM_ZONES = NULL;
static int32_t* MAP_CANONICAL_SYSTEM_ZONES = NULL;
static int32_t* MAP_CANONICAL_SYSTEM_LOCATION_ZONES = NULL;

static int32_t LEN_SYSTEM_ZONES = 0;
static int32_t LEN_CANONICAL_SYSTEM_ZONES = 0;
static int32_t LEN_CANONICAL_SYSTEM_LOCATION_ZONES = 0;

static icu::UInitOnce gSystemZonesInitOnce = U_INITONCE_INITIALIZER;
static icu::UInitOnce gCanonicalZonesInitOnce = U_INITONCE_INITIALIZER;
static icu::UInitOnce gCanonicalLocationZonesInitOnce = U_INITONCE_INITIALIZER;

U_CDECL_BEGIN
static UBool U_CALLCONV timeZone_cleanup(void)
{
    U_NAMESPACE_USE
    delete DEFAULT_ZONE;
    DEFAULT_ZONE = NULL;
    gDefaultZoneInitOnce.reset();

    delete _GMT;
    _GMT = NULL;
    delete _UNKNOWN_ZONE;
    _UNKNOWN_ZONE = NULL;
    gStaticZonesInitOnce.reset();

    uprv_memset(TZDATA_VERSION, 0, sizeof(TZDATA_VERSION));
    gTZDataVersionInitOnce.reset();

    LEN_SYSTEM_ZONES = 0;
    uprv_free(MAP_SYSTEM_ZONES);
    MAP_SYSTEM_ZONES = 0;
    gSystemZonesInitOnce.reset();

    LEN_CANONICAL_SYSTEM_ZONES = 0;
    uprv_free(MAP_CANONICAL_SYSTEM_ZONES);
    MAP_CANONICAL_SYSTEM_ZONES = 0;
    gCanonicalZonesInitOnce.reset();

    LEN_CANONICAL_SYSTEM_LOCATION_ZONES = 0;
    uprv_free(MAP_CANONICAL_SYSTEM_LOCATION_ZONES);
    MAP_CANONICAL_SYSTEM_LOCATION_ZONES = 0;
    gCanonicalLocationZonesInitOnce.reset();

    return TRUE;
}
U_CDECL_END

U_NAMESPACE_BEGIN

static int32_t findInStringArray(UResourceBundle* array, const UnicodeString& id, UErrorCode &status)
{
    UnicodeString copy;
    const UChar *u;
    int32_t len;

    int32_t start = 0;
    int32_t limit = ures_getSize(array);
    int32_t mid;
    int32_t lastMid = INT32_MAX;
    if(U_FAILURE(status) || (limit < 1)) {
        return -1;
    }
    U_DEBUG_TZ_MSG(("fisa: Looking for %s, between %d and %d\n", U_DEBUG_TZ_STR(UnicodeString(id).getTerminatedBuffer()), start, limit));

    for (;;) {
        mid = (int32_t)((start + limit) / 2);
        if (lastMid == mid) {   /* Have we moved? */
            break;  /* We haven't moved, and it wasn't found. */
        }
        lastMid = mid;
        u = ures_getStringByIndex(array, mid, &len, &status);
        if (U_FAILURE(status)) {
            break;
        }
        U_DEBUG_TZ_MSG(("tz: compare to %s, %d .. [%d] .. %d\n", U_DEBUG_TZ_STR(u), start, mid, limit));
        copy.setTo(TRUE, u, len);
        int r = id.compare(copy);
        if(r==0) {
            U_DEBUG_TZ_MSG(("fisa: found at %d\n", mid));
            return mid;
        } else if(r<0) {
            limit = mid;
        } else {
            start = mid;
        }
    }
    U_DEBUG_TZ_MSG(("fisa: not found\n"));
    return -1;
}

/**
 * Fetch a specific zone by name.  Replaces the getByKey call.
 * @param top Top timezone resource
 * @param id Time zone ID
 * @param oldbundle Bundle for reuse (or NULL).   see 'ures_open()'
 * @return the zone's bundle if found, or undefined if error.  Reuses oldbundle.
 */
static UResourceBundle* getZoneByName(const UResourceBundle* top, const UnicodeString& id, UResourceBundle *oldbundle, UErrorCode& status) {
    // load the Rules object
    UResourceBundle *tmp = ures_getByKey(top, kNAMES, NULL, &status);

    // search for the string
    int32_t idx = findInStringArray(tmp, id, status);

    if((idx == -1) && U_SUCCESS(status)) {
        // not found
        status = U_MISSING_RESOURCE_ERROR;
        //ures_close(oldbundle);
        //oldbundle = NULL;
    } else {
        U_DEBUG_TZ_MSG(("gzbn: oldbundle= size %d, type %d, %s\n", ures_getSize(tmp), ures_getType(tmp), u_errorName(status)));
        tmp = ures_getByKey(top, kZONES, tmp, &status); // get Zones object from top
        U_DEBUG_TZ_MSG(("gzbn: loaded ZONES, size %d, type %d, path %s %s\n", ures_getSize(tmp), ures_getType(tmp), ures_getPath(tmp), u_errorName(status)));
        oldbundle = ures_getByIndex(tmp, idx, oldbundle, &status); // get nth Zone object
        U_DEBUG_TZ_MSG(("gzbn: loaded z#%d, size %d, type %d, path %s, %s\n", idx, ures_getSize(oldbundle), ures_getType(oldbundle), ures_getPath(oldbundle),  u_errorName(status)));
    }
    ures_close(tmp);
    if(U_FAILURE(status)) {
        //ures_close(oldbundle);
        return NULL;
    } else {
        return oldbundle;
    }
}


UResourceBundle* TimeZone::loadRule(const UResourceBundle* top, const UnicodeString& ruleid, UResourceBundle* oldbundle, UErrorCode& status) {
    char key[64];
    ruleid.extract(0, sizeof(key)-1, key, (int32_t)sizeof(key)-1, US_INV);
    U_DEBUG_TZ_MSG(("loadRule(%s)\n", key));
    UResourceBundle *r = ures_getByKey(top, kRULES, oldbundle, &status);
    U_DEBUG_TZ_MSG(("loadRule(%s) -> kRULES [%s]\n", key, u_errorName(status)));
    r = ures_getByKey(r, key, r, &status);
    U_DEBUG_TZ_MSG(("loadRule(%s) -> item [%s]\n", key, u_errorName(status)));
    return r;
}

/**
 * Given an ID, open the appropriate resource for the given time zone.
 * Dereference aliases if necessary.
 * @param id zone id
 * @param res resource, which must be ready for use (initialized but not open)
 * @param ec input-output error code
 * @return top-level resource bundle
 */
static UResourceBundle* openOlsonResource(const UnicodeString& id,
                                          UResourceBundle& res,
                                          UErrorCode& ec)
{
#if U_DEBUG_TZ
    char buf[128];
    id.extract(0, sizeof(buf)-1, buf, sizeof(buf), "");
#endif
    UResourceBundle *top = ures_openDirect(0, kZONEINFO, &ec);
    U_DEBUG_TZ_MSG(("pre: res sz=%d\n", ures_getSize(&res)));
    /* &res = */ getZoneByName(top, id, &res, ec);
    // Dereference if this is an alias.  Docs say result should be 1
    // but it is 0 in 2.8 (?).
    U_DEBUG_TZ_MSG(("Loading zone '%s' (%s, size %d) - %s\n", buf, ures_getKey((UResourceBundle*)&res), ures_getSize(&res), u_errorName(ec)));
    if (ures_getType(&res) == URES_INT) {
        int32_t deref = ures_getInt(&res, &ec) + 0;
        U_DEBUG_TZ_MSG(("getInt: %s - type is %d\n", u_errorName(ec), ures_getType(&res)));
        UResourceBundle *ares = ures_getByKey(top, kZONES, NULL, &ec); // dereference Zones section
        ures_getByIndex(ares, deref, &res, &ec);
        ures_close(ares);
        U_DEBUG_TZ_MSG(("alias to #%d (%s) - %s\n", deref, "??", u_errorName(ec)));
    } else {
        U_DEBUG_TZ_MSG(("not an alias - size %d\n", ures_getSize(&res)));
    }
    U_DEBUG_TZ_MSG(("%s - final status is %s\n", buf, u_errorName(ec)));
    return top;
}

// -------------------------------------

namespace {

void U_CALLCONV initStaticTimeZones() {
    // Initialize _GMT independently of other static data; it should
    // be valid even if we can't load the time zone UDataMemory.
    ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
    _UNKNOWN_ZONE = new SimpleTimeZone(0, UnicodeString(TRUE, UNKNOWN_ZONE_ID, UNKNOWN_ZONE_ID_LENGTH));
    _GMT = new SimpleTimeZone(0, UnicodeString(TRUE, GMT_ID, GMT_ID_LENGTH));
}

}  // anonymous namespace

const TimeZone& U_EXPORT2
TimeZone::getUnknown()
{
    umtx_initOnce(gStaticZonesInitOnce, &initStaticTimeZones);
    return *_UNKNOWN_ZONE;
}

const TimeZone* U_EXPORT2
TimeZone::getGMT(void)
{
    umtx_initOnce(gStaticZonesInitOnce, &initStaticTimeZones);
    return _GMT;
}

// *****************************************************************************
// class TimeZone
// *****************************************************************************

UOBJECT_DEFINE_ABSTRACT_RTTI_IMPLEMENTATION(TimeZone)

TimeZone::TimeZone()
    :   UObject(), fID()
{
}

// -------------------------------------

TimeZone::TimeZone(const UnicodeString &id)
    :   UObject(), fID(id)
{
}

// -------------------------------------

TimeZone::~TimeZone()
{
}

// -------------------------------------

TimeZone::TimeZone(const TimeZone &source)
    :   UObject(source), fID(source.fID)
{
}

// -------------------------------------

TimeZone &
TimeZone::operator=(const TimeZone &right)
{
    if (this != &right) fID = right.fID;
    return *this;
}

// -------------------------------------

UBool
TimeZone::operator==(const TimeZone& that) const
{
    return typeid(*this) == typeid(that) &&
        fID == that.fID;
}

// -------------------------------------

namespace {
TimeZone*
createSystemTimeZone(const UnicodeString& id, UErrorCode& ec) {
    if (U_FAILURE(ec)) {
        return NULL;
    }
    TimeZone* z = 0;
    UResourceBundle res;
    ures_initStackObject(&res);
    U_DEBUG_TZ_MSG(("pre-err=%s\n", u_errorName(ec)));
    UResourceBundle *top = openOlsonResource(id, res, ec);
    U_DEBUG_TZ_MSG(("post-err=%s\n", u_errorName(ec)));
    if (U_SUCCESS(ec)) {
        z = new OlsonTimeZone(top, &res, id, ec);
        if (z == NULL) {
          U_DEBUG_TZ_MSG(("cstz: olson time zone failed to initialize - err %s\n", u_errorName(ec)));
        }
    }
    ures_close(&res);
    ures_close(top);
    if (U_FAILURE(ec)) {
        U_DEBUG_TZ_MSG(("cstz: failed to create, err %s\n", u_errorName(ec)));
        delete z;
        z = 0;
    }
    return z;
}

/**
 * Lookup the given name in our system zone table.  If found,
 * instantiate a new zone of that name and return it.  If not
 * found, return 0.
 */
TimeZone*
createSystemTimeZone(const UnicodeString& id) {
    UErrorCode ec = U_ZERO_ERROR;
    return createSystemTimeZone(id, ec);
}

}

TimeZone* U_EXPORT2
TimeZone::createTimeZone(const UnicodeString& ID)
{
    /* We first try to lookup the zone ID in our system list.  If this
     * fails, we try to parse it as a custom string GMT[+-]hh:mm.  If
     * all else fails, we return GMT, which is probably not what the
     * user wants, but at least is a functioning TimeZone object.
     *
     * We cannot return NULL, because that would break compatibility
     * with the JDK.
     */
    TimeZone* result = createSystemTimeZone(ID);

    if (result == NULL) {
        U_DEBUG_TZ_MSG(("failed to load system time zone with id - falling to custom"));
        result = createCustomTimeZone(ID);
    }
    if (result == NULL) {
        U_DEBUG_TZ_MSG(("failed to load time zone with id - falling to Etc/Unknown(GMT)"));
        const TimeZone& unknown = getUnknown();
        if (_UNKNOWN_ZONE == NULL) {                   // Cannot test (&unknown == NULL) because the
          U_DEBUG_TZ_MSG(("failed to getUnknown()"));  // behavior of NULL references is undefined.
        } else {
          result = unknown.clone();
        }
    }
    return result;
}

// -------------------------------------

TimeZone* U_EXPORT2
TimeZone::detectHostTimeZone()
{
    // We access system timezone data through TPlatformUtilities,
    // including tzset(), timezone, and tzname[].
    int32_t rawOffset = 0;
    const char *hostID;

    // First, try to create a system timezone, based
    // on the string ID in tzname[0].

    uprv_tzset(); // Initialize tz... system data

    uprv_tzname_clear_cache();

    // Get the timezone ID from the host.  This function should do
    // any required host-specific remapping; e.g., on Windows this
    // function maps the Date and Time control panel setting to an
    // ICU timezone ID.
    hostID = uprv_tzname(0);

    // Invert sign because UNIX semantics are backwards
    rawOffset = uprv_timezone() * -U_MILLIS_PER_SECOND;

    TimeZone* hostZone = NULL;

    /* Make sure that the string is NULL terminated to prevent BoundsChecker/Purify warnings. */
    UnicodeString hostStrID(hostID, -1, US_INV);
    hostStrID.append((UChar)0);
    hostStrID.truncate(hostStrID.length()-1);
    hostZone = createSystemTimeZone(hostStrID);

#if U_PLATFORM_USES_ONLY_WIN32_API
    // hostID points to a heap-allocated location on Windows.
    uprv_free(const_cast<char *>(hostID));
#endif

    int32_t hostIDLen = hostStrID.length();
    if (hostZone != NULL && rawOffset != hostZone->getRawOffset()
        && (3 <= hostIDLen && hostIDLen <= 4))
    {
        // Uh oh. This probably wasn't a good id.
        // It was probably an ambiguous abbreviation
        delete hostZone;
        hostZone = NULL;
    }

    // Construct a fixed standard zone with the host's ID
    // and raw offset.
    if (hostZone == NULL) {
        hostZone = new SimpleTimeZone(rawOffset, hostStrID);
    }

    // If we _still_ don't have a time zone, use GMT.
    //
    // Note: This is extremely unlikely situation. If
    // new SimpleTimeZone(...) above fails, the following
    // code may also fail.
    if (hostZone == NULL) {
        const TimeZone* temptz = TimeZone::getGMT();
        // If we can't use GMT, get out.
        if (temptz == NULL) {
            return NULL;
        }
        hostZone = temptz->clone();
    }

    return hostZone;
}

// -------------------------------------

/**
 * Initialize DEFAULT_ZONE from the system default time zone.  
 * Upon return, DEFAULT_ZONE will not be NULL, unless operator new()
 * returns NULL.
 */
static void U_CALLCONV initDefault()
{
    ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);

    // If setDefault() has already been called we can skip getting the
    // default zone information from the system.
    if (DEFAULT_ZONE != NULL) {
        return;
    }
    
    // NOTE:  this code is safely single threaded, being only
    // run via umtx_initOnce().
    //
    // Some of the locale/timezone OS functions may not be thread safe,
    //
    // The operating system might actually use ICU to implement timezones.
    // So we may have ICU calling ICU here, like on AIX.
    // There shouldn't be a problem with this; initOnce does not hold a mutex
    // while the init function is being run.

    // The code detecting the host time zone was separated from this
    // and implemented as TimeZone::detectHostTimeZone()

    TimeZone *default_zone = TimeZone::detectHostTimeZone();

    // The only way for DEFAULT_ZONE to be non-null at this point is if the user
    // made a thread-unsafe call to setDefault() or adoptDefault() in another
    // thread while this thread was doing something that required getting the default.
    U_ASSERT(DEFAULT_ZONE == NULL);

    DEFAULT_ZONE = default_zone;
}

// -------------------------------------

TimeZone* U_EXPORT2
TimeZone::createDefault()
{
    umtx_initOnce(gDefaultZoneInitOnce, initDefault);
    return (DEFAULT_ZONE != NULL) ? DEFAULT_ZONE->clone() : NULL;
}

// -------------------------------------

void U_EXPORT2
TimeZone::adoptDefault(TimeZone* zone)
{
    if (zone != NULL)
    {
        TimeZone *old = DEFAULT_ZONE;
        DEFAULT_ZONE = zone;
        delete old;
        ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
    }
}
// -------------------------------------

void U_EXPORT2
TimeZone::setDefault(const TimeZone& zone)
{
    adoptDefault(zone.clone());
}

//----------------------------------------------------------------------


static void U_CALLCONV initMap(USystemTimeZoneType type, UErrorCode& ec) {
    ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);

    UResourceBundle *res = ures_openDirect(0, kZONEINFO, &ec);
    res = ures_getByKey(res, kNAMES, res, &ec); // dereference Zones section
    if (U_SUCCESS(ec)) {
        int32_t size = ures_getSize(res);
        int32_t *m = (int32_t *)uprv_malloc(size * sizeof(int32_t));
        if (m == NULL) {
            ec = U_MEMORY_ALLOCATION_ERROR;
        } else {
            int32_t numEntries = 0;
            for (int32_t i = 0; i < size; i++) {
                UnicodeString id = ures_getUnicodeStringByIndex(res, i, &ec);
                if (U_FAILURE(ec)) {
                    break;
                }
                if (0 == id.compare(UNKNOWN_ZONE_ID, UNKNOWN_ZONE_ID_LENGTH)) {
                    // exclude Etc/Unknown
                    continue;
                }
                if (type == UCAL_ZONE_TYPE_CANONICAL || type == UCAL_ZONE_TYPE_CANONICAL_LOCATION) {
                    UnicodeString canonicalID;
                    ZoneMeta::getCanonicalCLDRID(id, canonicalID, ec);
                    if (U_FAILURE(ec)) {
                        break;
                    }
                    if (canonicalID != id) {
                        // exclude aliases
                        continue;
                    }
                }
                if (type == UCAL_ZONE_TYPE_CANONICAL_LOCATION) {
                    const UChar *region = TimeZone::getRegion(id, ec);
                    if (U_FAILURE(ec)) {
                        break;
                    }
                    if (u_strcmp(region, WORLD) == 0) {
                       // exclude non-location ("001")
                        continue;
                    }
                }
                m[numEntries++] = i;
            }
            if (U_SUCCESS(ec)) {
                int32_t *tmp = m;
                m = (int32_t *)uprv_realloc(tmp, numEntries * sizeof(int32_t));
                if (m == NULL) {
                    // realloc failed.. use the original one even it has unused
                    // area at the end
                    m = tmp;
                }

                switch(type) {
                case UCAL_ZONE_TYPE_ANY:
                    U_ASSERT(MAP_SYSTEM_ZONES == NULL);
                    MAP_SYSTEM_ZONES = m;
                    LEN_SYSTEM_ZONES = numEntries;
                    break;
                case UCAL_ZONE_TYPE_CANONICAL:
                    U_ASSERT(MAP_CANONICAL_SYSTEM_ZONES == NULL);
                    MAP_CANONICAL_SYSTEM_ZONES = m;
                    LEN_CANONICAL_SYSTEM_ZONES = numEntries;
                    break;
                case UCAL_ZONE_TYPE_CANONICAL_LOCATION:
                    U_ASSERT(MAP_CANONICAL_SYSTEM_LOCATION_ZONES == NULL);
                    MAP_CANONICAL_SYSTEM_LOCATION_ZONES = m;
                    LEN_CANONICAL_SYSTEM_LOCATION_ZONES = numEntries;
                    break;
                }
            }
        }
    }
    ures_close(res);
}


/**
 * This is the default implementation for subclasses that do not
 * override this method.  This implementation calls through to the
 * 8-argument getOffset() method after suitable computations, and
 * correctly adjusts GMT millis to local millis when necessary.
 */
void TimeZone::getOffset(UDate date, UBool local, int32_t& rawOffset,
                         int32_t& dstOffset, UErrorCode& ec) const {
    if (U_FAILURE(ec)) {
        return;
    }

    rawOffset = getRawOffset();
    if (!local) {
        date += rawOffset; // now in local standard millis
    }

    // When local == TRUE, date might not be in local standard
    // millis.  getOffset taking 7 parameters used here assume
    // the given time in day is local standard time.
    // At STD->DST transition, there is a range of time which
    // does not exist.  When 'date' is in this time range
    // (and local == TRUE), this method interprets the specified
    // local time as DST.  At DST->STD transition, there is a
    // range of time which occurs twice.  In this case, this
    // method interprets the specified local time as STD.
    // To support the behavior above, we need to call getOffset
    // (with 7 args) twice when local == true and DST is
    // detected in the initial call.
    for (int32_t pass=0; ; ++pass) {
        int32_t year, month, dom, dow;
        double day = uprv_floor(date / U_MILLIS_PER_DAY);
        int32_t millis = (int32_t) (date - day * U_MILLIS_PER_DAY);

        Grego::dayToFields(day, year, month, dom, dow);

        dstOffset = getOffset(GregorianCalendar::AD, year, month, dom,
                              (uint8_t) dow, millis,
                              Grego::monthLength(year, month),
                              ec) - rawOffset;

        // Recompute if local==TRUE, dstOffset!=0.
        if (pass!=0 || !local || dstOffset == 0) {
            break;
        }
        // adjust to local standard millis
        date -= dstOffset;
    }
}

// -------------------------------------

// New available IDs API as of ICU 2.4.  Uses StringEnumeration API.

class TZEnumeration : public StringEnumeration {
private:

    // Map into to zones.  Our results are zone[map[i]] for
    // i=0..len-1, where zone[i] is the i-th Olson zone.  If map==NULL
    // then our results are zone[i] for i=0..len-1.  Len will be zero
    // if the zone data could not be loaded.
    int32_t* map;
    int32_t* localMap;
    int32_t  len;
    int32_t  pos;

    TZEnumeration(int32_t* mapData, int32_t mapLen, UBool adoptMapData) : pos(0) {
        map = mapData;
        localMap = adoptMapData ? mapData : NULL;
        len = mapLen;
    }

    UBool getID(int32_t i) {
        UErrorCode ec = U_ZERO_ERROR;
        int32_t idLen = 0;
        const UChar* id = NULL;
        UResourceBundle *top = ures_openDirect(0, kZONEINFO, &ec);
        top = ures_getByKey(top, kNAMES, top, &ec); // dereference Zones section
        id = ures_getStringByIndex(top, i, &idLen, &ec);
        if(U_FAILURE(ec)) {
            unistr.truncate(0);
        }
        else {
            unistr.fastCopyFrom(UnicodeString(TRUE, id, idLen));
        }
        ures_close(top);
        return U_SUCCESS(ec);
    }

    static int32_t* getMap(USystemTimeZoneType type, int32_t& len, UErrorCode& ec) {
        len = 0;
        if (U_FAILURE(ec)) {
            return NULL;
        }
        int32_t* m = NULL;
        switch (type) {
        case UCAL_ZONE_TYPE_ANY:
            umtx_initOnce(gSystemZonesInitOnce, &initMap, type, ec);
            m = MAP_SYSTEM_ZONES;
            len = LEN_SYSTEM_ZONES;
            break;
        case UCAL_ZONE_TYPE_CANONICAL:
            umtx_initOnce(gCanonicalZonesInitOnce, &initMap, type, ec);
            m = MAP_CANONICAL_SYSTEM_ZONES;
            len = LEN_CANONICAL_SYSTEM_ZONES;
            break;
        case UCAL_ZONE_TYPE_CANONICAL_LOCATION:
            umtx_initOnce(gCanonicalLocationZonesInitOnce, &initMap, type, ec);
            m = MAP_CANONICAL_SYSTEM_LOCATION_ZONES;
            len = LEN_CANONICAL_SYSTEM_LOCATION_ZONES;
            break;
        default:
            ec = U_ILLEGAL_ARGUMENT_ERROR;
            m = NULL;
            len = 0;
            break;
        }
        return m;
    }

public:

#define DEFAULT_FILTERED_MAP_SIZE 8
#define MAP_INCREMENT_SIZE 8

    static TZEnumeration* create(USystemTimeZoneType type, const char* region, const int32_t* rawOffset, UErrorCode& ec) {
        if (U_FAILURE(ec)) {
            return NULL;
        }

        int32_t baseLen;
        int32_t *baseMap = getMap(type, baseLen, ec);

        if (U_FAILURE(ec)) {
            return NULL;
        }

        // If any additional conditions are available,
        // create instance local map filtered by the conditions.

        int32_t *filteredMap = NULL;
        int32_t numEntries = 0;

        if (region != NULL || rawOffset != NULL) {
            int32_t filteredMapSize = DEFAULT_FILTERED_MAP_SIZE;
            filteredMap = (int32_t *)uprv_malloc(filteredMapSize * sizeof(int32_t));
            if (filteredMap == NULL) {
                ec = U_MEMORY_ALLOCATION_ERROR;
                return NULL;
            }

            // Walk through the base map
            UResourceBundle *res = ures_openDirect(0, kZONEINFO, &ec);
            res = ures_getByKey(res, kNAMES, res, &ec); // dereference Zones section
            for (int32_t i = 0; i < baseLen; i++) {
                int32_t zidx = baseMap[i];
                UnicodeString id = ures_getUnicodeStringByIndex(res, zidx, &ec);
                if (U_FAILURE(ec)) {
                    break;
                }
                if (region != NULL) {
                    // Filter by region
                    char tzregion[4]; // max 3 letters + null term
                    TimeZone::getRegion(id, tzregion, sizeof(tzregion), ec);
                    if (U_FAILURE(ec)) {
                        break;
                    }
                    if (uprv_stricmp(tzregion, region) != 0) {
                        // region does not match
                        continue;
                    }
                }
                if (rawOffset != NULL) {
                    // Filter by raw offset
                    // Note: This is VERY inefficient
                    TimeZone *z = createSystemTimeZone(id, ec);
                    if (U_FAILURE(ec)) {
                        break;
                    }
                    int32_t tzoffset = z->getRawOffset();
                    delete z;

                    if (tzoffset != *rawOffset) {
                        continue;
                    }
                }

                if (filteredMapSize <= numEntries) {
                    filteredMapSize += MAP_INCREMENT_SIZE;
                    int32_t *tmp = (int32_t *)uprv_realloc(filteredMap, filteredMapSize * sizeof(int32_t));
                    if (tmp == NULL) {
                        ec = U_MEMORY_ALLOCATION_ERROR;
                        break;
                    } else {
                        filteredMap = tmp;
                    }
                }

                filteredMap[numEntries++] = zidx;
            }

            if (U_FAILURE(ec)) {
                uprv_free(filteredMap);
                filteredMap = NULL;
            }

            ures_close(res);
        }

        TZEnumeration *result = NULL;
        if (U_SUCCESS(ec)) {
            // Finally, create a new enumeration instance
            if (filteredMap == NULL) {
                result = new TZEnumeration(baseMap, baseLen, FALSE);
            } else {
                result = new TZEnumeration(filteredMap, numEntries, TRUE);
                filteredMap = NULL;
            }
            if (result == NULL) {
                ec = U_MEMORY_ALLOCATION_ERROR;
            }
        }

        if (filteredMap != NULL) {
            uprv_free(filteredMap);
        }

        return result;
    }

    TZEnumeration(const TZEnumeration &other) : StringEnumeration(), map(NULL), localMap(NULL), len(0), pos(0) {
        if (other.localMap != NULL) {
            localMap = (int32_t *)uprv_malloc(other.len * sizeof(int32_t));
            if (localMap != NULL) {
                len = other.len;
                uprv_memcpy(localMap, other.localMap, len * sizeof(int32_t));
                pos = other.pos;
                map = localMap;
            } else {
                len = 0;
                pos = 0;
                map = NULL;
            }
        } else {
            map = other.map;
            localMap = NULL;
            len = other.len;
            pos = other.pos;
        }
    }

    virtual ~TZEnumeration();

    virtual StringEnumeration *clone() const {
        return new TZEnumeration(*this);
    }

    virtual int32_t count(UErrorCode& status) const {
        return U_FAILURE(status) ? 0 : len;
    }

    virtual const UnicodeString* snext(UErrorCode& status) {
        if (U_SUCCESS(status) && map != NULL && pos < len) {
            getID(map[pos]);
            ++pos;
            return &unistr;
        }
        return 0;
    }

    virtual void reset(UErrorCode& /*status*/) {
        pos = 0;
    }

public:
    static UClassID U_EXPORT2 getStaticClassID(void);
    virtual UClassID getDynamicClassID(void) const;
};

TZEnumeration::~TZEnumeration() {
    if (localMap != NULL) {
        uprv_free(localMap);
    }
}

UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TZEnumeration)

StringEnumeration* U_EXPORT2
TimeZone::createTimeZoneIDEnumeration(
            USystemTimeZoneType zoneType,
            const char* region,
            const int32_t* rawOffset,
            UErrorCode& ec) {
    return TZEnumeration::create(zoneType, region, rawOffset, ec);
}

StringEnumeration* U_EXPORT2
TimeZone::createEnumeration() {
    UErrorCode ec = U_ZERO_ERROR;
    return TZEnumeration::create(UCAL_ZONE_TYPE_ANY, NULL, NULL, ec);
}

StringEnumeration* U_EXPORT2
TimeZone::createEnumeration(int32_t rawOffset) {
    UErrorCode ec = U_ZERO_ERROR;
    return TZEnumeration::create(UCAL_ZONE_TYPE_ANY, NULL, &rawOffset, ec);
}

StringEnumeration* U_EXPORT2
TimeZone::createEnumeration(const char* country) {
    UErrorCode ec = U_ZERO_ERROR;
    return TZEnumeration::create(UCAL_ZONE_TYPE_ANY, country, NULL, ec);
}

// ---------------------------------------

int32_t U_EXPORT2
TimeZone::countEquivalentIDs(const UnicodeString& id) {
    int32_t result = 0;
    UErrorCode ec = U_ZERO_ERROR;
    UResourceBundle res;
    ures_initStackObject(&res);
    U_DEBUG_TZ_MSG(("countEquivalentIDs..\n"));
    UResourceBundle *top = openOlsonResource(id, res, ec);
    if (U_SUCCESS(ec)) {
        UResourceBundle r;
        ures_initStackObject(&r);
        ures_getByKey(&res, kLINKS, &r, &ec);
        ures_getIntVector(&r, &result, &ec);
        ures_close(&r);
    }
    ures_close(&res);
    ures_close(top);
    return result;
}

// ---------------------------------------

const UnicodeString U_EXPORT2
TimeZone::getEquivalentID(const UnicodeString& id, int32_t index) {
    U_DEBUG_TZ_MSG(("gEI(%d)\n", index));
    UnicodeString result;
    UErrorCode ec = U_ZERO_ERROR;
    UResourceBundle res;
    ures_initStackObject(&res);
    UResourceBundle *top = openOlsonResource(id, res, ec);
    int32_t zone = -1;
    if (U_SUCCESS(ec)) {
        UResourceBundle r;
        ures_initStackObject(&r);
        int32_t size;
        ures_getByKey(&res, kLINKS, &r, &ec);
        const int32_t* v = ures_getIntVector(&r, &size, &ec);
        if (U_SUCCESS(ec)) {
            if (index >= 0 && index < size) {
                zone = v[index];
            }
        }
        ures_close(&r);
    }
    ures_close(&res);
    if (zone >= 0) {
        UResourceBundle *ares = ures_getByKey(top, kNAMES, NULL, &ec); // dereference Zones section
        if (U_SUCCESS(ec)) {
            int32_t idLen = 0;
            const UChar* id = ures_getStringByIndex(ares, zone, &idLen, &ec);
            result.fastCopyFrom(UnicodeString(TRUE, id, idLen));
            U_DEBUG_TZ_MSG(("gei(%d) -> %d, len%d, %s\n", index, zone, result.length(), u_errorName(ec)));
        }
        ures_close(ares);
    }
    ures_close(top);
#if defined(U_DEBUG_TZ)
    if(result.length() ==0) {
      U_DEBUG_TZ_MSG(("equiv [__, #%d] -> 0 (%s)\n", index, u_errorName(ec)));
    }
#endif
    return result;
}

// ---------------------------------------

// These methods are used by ZoneMeta class only.

const UChar*
TimeZone::findID(const UnicodeString& id) {
    const UChar *result = NULL;
    UErrorCode ec = U_ZERO_ERROR;
    UResourceBundle *rb = ures_openDirect(NULL, kZONEINFO, &ec);

    // resolve zone index by name
    UResourceBundle *names = ures_getByKey(rb, kNAMES, NULL, &ec);
    int32_t idx = findInStringArray(names, id, ec);
    result = ures_getStringByIndex(names, idx, NULL, &ec);
    if (U_FAILURE(ec)) {
        result = NULL;
    }
    ures_close(names);
    ures_close(rb);
    return result;
}


const UChar*
TimeZone::dereferOlsonLink(const UnicodeString& id) {
    const UChar *result = NULL;
    UErrorCode ec = U_ZERO_ERROR;
    UResourceBundle *rb = ures_openDirect(NULL, kZONEINFO, &ec);

    // resolve zone index by name
    UResourceBundle *names = ures_getByKey(rb, kNAMES, NULL, &ec);
    int32_t idx = findInStringArray(names, id, ec);
    result = ures_getStringByIndex(names, idx, NULL, &ec);

    // open the zone bundle by index
    ures_getByKey(rb, kZONES, rb, &ec);
    ures_getByIndex(rb, idx, rb, &ec); 

    if (U_SUCCESS(ec)) {
        if (ures_getType(rb) == URES_INT) {
            // this is a link - dereference the link
            int32_t deref = ures_getInt(rb, &ec);
            const UChar* tmp = ures_getStringByIndex(names, deref, NULL, &ec);
            if (U_SUCCESS(ec)) {
                result = tmp;
            }
        }
    }

    ures_close(names);
    ures_close(rb);

    return result;
}

const UChar*
TimeZone::getRegion(const UnicodeString& id) {
    UErrorCode status = U_ZERO_ERROR;
    return getRegion(id, status);
}

const UChar*
TimeZone::getRegion(const UnicodeString& id, UErrorCode& status) {
    if (U_FAILURE(status)) {
        return NULL;
    }
    const UChar *result = NULL;
    UResourceBundle *rb = ures_openDirect(NULL, kZONEINFO, &status);

    // resolve zone index by name
    UResourceBundle *res = ures_getByKey(rb, kNAMES, NULL, &status);
    int32_t idx = findInStringArray(res, id, status);

    // get region mapping
    ures_getByKey(rb, kREGIONS, res, &status);
    const UChar *tmp = ures_getStringByIndex(res, idx, NULL, &status);
    if (U_SUCCESS(status)) {
        result = tmp;
    }

    ures_close(res);
    ures_close(rb);

    return result;
}


// ---------------------------------------
int32_t
TimeZone::getRegion(const UnicodeString& id, char *region, int32_t capacity, UErrorCode& status)
{
    int32_t resultLen = 0;
    *region = 0;
    if (U_FAILURE(status)) {
        return 0;
    }

    const UChar *uregion = NULL;
    // "Etc/Unknown" is not a system zone ID,
    // but in the zone data
    if (id.compare(UNKNOWN_ZONE_ID, UNKNOWN_ZONE_ID_LENGTH) != 0) {
        uregion = getRegion(id);
    }
    if (uregion == NULL) {
        status = U_ILLEGAL_ARGUMENT_ERROR;
        return 0;
    }
    resultLen = u_strlen(uregion);
    // A region code is represented by invariant characters
    u_UCharsToChars(uregion, region, uprv_min(resultLen, capacity));

    if (capacity < resultLen) {
        status = U_BUFFER_OVERFLOW_ERROR;
        return resultLen;
    }

    return u_terminateChars(region, capacity, resultLen, &status);
}

// ---------------------------------------


UnicodeString&
TimeZone::getDisplayName(UnicodeString& result) const
{
    return getDisplayName(FALSE,LONG,Locale::getDefault(), result);
}

UnicodeString&
TimeZone::getDisplayName(const Locale& locale, UnicodeString& result) const
{
    return getDisplayName(FALSE, LONG, locale, result);
}

UnicodeString&
TimeZone::getDisplayName(UBool daylight, EDisplayType style, UnicodeString& result)  const
{
    return getDisplayName(daylight,style, Locale::getDefault(), result);
}
//--------------------------------------
int32_t
TimeZone::getDSTSavings()const {
    if (useDaylightTime()) {
        return 3600000;
    }
    return 0;
}
//---------------------------------------
UnicodeString&
TimeZone::getDisplayName(UBool daylight, EDisplayType style, const Locale& locale, UnicodeString& result) const
{
    UErrorCode status = U_ZERO_ERROR;
    UDate date = Calendar::getNow();
    UTimeZoneFormatTimeType timeType;
    int32_t offset;

    if (style == GENERIC_LOCATION || style == LONG_GENERIC || style == SHORT_GENERIC) {
        LocalPointer<TimeZoneFormat> tzfmt(TimeZoneFormat::createInstance(locale, status));
        if (U_FAILURE(status)) {
            result.remove();
            return result;
        }
        // Generic format
        switch (style) {
        case GENERIC_LOCATION:
            tzfmt->format(UTZFMT_STYLE_GENERIC_LOCATION, *this, date, result, &timeType);
            break;
        case LONG_GENERIC:
            tzfmt->format(UTZFMT_STYLE_GENERIC_LONG, *this, date, result, &timeType);
            break;
        case SHORT_GENERIC:
            tzfmt->format(UTZFMT_STYLE_GENERIC_SHORT, *this, date, result, &timeType);
            break;
        default:
            U_ASSERT(FALSE);
        }
        // Generic format many use Localized GMT as the final fallback.
        // When Localized GMT format is used, the result might not be
        // appropriate for the requested daylight value.
        if ((daylight && timeType == UTZFMT_TIME_TYPE_STANDARD) || (!daylight && timeType == UTZFMT_TIME_TYPE_DAYLIGHT)) {
            offset = daylight ? getRawOffset() + getDSTSavings() : getRawOffset();
            if (style == SHORT_GENERIC) {
                tzfmt->formatOffsetShortLocalizedGMT(offset, result, status);
            } else {
                tzfmt->formatOffsetLocalizedGMT(offset, result, status);
            }
        }
    } else if (style == LONG_GMT || style == SHORT_GMT) {
        LocalPointer<TimeZoneFormat> tzfmt(TimeZoneFormat::createInstance(locale, status));
        if (U_FAILURE(status)) {
            result.remove();
            return result;
        }
        offset = daylight && useDaylightTime() ? getRawOffset() + getDSTSavings() : getRawOffset();
        switch (style) {
        case LONG_GMT:
            tzfmt->formatOffsetLocalizedGMT(offset, result, status);
            break;
        case SHORT_GMT:
            tzfmt->formatOffsetISO8601Basic(offset, FALSE, FALSE, FALSE, result, status);
            break;
        default:
            U_ASSERT(FALSE);
        }

    } else {
        U_ASSERT(style == LONG || style == SHORT || style == SHORT_COMMONLY_USED);
        UTimeZoneNameType nameType = UTZNM_UNKNOWN;
        switch (style) {
        case LONG:
            nameType = daylight ? UTZNM_LONG_DAYLIGHT : UTZNM_LONG_STANDARD;
            break;
        case SHORT:
        case SHORT_COMMONLY_USED:
            nameType = daylight ? UTZNM_SHORT_DAYLIGHT : UTZNM_SHORT_STANDARD;
            break;
        default:
            U_ASSERT(FALSE);
        }
        LocalPointer<TimeZoneNames> tznames(TimeZoneNames::createInstance(locale, status));
        if (U_FAILURE(status)) {
            result.remove();
            return result;
        }
        UnicodeString canonicalID(ZoneMeta::getCanonicalCLDRID(*this));
        tznames->getDisplayName(canonicalID, nameType, date, result);
        if (result.isEmpty()) {
            // Fallback to localized GMT
            LocalPointer<TimeZoneFormat> tzfmt(TimeZoneFormat::createInstance(locale, status));
            offset = daylight && useDaylightTime() ? getRawOffset() + getDSTSavings() : getRawOffset();
            if (style == LONG) {
                tzfmt->formatOffsetLocalizedGMT(offset, result, status);
            } else {
                tzfmt->formatOffsetShortLocalizedGMT(offset, result, status);
            }
        }
    }
    if (U_FAILURE(status)) {
        result.remove();
    }
    return  result;
}

/**
 * Parse a custom time zone identifier and return a corresponding zone.
 * @param id a string of the form GMT[+-]hh:mm, GMT[+-]hhmm, or
 * GMT[+-]hh.
 * @return a newly created SimpleTimeZone with the given offset and
 * no Daylight Savings Time, or null if the id cannot be parsed.
*/
TimeZone*
TimeZone::createCustomTimeZone(const UnicodeString& id)
{
    int32_t sign, hour, min, sec;
    if (parseCustomID(id, sign, hour, min, sec)) {
        UnicodeString customID;
        formatCustomID(hour, min, sec, (sign < 0), customID);
        int32_t offset = sign * ((hour * 60 + min) * 60 + sec) * 1000;
        return new SimpleTimeZone(offset, customID);
    }
    return NULL;
}

UnicodeString&
TimeZone::getCustomID(const UnicodeString& id, UnicodeString& normalized, UErrorCode& status) {
    normalized.remove();
    if (U_FAILURE(status)) {
        return normalized;
    }
    int32_t sign, hour, min, sec;
    if (parseCustomID(id, sign, hour, min, sec)) {
        formatCustomID(hour, min, sec, (sign < 0), normalized);
    } else {
        status = U_ILLEGAL_ARGUMENT_ERROR;
    }
    return normalized;
}

UBool
TimeZone::parseCustomID(const UnicodeString& id, int32_t& sign,
                        int32_t& hour, int32_t& min, int32_t& sec) {
    static const int32_t         kParseFailed = -99999;

    NumberFormat* numberFormat = 0;
    UnicodeString idUppercase = id;
    idUppercase.toUpper("");

    if (id.length() > GMT_ID_LENGTH &&
        idUppercase.startsWith(GMT_ID, GMT_ID_LENGTH))
    {
        ParsePosition pos(GMT_ID_LENGTH);
        sign = 1;
        hour = 0;
        min = 0;
        sec = 0;

        if (id[pos.getIndex()] == MINUS /*'-'*/) {
            sign = -1;
        } else if (id[pos.getIndex()] != PLUS /*'+'*/) {
            return FALSE;
        }
        pos.setIndex(pos.getIndex() + 1);

        UErrorCode success = U_ZERO_ERROR;
        numberFormat = NumberFormat::createInstance(success);
        if(U_FAILURE(success)){
            return FALSE;
        }
        numberFormat->setParseIntegerOnly(TRUE);
        //numberFormat->setLenient(TRUE); // TODO: May need to set this, depends on latest timezone parsing

        // Look for either hh:mm, hhmm, or hh
        int32_t start = pos.getIndex();
        Formattable n(kParseFailed);
        numberFormat->parse(id, n, pos);
        if (pos.getIndex() == start) {
            delete numberFormat;
            return FALSE;
        }
        hour = n.getLong();

        if (pos.getIndex() < id.length()) {
            if (pos.getIndex() - start > 2
                || id[pos.getIndex()] != COLON) {
                delete numberFormat;
                return FALSE;
            }
            // hh:mm
            pos.setIndex(pos.getIndex() + 1);
            int32_t oldPos = pos.getIndex();
            n.setLong(kParseFailed);
            numberFormat->parse(id, n, pos);
            if ((pos.getIndex() - oldPos) != 2) {
                // must be 2 digits
                delete numberFormat;
                return FALSE;
            }
            min = n.getLong();
            if (pos.getIndex() < id.length()) {
                if (id[pos.getIndex()] != COLON) {
                    delete numberFormat;
                    return FALSE;
                }
                // [:ss]
                pos.setIndex(pos.getIndex() + 1);
                oldPos = pos.getIndex();
                n.setLong(kParseFailed);
                numberFormat->parse(id, n, pos);
                if (pos.getIndex() != id.length()
                        || (pos.getIndex() - oldPos) != 2) {
                    delete numberFormat;
                    return FALSE;
                }
                sec = n.getLong();
            }
        } else {
            // Supported formats are below -
            //
            // HHmmss
            // Hmmss
            // HHmm
            // Hmm
            // HH
            // H

            int32_t length = pos.getIndex() - start;
            if (length <= 0 || 6 < length) {
                // invalid length
                delete numberFormat;
                return FALSE;
            }
            switch (length) {
                case 1:
                case 2:
                    // already set to hour
                    break;
                case 3:
                case 4:
                    min = hour % 100;
                    hour /= 100;
                    break;
                case 5:
                case 6:
                    sec = hour % 100;
                    min = (hour/100) % 100;
                    hour /= 10000;
                    break;
            }
        }

        delete numberFormat;

        if (hour > kMAX_CUSTOM_HOUR || min > kMAX_CUSTOM_MIN || sec > kMAX_CUSTOM_SEC) {
            return FALSE;
        }
        return TRUE;
    }
    return FALSE;
}

UnicodeString&
TimeZone::formatCustomID(int32_t hour, int32_t min, int32_t sec,
                         UBool negative, UnicodeString& id) {
    // Create time zone ID - GMT[+|-]hhmm[ss]
    id.setTo(GMT_ID, GMT_ID_LENGTH);
    if (hour | min | sec) {
        if (negative) {
            id += (UChar)MINUS;
        } else {
            id += (UChar)PLUS;
        }

        if (hour < 10) {
            id += (UChar)ZERO_DIGIT;
        } else {
            id += (UChar)(ZERO_DIGIT + hour/10);
        }
        id += (UChar)(ZERO_DIGIT + hour%10);
        id += (UChar)COLON;
        if (min < 10) {
            id += (UChar)ZERO_DIGIT;
        } else {
            id += (UChar)(ZERO_DIGIT + min/10);
        }
        id += (UChar)(ZERO_DIGIT + min%10);

        if (sec) {
            id += (UChar)COLON;
            if (sec < 10) {
                id += (UChar)ZERO_DIGIT;
            } else {
                id += (UChar)(ZERO_DIGIT + sec/10);
            }
            id += (UChar)(ZERO_DIGIT + sec%10);
        }
    }
    return id;
}


UBool
TimeZone::hasSameRules(const TimeZone& other) const
{
    return (getRawOffset() == other.getRawOffset() &&
            useDaylightTime() == other.useDaylightTime());
}

static void U_CALLCONV initTZDataVersion(UErrorCode &status) {
    ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONE, timeZone_cleanup);
    int32_t len = 0;
    UResourceBundle *bundle = ures_openDirect(NULL, kZONEINFO, &status);
    const UChar *tzver = ures_getStringByKey(bundle, kTZVERSION, &len, &status);

    if (U_SUCCESS(status)) {
        if (len >= (int32_t)sizeof(TZDATA_VERSION)) {
            // Ensure that there is always space for a trailing nul in TZDATA_VERSION
            len = sizeof(TZDATA_VERSION) - 1;
        }
        u_UCharsToChars(tzver, TZDATA_VERSION, len);
    }
    ures_close(bundle);

}

const char*
TimeZone::getTZDataVersion(UErrorCode& status)
{
    umtx_initOnce(gTZDataVersionInitOnce, &initTZDataVersion, status);
    return (const char*)TZDATA_VERSION;
}

UnicodeString&
TimeZone::getCanonicalID(const UnicodeString& id, UnicodeString& canonicalID, UErrorCode& status)
{
    UBool isSystemID = FALSE;
    return getCanonicalID(id, canonicalID, isSystemID, status);
}

UnicodeString&
TimeZone::getCanonicalID(const UnicodeString& id, UnicodeString& canonicalID, UBool& isSystemID,
                         UErrorCode& status)
{
    canonicalID.remove();
    isSystemID = FALSE;
    if (U_FAILURE(status)) {
        return canonicalID;
    }
    if (id.compare(UNKNOWN_ZONE_ID, UNKNOWN_ZONE_ID_LENGTH) == 0) {
        // special case - Etc/Unknown is a canonical ID, but not system ID
        canonicalID.fastCopyFrom(id);
        isSystemID = FALSE;
    } else {
        ZoneMeta::getCanonicalCLDRID(id, canonicalID, status);
        if (U_SUCCESS(status)) {
            isSystemID = TRUE;
        } else {
            // Not a system ID
            status = U_ZERO_ERROR;
            getCustomID(id, canonicalID, status);
        }
    }
    return canonicalID;
}

UnicodeString&
TimeZone::getWindowsID(const UnicodeString& id, UnicodeString& winid, UErrorCode& status) {
    winid.remove();
    if (U_FAILURE(status)) {
        return winid;
    }

    // canonicalize the input ID
    UnicodeString canonicalID;
    UBool isSystemID = FALSE;

    getCanonicalID(id, canonicalID, isSystemID, status);
    if (U_FAILURE(status) || !isSystemID) {
        // mapping data is only applicable to tz database IDs
        if (status == U_ILLEGAL_ARGUMENT_ERROR) {
            // getWindowsID() sets an empty string where
            // getCanonicalID() sets a U_ILLEGAL_ARGUMENT_ERROR.
            status = U_ZERO_ERROR;
        }
        return winid;
    }

    UResourceBundle *mapTimezones = ures_openDirect(NULL, "windowsZones", &status);
    ures_getByKey(mapTimezones, "mapTimezones", mapTimezones, &status);

    if (U_FAILURE(status)) {
        return winid;
    }

    UResourceBundle *winzone = NULL;
    UBool found = FALSE;
    while (ures_hasNext(mapTimezones) && !found) {
        winzone = ures_getNextResource(mapTimezones, winzone, &status);
        if (U_FAILURE(status)) {
            break;
        }
        if (ures_getType(winzone) != URES_TABLE) {
            continue;
        }
        UResourceBundle *regionalData = NULL;
        while (ures_hasNext(winzone) && !found) {
            regionalData = ures_getNextResource(winzone, regionalData, &status);
            if (U_FAILURE(status)) {
                break;
            }
            if (ures_getType(regionalData) != URES_STRING) {
                continue;
            }
            int32_t len;
            const UChar *tzids = ures_getString(regionalData, &len, &status);
            if (U_FAILURE(status)) {
                break;
            }

            const UChar *start = tzids;
            UBool hasNext = TRUE;
            while (hasNext) {
                const UChar *end = u_strchr(start, (UChar)0x20);
                if (end == NULL) {
                    end = tzids + len;
                    hasNext = FALSE;
                }
                if (canonicalID.compare(start, end - start) == 0) {
                    winid = UnicodeString(ures_getKey(winzone), -1 , US_INV);
                    found = TRUE;
                    break;
                }
                start = end + 1;
            }
        }
        ures_close(regionalData);
    }
    ures_close(winzone);
    ures_close(mapTimezones);

    return winid;
}

#define MAX_WINDOWS_ID_SIZE 128

UnicodeString&
TimeZone::getIDForWindowsID(const UnicodeString& winid, const char* region, UnicodeString& id, UErrorCode& status) {
    id.remove();
    if (U_FAILURE(status)) {
        return id;
    }

    UResourceBundle *zones = ures_openDirect(NULL, "windowsZones", &status);
    ures_getByKey(zones, "mapTimezones", zones, &status);
    if (U_FAILURE(status)) {
        ures_close(zones);
        return id;
    }

    UErrorCode tmperr = U_ZERO_ERROR;
    char winidKey[MAX_WINDOWS_ID_SIZE];
    int32_t winKeyLen = winid.extract(0, winid.length(), winidKey, sizeof(winidKey) - 1, US_INV);

    if (winKeyLen == 0 || winKeyLen >= (int32_t)sizeof(winidKey)) {
        ures_close(zones);
        return id;
    }
    winidKey[winKeyLen] = 0;

    ures_getByKey(zones, winidKey, zones, &tmperr); // use tmperr, because windows mapping might not
                                                    // be avaiable by design
    if (U_FAILURE(tmperr)) {
        ures_close(zones);
        return id;
    }

    const UChar *tzid = NULL;
    int32_t len = 0;
    UBool gotID = FALSE;
    if (region) {
        const UChar *tzids = ures_getStringByKey(zones, region, &len, &tmperr); // use tmperr, because
                                                                                // regional mapping is optional
        if (U_SUCCESS(tmperr)) {
            // first ID delimited by space is the defasult one
            const UChar *end = u_strchr(tzids, (UChar)0x20);
            if (end == NULL) {
                id.setTo(tzids, -1);
            } else {
                id.setTo(tzids, end - tzids);
            }
            gotID = TRUE;
        }
    }

    if (!gotID) {
        tzid = ures_getStringByKey(zones, "001", &len, &status);    // using status, because "001" must be
                                                                // available at this point
        if (U_SUCCESS(status)) {
            id.setTo(tzid, len);
        }
    }

    ures_close(zones);
    return id;
}


U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */

//eof
