/*
*******************************************************************************
* 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 "starboard/client_porting/poem/assert_poem.h"
#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 || defined(__LB_XB1__)
    // 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
