1b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho/* 2b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho******************************************************************************* 359d709d503bab6e2b61931737e662dd293b40578ccornelius* Copyright (C) 2011-2013, International Business Machines Corporation and 459d709d503bab6e2b61931737e662dd293b40578ccornelius* others. All Rights Reserved. 5b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho******************************************************************************* 6b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho*/ 7b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 8b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "unicode/utypes.h" 9b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 10b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#if !UCONFIG_NO_FORMATTING 11b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 12103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/calendar.h" 13103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/tzfmt.h" 14103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/numsys.h" 15103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/uchar.h" 16103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "unicode/udat.h" 17b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "tzgnames.h" 18b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "cmemory.h" 19b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "cstring.h" 20b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "putilimp.h" 21b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "uassert.h" 22b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "ucln_in.h" 23b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "umutex.h" 24103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "uresimp.h" 25103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "ureslocs.h" 26103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#include "uvector.h" 27b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#include "zonemeta.h" 288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#include "tznames_impl.h" // TextTrieMap 29b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 30b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_NAMESPACE_BEGIN 31b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius// Bit flags used by the parse method. 338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius// The order must match UTimeZoneFormatStyle enum. 348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#define ISO_Z_STYLE_FLAG 0x0080 358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#define ISO_LOCAL_STYLE_FLAG 0x0100 368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const int16_t STYLE_PARSE_FLAGS[] = { 378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 0x0001, // UTZFMT_STYLE_GENERIC_LOCATION, 388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 0x0002, // UTZFMT_STYLE_GENERIC_LONG, 398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 0x0004, // UTZFMT_STYLE_GENERIC_SHORT, 408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 0x0008, // UTZFMT_STYLE_SPECIFIC_LONG, 418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 0x0010, // UTZFMT_STYLE_SPECIFIC_SHORT, 428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 0x0020, // UTZFMT_STYLE_LOCALIZED_GMT, 438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 0x0040, // UTZFMT_STYLE_LOCALIZED_GMT_SHORT, 448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ISO_Z_STYLE_FLAG, // UTZFMT_STYLE_ISO_BASIC_SHORT, 458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ISO_LOCAL_STYLE_FLAG, // UTZFMT_STYLE_ISO_BASIC_LOCAL_SHORT, 468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ISO_Z_STYLE_FLAG, // UTZFMT_STYLE_ISO_BASIC_FIXED, 478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ISO_LOCAL_STYLE_FLAG, // UTZFMT_STYLE_ISO_BASIC_LOCAL_FIXED, 488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ISO_Z_STYLE_FLAG, // UTZFMT_STYLE_ISO_BASIC_FULL, 498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ISO_LOCAL_STYLE_FLAG, // UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL, 508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ISO_Z_STYLE_FLAG, // UTZFMT_STYLE_ISO_EXTENDED_FIXED, 518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ISO_LOCAL_STYLE_FLAG, // UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FIXED, 528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ISO_Z_STYLE_FLAG, // UTZFMT_STYLE_ISO_EXTENDED_FULL, 538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ISO_LOCAL_STYLE_FLAG, // UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL, 548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 0x0200, // UTZFMT_STYLE_ZONE_ID, 558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 0x0400, // UTZFMT_STYLE_ZONE_ID_SHORT, 568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 0x0800 // UTZFMT_STYLE_EXEMPLAR_LOCATION 578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}; 588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 59103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const char gZoneStringsTag[] = "zoneStrings"; 60103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const char gGmtFormatTag[]= "gmtFormat"; 61103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const char gGmtZeroFormatTag[] = "gmtZeroFormat"; 62103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const char gHourFormatTag[]= "hourFormat"; 63103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 64103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const UChar TZID_GMT[] = {0x0045, 0x0074, 0x0063, 0x002F, 0x0047, 0x004D, 0x0054, 0}; // Etc/GMT 658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const UChar UNKNOWN_ZONE_ID[] = { 668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 0x0045, 0x0074, 0x0063, 0x002F, 0x0055, 0x006E, 0x006B, 0x006E, 0x006F, 0x0077, 0x006E, 0}; // Etc/Unknown 678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const UChar UNKNOWN_SHORT_ZONE_ID[] = {0x0075, 0x006E, 0x006B, 0}; // unk 688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const UChar UNKNOWN_LOCATION[] = {0x0055, 0x006E, 0x006B, 0x006E, 0x006F, 0x0077, 0x006E, 0}; // Unknown 69103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 70103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const UChar DEFAULT_GMT_PATTERN[] = {0x0047, 0x004D, 0x0054, 0x007B, 0x0030, 0x007D, 0}; // GMT{0} 7154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//static const UChar DEFAULT_GMT_ZERO[] = {0x0047, 0x004D, 0x0054, 0}; // GMT 728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const UChar DEFAULT_GMT_POSITIVE_HM[] = {0x002B, 0x0048, 0x003A, 0x006D, 0x006D, 0}; // +H:mm 738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const UChar DEFAULT_GMT_POSITIVE_HMS[] = {0x002B, 0x0048, 0x003A, 0x006D, 0x006D, 0x003A, 0x0073, 0x0073, 0}; // +H:mm:ss 748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const UChar DEFAULT_GMT_NEGATIVE_HM[] = {0x002D, 0x0048, 0x003A, 0x006D, 0x006D, 0}; // -H:mm 758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const UChar DEFAULT_GMT_NEGATIVE_HMS[] = {0x002D, 0x0048, 0x003A, 0x006D, 0x006D, 0x003A, 0x0073, 0x0073, 0}; // -H:mm:ss 768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const UChar DEFAULT_GMT_POSITIVE_H[] = {0x002B, 0x0048, 0}; // +H 778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const UChar DEFAULT_GMT_NEGATIVE_H[] = {0x002D, 0x0048, 0}; // -H 78103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 79103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const UChar32 DEFAULT_GMT_DIGITS[] = { 80103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 81103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 0x0035, 0x0036, 0x0037, 0x0038, 0x0039 82103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}; 83103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 84103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const UChar DEFAULT_GMT_OFFSET_SEP = 0x003A; // ':' 85103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 86103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const UChar ARG0[] = {0x007B, 0x0030, 0x007D}; // "{0}" 878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const int32_t ARG0_LEN = 3; 88103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 89103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const UChar DEFAULT_GMT_OFFSET_MINUTE_PATTERN[] = {0x006D, 0x006D, 0}; // "mm" 90103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const UChar DEFAULT_GMT_OFFSET_SECOND_PATTERN[] = {0x0073, 0x0073, 0}; // "ss" 91103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 92103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const UChar ALT_GMT_STRINGS[][4] = { 93103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius {0x0047, 0x004D, 0x0054, 0}, // GMT 94103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius {0x0055, 0x0054, 0x0043, 0}, // UTC 95103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius {0x0055, 0x0054, 0, 0}, // UT 96103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius {0, 0, 0, 0} 97103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}; 98103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 99103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Order of GMT offset pattern parsing, *_HMS must be evaluated first 100103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// because *_HM is most likely a substring of *_HMS 101103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const int32_t PARSE_GMT_OFFSET_TYPES[] = { 102103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UTZFMT_PAT_POSITIVE_HMS, 103103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UTZFMT_PAT_NEGATIVE_HMS, 104103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UTZFMT_PAT_POSITIVE_HM, 105103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UTZFMT_PAT_NEGATIVE_HM, 1068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UTZFMT_PAT_POSITIVE_H, 1078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UTZFMT_PAT_NEGATIVE_H, 108103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius -1 109103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}; 110103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 111103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const UChar SINGLEQUOTE = 0x0027; 112103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const UChar PLUS = 0x002B; 113103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const UChar MINUS = 0x002D; 114103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const UChar ISO8601_UTC = 0x005A; // 'Z' 115103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const UChar ISO8601_SEP = 0x003A; // ':' 116103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 117103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const int32_t MILLIS_PER_HOUR = 60 * 60 * 1000; 118103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const int32_t MILLIS_PER_MINUTE = 60 * 1000; 119103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const int32_t MILLIS_PER_SECOND = 1000; 120103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 121103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Maximum offset (exclusive) in millisecond supported by offset formats 122103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic int32_t MAX_OFFSET = 24 * MILLIS_PER_HOUR; 123103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 124103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Maximum values for GMT offset fields 125103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const int32_t MAX_OFFSET_HOUR = 23; 126103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const int32_t MAX_OFFSET_MINUTE = 59; 127103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const int32_t MAX_OFFSET_SECOND = 59; 128103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 129103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const int32_t UNKNOWN_OFFSET = 0x7FFFFFFF; 130103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic const int32_t ALL_SIMPLE_NAME_TYPES = UTZNM_LONG_STANDARD | UTZNM_LONG_DAYLIGHT | UTZNM_SHORT_STANDARD | UTZNM_SHORT_DAYLIGHT | UTZNM_EXEMPLAR_LOCATION; 132103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic const int32_t ALL_GENERIC_NAME_TYPES = UTZGNM_LOCATION | UTZGNM_LONG | UTZGNM_SHORT; 133103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 134103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#define DIGIT_VAL(c) (0x0030 <= (c) && (c) <= 0x0039 ? (c) - 0x0030 : -1) 135103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#define MAX_OFFSET_DIGITS 6 136103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius// Time Zone ID/Short ID trie 1388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic TextTrieMap *gZoneIdTrie = NULL; 13959d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic icu::UInitOnce gZoneIdTrieInitOnce = U_INITONCE_INITIALIZER; 1408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic TextTrieMap *gShortZoneIdTrie = NULL; 14259d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic icu::UInitOnce gShortZoneIdTrieInitOnce = U_INITONCE_INITIALIZER; 1438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic UMutex gLock = U_MUTEX_INITIALIZER; 1458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusU_CDECL_BEGIN 1478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius/** 1488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius * Cleanup callback func 1498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius */ 1508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusstatic UBool U_CALLCONV tzfmt_cleanup(void) 1518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius{ 1528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (gZoneIdTrie != NULL) { 1538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius delete gZoneIdTrie; 1548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius gZoneIdTrie = NULL; 15659d709d503bab6e2b61931737e662dd293b40578ccornelius gZoneIdTrieInitOnce.reset(); 1578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (gShortZoneIdTrie != NULL) { 1598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius delete gShortZoneIdTrie; 1608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius gShortZoneIdTrie = NULL; 16259d709d503bab6e2b61931737e662dd293b40578ccornelius gShortZoneIdTrieInitOnce.reset(); 1638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return TRUE; 1658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 1668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusU_CDECL_END 167103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 168103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// ------------------------------------------------------------------ 169103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// GMTOffsetField 170103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// 171103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// This class represents a localized GMT offset pattern 172103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// item and used by TimeZoneFormat 173103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// ------------------------------------------------------------------ 174103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusclass GMTOffsetField : public UMemory { 175b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehopublic: 176103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius enum FieldType { 177103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius TEXT = 0, 178103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius HOUR = 1, 179103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius MINUTE = 2, 180103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius SECOND = 4 181103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius }; 182b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 183103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius virtual ~GMTOffsetField(); 184b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 185103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius static GMTOffsetField* createText(const UnicodeString& text, UErrorCode& status); 186103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius static GMTOffsetField* createTimeField(FieldType type, uint8_t width, UErrorCode& status); 187103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius static UBool isValid(FieldType type, int32_t width); 188103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius static FieldType getTypeByLetter(UChar ch); 189b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 190103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius FieldType getType() const; 191103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius uint8_t getWidth() const; 192103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UChar* getPatternText(void) const; 193b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 194b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoprivate: 195103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar* fText; 196103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius FieldType fType; 197103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius uint8_t fWidth; 198b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 199103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius GMTOffsetField(); 200103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius}; 201b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 202103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusGMTOffsetField::GMTOffsetField() 203103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius: fText(NULL), fType(TEXT), fWidth(0) { 204103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 205b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 206103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusGMTOffsetField::~GMTOffsetField() { 207103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (fText) { 208103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius uprv_free(fText); 209103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 210103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 211b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 212103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusGMTOffsetField* 213103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusGMTOffsetField::createText(const UnicodeString& text, UErrorCode& status) { 214103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 215103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return NULL; 216103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 217103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius GMTOffsetField* result = new GMTOffsetField(); 218103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (result == NULL) { 219103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius status = U_MEMORY_ALLOCATION_ERROR; 220103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return NULL; 221103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 222103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 223103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t len = text.length(); 224103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result->fText = (UChar*)uprv_malloc((len + 1) * sizeof(UChar)); 225103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (result->fText == NULL) { 226103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius status = U_MEMORY_ALLOCATION_ERROR; 227103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete result; 228103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return NULL; 229103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 230103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius u_strncpy(result->fText, text.getBuffer(), len); 231103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result->fText[len] = 0; 232103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result->fType = TEXT; 233103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 234103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return result; 235103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 236103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 237103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusGMTOffsetField* 238103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusGMTOffsetField::createTimeField(FieldType type, uint8_t width, UErrorCode& status) { 239103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(type != TEXT); 240103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 241103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return NULL; 242103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 243103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius GMTOffsetField* result = new GMTOffsetField(); 244103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (result == NULL) { 245103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius status = U_MEMORY_ALLOCATION_ERROR; 246103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return NULL; 247103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 248103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 249103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result->fType = type; 250103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result->fWidth = width; 251103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 252103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return result; 253103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 254103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 255103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUBool 256103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusGMTOffsetField::isValid(FieldType type, int32_t width) { 257103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius switch (type) { 258103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case HOUR: 259103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return (width == 1 || width == 2); 260103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case MINUTE: 261103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case SECOND: 262103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return (width == 2); 263103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius default: 264103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(FALSE); 265103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 266103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return (width > 0); 267103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 268103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 269103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusGMTOffsetField::FieldType 270103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusGMTOffsetField::getTypeByLetter(UChar ch) { 271103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (ch == 0x0048 /* H */) { 272103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return HOUR; 273103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else if (ch == 0x006D /* m */) { 274103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return MINUTE; 275103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else if (ch == 0x0073 /* s */) { 276103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return SECOND; 277103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 278103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return TEXT; 279103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 280103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 281103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusinline GMTOffsetField::FieldType 282103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusGMTOffsetField::getType() const { 283103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return fType; 284103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 285103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 286103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusinline uint8_t 287103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusGMTOffsetField::getWidth() const { 288103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return fWidth; 289103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 290103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 291103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusinline const UChar* 292103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusGMTOffsetField::getPatternText(void) const { 293103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return fText; 294103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 295103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 296103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 297103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CDECL_BEGIN 298103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusstatic void U_CALLCONV 299103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusdeleteGMTOffsetField(void *obj) { 300103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete static_cast<GMTOffsetField *>(obj); 301103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 302103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusU_CDECL_END 303103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 304103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 305103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// ------------------------------------------------------------------ 306103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// TimeZoneFormat 307103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// ------------------------------------------------------------------ 308103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeZoneFormat) 309103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 310103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::TimeZoneFormat(const Locale& locale, UErrorCode& status) 31154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius: fLocale(locale), fTimeZoneNames(NULL), fTimeZoneGenericNames(NULL), fDefParseOptionFlags(0) { 312103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 3138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) { 314103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTOffsetPatternItems[i] = NULL; 315103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 316b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 317b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho const char* region = fLocale.getCountry(); 318b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho int32_t regionLen = uprv_strlen(region); 319b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho if (regionLen == 0) { 320b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho char loc[ULOC_FULLNAME_CAPACITY]; 321b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho uloc_addLikelySubtags(fLocale.getName(), loc, sizeof(loc), &status); 322b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 323103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius regionLen = uloc_getCountry(loc, fTargetRegion, sizeof(fTargetRegion), &status); 324103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_SUCCESS(status)) { 325103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fTargetRegion[regionLen] = 0; 326103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 327103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return; 328103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 329103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else if (regionLen < (int32_t)sizeof(fTargetRegion)) { 330103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius uprv_strcpy(fTargetRegion, region); 331103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 332103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fTargetRegion[0] = 0; 333103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 334103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 335103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fTimeZoneNames = TimeZoneNames::createInstance(locale, status); 336103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // fTimeZoneGenericNames is lazily instantiated 3378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (U_FAILURE(status)) { 3388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return; 3398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 340103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 341103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UChar* gmtPattern = NULL; 342103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UChar* hourFormats = NULL; 343103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 344103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UResourceBundle *zoneBundle = ures_open(U_ICUDATA_ZONE, locale.getName(), &status); 345103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UResourceBundle *zoneStringsArray = ures_getByKeyWithFallback(zoneBundle, gZoneStringsTag, NULL, &status); 346103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_SUCCESS(status)) { 347103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UChar* resStr; 348103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t len; 349103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius resStr = ures_getStringByKeyWithFallback(zoneStringsArray, gGmtFormatTag, &len, &status); 350103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (len > 0) { 351103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius gmtPattern = resStr; 352103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 353103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius resStr = ures_getStringByKeyWithFallback(zoneStringsArray, gGmtZeroFormatTag, &len, &status); 354103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (len > 0) { 355103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTZeroFormat.setTo(TRUE, resStr, len); 356103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 357103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius resStr = ures_getStringByKeyWithFallback(zoneStringsArray, gHourFormatTag, &len, &status); 358103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (len > 0) { 359103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius hourFormats = resStr; 360103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 361103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ures_close(zoneStringsArray); 362103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ures_close(zoneBundle); 363103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 364103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 365103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (gmtPattern == NULL) { 366103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius gmtPattern = DEFAULT_GMT_PATTERN; 367103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 368103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius initGMTPattern(UnicodeString(gmtPattern, -1), status); 369103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 3708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UBool useDefaultOffsetPatterns = TRUE; 371103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (hourFormats) { 372103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar *sep = u_strchr(hourFormats, (UChar)0x003B /* ';' */); 373103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (sep != NULL) { 3748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UErrorCode tmpStatus = U_ZERO_ERROR; 375103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTOffsetPatterns[UTZFMT_PAT_POSITIVE_HM].setTo(FALSE, hourFormats, (int32_t)(sep - hourFormats)); 376103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTOffsetPatterns[UTZFMT_PAT_NEGATIVE_HM].setTo(TRUE, sep + 1, -1); 3778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius expandOffsetPattern(fGMTOffsetPatterns[UTZFMT_PAT_POSITIVE_HM], fGMTOffsetPatterns[UTZFMT_PAT_POSITIVE_HMS], tmpStatus); 3788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius expandOffsetPattern(fGMTOffsetPatterns[UTZFMT_PAT_NEGATIVE_HM], fGMTOffsetPatterns[UTZFMT_PAT_NEGATIVE_HMS], tmpStatus); 3798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius truncateOffsetPattern(fGMTOffsetPatterns[UTZFMT_PAT_POSITIVE_HM], fGMTOffsetPatterns[UTZFMT_PAT_POSITIVE_H], tmpStatus); 3808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius truncateOffsetPattern(fGMTOffsetPatterns[UTZFMT_PAT_NEGATIVE_HM], fGMTOffsetPatterns[UTZFMT_PAT_NEGATIVE_H], tmpStatus); 3818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (U_SUCCESS(tmpStatus)) { 3828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius useDefaultOffsetPatterns = FALSE; 3838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 384103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 385103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 3868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (useDefaultOffsetPatterns) { 3878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius fGMTOffsetPatterns[UTZFMT_PAT_POSITIVE_H].setTo(TRUE, DEFAULT_GMT_POSITIVE_H, -1); 388103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTOffsetPatterns[UTZFMT_PAT_POSITIVE_HM].setTo(TRUE, DEFAULT_GMT_POSITIVE_HM, -1); 389103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTOffsetPatterns[UTZFMT_PAT_POSITIVE_HMS].setTo(TRUE, DEFAULT_GMT_POSITIVE_HMS, -1); 3908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius fGMTOffsetPatterns[UTZFMT_PAT_NEGATIVE_H].setTo(TRUE, DEFAULT_GMT_NEGATIVE_H, -1); 391103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTOffsetPatterns[UTZFMT_PAT_NEGATIVE_HM].setTo(TRUE, DEFAULT_GMT_NEGATIVE_HM, -1); 392103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTOffsetPatterns[UTZFMT_PAT_NEGATIVE_HMS].setTo(TRUE, DEFAULT_GMT_NEGATIVE_HMS, -1); 393103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 394103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius initGMTOffsetPatterns(status); 395103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 396103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius NumberingSystem* ns = NumberingSystem::createInstance(locale, status); 397103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool useDefDigits = TRUE; 398103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (ns && !ns->isAlgorithmic()) { 399103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UnicodeString digits = ns->getDescription(); 400103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius useDefDigits = !toCodePoints(digits, fGMTOffsetDigits, 10); 401103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 402103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (useDefDigits) { 403103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius uprv_memcpy(fGMTOffsetDigits, DEFAULT_GMT_DIGITS, sizeof(UChar32) * 10); 404103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 405103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete ns; 406103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 407103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 408103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::TimeZoneFormat(const TimeZoneFormat& other) 409103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius: Format(other), fTimeZoneNames(NULL), fTimeZoneGenericNames(NULL) { 410103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 4118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) { 412103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTOffsetPatternItems[i] = NULL; 413103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 414103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *this = other; 415103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 416103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 417103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 418103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::~TimeZoneFormat() { 419103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete fTimeZoneNames; 420103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete fTimeZoneGenericNames; 4218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) { 422103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete fGMTOffsetPatternItems[i]; 423103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 424103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 425103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 426103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat& 427103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::operator=(const TimeZoneFormat& other) { 428103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (this == &other) { 429103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return *this; 430103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 431103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 432103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete fTimeZoneNames; 433103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete fTimeZoneGenericNames; 434103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fTimeZoneGenericNames = NULL; 435103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 436103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fLocale = other.fLocale; 437103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius uprv_memcpy(fTargetRegion, other.fTargetRegion, sizeof(fTargetRegion)); 438103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 439103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fTimeZoneNames = other.fTimeZoneNames->clone(); 440103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (other.fTimeZoneGenericNames) { 44159d709d503bab6e2b61931737e662dd293b40578ccornelius // TODO: this test has dubious thread safety. 442103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fTimeZoneGenericNames = other.fTimeZoneGenericNames->clone(); 443103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 444103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 445103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTPattern = other.fGMTPattern; 446103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTPatternPrefix = other.fGMTPatternPrefix; 447103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTPatternSuffix = other.fGMTPatternSuffix; 448103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 449103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UErrorCode status = U_ZERO_ERROR; 4508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) { 451103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTOffsetPatterns[i] = other.fGMTOffsetPatterns[i]; 452103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete fGMTOffsetPatternItems[i]; 453103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 454103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius initGMTOffsetPatterns(status); 455103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(U_SUCCESS(status)); 456103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 457103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTZeroFormat = other.fGMTZeroFormat; 458103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 459103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius uprv_memcpy(fGMTOffsetDigits, other.fGMTOffsetDigits, sizeof(fGMTOffsetDigits)); 460103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 461103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fDefParseOptionFlags = other.fDefParseOptionFlags; 462103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 463103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return *this; 464103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 465103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 466103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 467103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUBool 468103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::operator==(const Format& other) const { 469103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius TimeZoneFormat* tzfmt = (TimeZoneFormat*)&other; 470103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 471103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool isEqual = 472103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fLocale == tzfmt->fLocale 473103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius && fGMTPattern == tzfmt->fGMTPattern 474103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius && fGMTZeroFormat == tzfmt->fGMTZeroFormat 475103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius && *fTimeZoneNames == *tzfmt->fTimeZoneNames; 476103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 4778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius for (int32_t i = 0; i < UTZFMT_PAT_COUNT && isEqual; i++) { 478103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius isEqual = fGMTOffsetPatterns[i] == tzfmt->fGMTOffsetPatterns[i]; 479103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 480103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t i = 0; i < 10 && isEqual; i++) { 481103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius isEqual = fGMTOffsetDigits[i] == tzfmt->fGMTOffsetDigits[i]; 482103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 483103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // TODO 484103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Check fTimeZoneGenericNames. For now, 485103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // if fTimeZoneNames is same, fTimeZoneGenericNames should 486103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // be also equivalent. 487103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return isEqual; 488103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 489103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 490103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusFormat* 491103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::clone() const { 492103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return new TimeZoneFormat(*this); 493103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 494103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 495103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat* U_EXPORT2 496103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::createInstance(const Locale& locale, UErrorCode& status) { 497103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius TimeZoneFormat* tzfmt = new TimeZoneFormat(locale, status); 498103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_SUCCESS(status)) { 499103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return tzfmt; 500103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 501103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete tzfmt; 502103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return NULL; 503103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 504103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 505103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// ------------------------------------------------------------------ 506103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Setter and Getter 507103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 508103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusconst TimeZoneNames* 509103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::getTimeZoneNames() const { 510103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return (const TimeZoneNames*)fTimeZoneNames; 511103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 512103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 513103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid 514103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::adoptTimeZoneNames(TimeZoneNames *tznames) { 515103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete fTimeZoneNames; 516103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fTimeZoneNames = tznames; 517103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 518103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // TODO - We should also update fTimeZoneGenericNames 519103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 520103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 521103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid 522103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::setTimeZoneNames(const TimeZoneNames &tznames) { 523103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete fTimeZoneNames; 524103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fTimeZoneNames = tznames.clone(); 525103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 526103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // TODO - We should also update fTimeZoneGenericNames 527103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 528103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 529103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid 53054dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusTimeZoneFormat::setDefaultParseOptions(uint32_t flags) { 531103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fDefParseOptionFlags = flags; 532103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 533103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 53454dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusuint32_t 535103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::getDefaultParseOptions(void) const { 536103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return fDefParseOptionFlags; 537103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 538103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 539103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 540103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 541103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::getGMTPattern(UnicodeString& pattern) const { 542103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return pattern.setTo(fGMTPattern); 543103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 544103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 545103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid 546103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::setGMTPattern(const UnicodeString& pattern, UErrorCode& status) { 547103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius initGMTPattern(pattern, status); 548103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 549103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 550103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 551103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::getGMTOffsetPattern(UTimeZoneFormatGMTOffsetPatternType type, UnicodeString& pattern) const { 552103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return pattern.setTo(fGMTOffsetPatterns[type]); 553103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 554103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 555103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid 556103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::setGMTOffsetPattern(UTimeZoneFormatGMTOffsetPatternType type, const UnicodeString& pattern, UErrorCode& status) { 557103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 558103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return; 559103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 560103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (pattern == fGMTOffsetPatterns[type]) { 561103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // No need to reset 562103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return; 563103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 564103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 5658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius OffsetFields required = FIELDS_HM; 5668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius switch (type) { 5678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_PAT_POSITIVE_H: 5688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_PAT_NEGATIVE_H: 5698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius required = FIELDS_H; 5708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 5718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_PAT_POSITIVE_HM: 5728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_PAT_NEGATIVE_HM: 5738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius required = FIELDS_HM; 5748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 5758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_PAT_POSITIVE_HMS: 5768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_PAT_NEGATIVE_HMS: 5778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius required = FIELDS_HMS; 5788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 5798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius default: 5808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius U_ASSERT(FALSE); 5818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 5828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 583103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 584103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UVector* patternItems = parseOffsetPattern(pattern, required, status); 585103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (patternItems == NULL) { 586103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return; 587103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 588103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 589103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTOffsetPatterns[type].setTo(pattern); 590103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete fGMTOffsetPatternItems[type]; 591103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTOffsetPatternItems[type] = patternItems; 5928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius checkAbuttingHoursAndMinutes(); 593103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 594103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 595103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 596103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::getGMTOffsetDigits(UnicodeString& digits) const { 597103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius digits.remove(); 598103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t i = 0; i < 10; i++) { 599103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius digits.append(fGMTOffsetDigits[i]); 600103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 601103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return digits; 602103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 603103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 604103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid 605103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::setGMTOffsetDigits(const UnicodeString& digits, UErrorCode& status) { 606103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 607103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return; 608103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 609103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar32 digitArray[10]; 610103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (!toCodePoints(digits, digitArray, 10)) { 611103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius status = U_ILLEGAL_ARGUMENT_ERROR; 612103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return; 613103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 614103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius uprv_memcpy(fGMTOffsetDigits, digitArray, sizeof(UChar32)*10); 615103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 616103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 617103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 618103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::getGMTZeroFormat(UnicodeString& gmtZeroFormat) const { 619103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return gmtZeroFormat.setTo(fGMTZeroFormat); 620103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 621103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 622103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid 623103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::setGMTZeroFormat(const UnicodeString& gmtZeroFormat, UErrorCode& status) { 624103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_SUCCESS(status)) { 625103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (gmtZeroFormat.isEmpty()) { 626103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius status = U_ILLEGAL_ARGUMENT_ERROR; 627103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else if (gmtZeroFormat != fGMTZeroFormat) { 628103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTZeroFormat.setTo(gmtZeroFormat); 629103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 630103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 631103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 632103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 633103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// ------------------------------------------------------------------ 634103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Format and Parse 635103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 636103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 637103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::format(UTimeZoneFormatStyle style, const TimeZone& tz, UDate date, 638103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UnicodeString& name, UTimeZoneFormatTimeType* timeType /* = NULL */) const { 639103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (timeType) { 640103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *timeType = UTZFMT_TIME_TYPE_UNKNOWN; 641103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 64259d709d503bab6e2b61931737e662dd293b40578ccornelius 64359d709d503bab6e2b61931737e662dd293b40578ccornelius UBool noOffsetFormatFallback = FALSE; 64459d709d503bab6e2b61931737e662dd293b40578ccornelius 645103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius switch (style) { 646103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_STYLE_GENERIC_LOCATION: 647103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius formatGeneric(tz, UTZGNM_LOCATION, date, name); 648103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 649103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_STYLE_GENERIC_LONG: 650103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius formatGeneric(tz, UTZGNM_LONG, date, name); 651103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 652103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_STYLE_GENERIC_SHORT: 653103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius formatGeneric(tz, UTZGNM_SHORT, date, name); 654103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 655103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_STYLE_SPECIFIC_LONG: 656103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius formatSpecific(tz, UTZNM_LONG_STANDARD, UTZNM_LONG_DAYLIGHT, date, name, timeType); 657103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 658103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_STYLE_SPECIFIC_SHORT: 659103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius formatSpecific(tz, UTZNM_SHORT_STANDARD, UTZNM_SHORT_DAYLIGHT, date, name, timeType); 660103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 66159d709d503bab6e2b61931737e662dd293b40578ccornelius 66259d709d503bab6e2b61931737e662dd293b40578ccornelius case UTZFMT_STYLE_ZONE_ID: 66359d709d503bab6e2b61931737e662dd293b40578ccornelius tz.getID(name); 66459d709d503bab6e2b61931737e662dd293b40578ccornelius noOffsetFormatFallback = TRUE; 66559d709d503bab6e2b61931737e662dd293b40578ccornelius break; 66659d709d503bab6e2b61931737e662dd293b40578ccornelius case UTZFMT_STYLE_ZONE_ID_SHORT: 66759d709d503bab6e2b61931737e662dd293b40578ccornelius { 66859d709d503bab6e2b61931737e662dd293b40578ccornelius const UChar* shortID = ZoneMeta::getShortID(tz); 66959d709d503bab6e2b61931737e662dd293b40578ccornelius if (shortID == NULL) { 67059d709d503bab6e2b61931737e662dd293b40578ccornelius shortID = UNKNOWN_SHORT_ZONE_ID; 67159d709d503bab6e2b61931737e662dd293b40578ccornelius } 67259d709d503bab6e2b61931737e662dd293b40578ccornelius name.setTo(shortID, -1); 67359d709d503bab6e2b61931737e662dd293b40578ccornelius } 67459d709d503bab6e2b61931737e662dd293b40578ccornelius noOffsetFormatFallback = TRUE; 67559d709d503bab6e2b61931737e662dd293b40578ccornelius break; 67659d709d503bab6e2b61931737e662dd293b40578ccornelius 67759d709d503bab6e2b61931737e662dd293b40578ccornelius case UTZFMT_STYLE_EXEMPLAR_LOCATION: 67859d709d503bab6e2b61931737e662dd293b40578ccornelius formatExemplarLocation(tz, name); 67959d709d503bab6e2b61931737e662dd293b40578ccornelius noOffsetFormatFallback = TRUE; 68059d709d503bab6e2b61931737e662dd293b40578ccornelius break; 68159d709d503bab6e2b61931737e662dd293b40578ccornelius 6828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius default: 683103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // will be handled below 684103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 685103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 686103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 68759d709d503bab6e2b61931737e662dd293b40578ccornelius if (name.isEmpty() && !noOffsetFormatFallback) { 688103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UErrorCode status = U_ZERO_ERROR; 689103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t rawOffset, dstOffset; 690103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius tz.getOffset(date, FALSE, rawOffset, dstOffset, status); 6918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t offset = rawOffset + dstOffset; 692103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_SUCCESS(status)) { 693103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius switch (style) { 6948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_GENERIC_LOCATION: 6958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_GENERIC_LONG: 6968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_SPECIFIC_LONG: 6978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_LOCALIZED_GMT: 6988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius formatOffsetLocalizedGMT(offset, name, status); 6998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 7008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 7018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_GENERIC_SHORT: 7028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_SPECIFIC_SHORT: 7038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_LOCALIZED_GMT_SHORT: 7048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius formatOffsetShortLocalizedGMT(offset, name, status); 705103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 7068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 7078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_BASIC_SHORT: 7088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius formatOffsetISO8601Basic(offset, TRUE, TRUE, TRUE, name, status); 709103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 7108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 7118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_BASIC_LOCAL_SHORT: 7128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius formatOffsetISO8601Basic(offset, FALSE, TRUE, TRUE, name, status); 7138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 7148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 7158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_BASIC_FIXED: 7168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius formatOffsetISO8601Basic(offset, TRUE, FALSE, TRUE, name, status); 7178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 7188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 7198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_BASIC_LOCAL_FIXED: 7208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius formatOffsetISO8601Basic(offset, FALSE, FALSE, TRUE, name, status); 7218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 7228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 7238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_EXTENDED_FIXED: 7248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius formatOffsetISO8601Extended(offset, TRUE, FALSE, TRUE, name, status); 7258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 7268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 7278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FIXED: 7288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius formatOffsetISO8601Extended(offset, FALSE, FALSE, TRUE, name, status); 7298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 7308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 7318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_BASIC_FULL: 7328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius formatOffsetISO8601Basic(offset, TRUE, FALSE, FALSE, name, status); 7338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 7348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 7358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL: 7368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius formatOffsetISO8601Basic(offset, FALSE, FALSE, FALSE, name, status); 7378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 7388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 7398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_EXTENDED_FULL: 7408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius formatOffsetISO8601Extended(offset, TRUE, FALSE, FALSE, name, status); 7418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 7428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 7438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL: 7448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius formatOffsetISO8601Extended(offset, FALSE, FALSE, FALSE, name, status); 7458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 7468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 74759d709d503bab6e2b61931737e662dd293b40578ccornelius default: 74859d709d503bab6e2b61931737e662dd293b40578ccornelius // UTZFMT_STYLE_ZONE_ID, UTZFMT_STYLE_ZONE_ID_SHORT, UTZFMT_STYLE_EXEMPLAR_LOCATION 74959d709d503bab6e2b61931737e662dd293b40578ccornelius break; 750103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 75159d709d503bab6e2b61931737e662dd293b40578ccornelius 752103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (timeType) { 753103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *timeType = (dstOffset != 0) ? UTZFMT_TIME_TYPE_DAYLIGHT : UTZFMT_TIME_TYPE_STANDARD; 754103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 755103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 756103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 757103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 758103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return name; 759103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 760103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 761103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 762103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::format(const Formattable& obj, UnicodeString& appendTo, 763103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius FieldPosition& pos, UErrorCode& status) const { 764103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 765103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return appendTo; 766103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 767103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UDate date = Calendar::getNow(); 768103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (obj.getType() == Formattable::kObject) { 769103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UObject* formatObj = obj.getObject(); 770103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const TimeZone* tz = dynamic_cast<const TimeZone*>(formatObj); 771103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (tz == NULL) { 772103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const Calendar* cal = dynamic_cast<const Calendar*>(formatObj); 773103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (cal != NULL) { 774103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius tz = &cal->getTimeZone(); 775103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius date = cal->getTime(status); 776103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 777103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 778103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (tz != NULL) { 779103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t rawOffset, dstOffset; 780103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius tz->getOffset(date, FALSE, rawOffset, dstOffset, status); 781103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UnicodeString result; 782103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius formatOffsetLocalizedGMT(rawOffset + dstOffset, result, status); 783103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_SUCCESS(status)) { 784103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius appendTo.append(result); 785103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (pos.getField() == UDAT_TIMEZONE_FIELD) { 786103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setBeginIndex(0); 787103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setEndIndex(result.length()); 788103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 789103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 790103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 791103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 792103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return appendTo; 793103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 794103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 795103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZone* 796103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::parse(UTimeZoneFormatStyle style, const UnicodeString& text, ParsePosition& pos, 797103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UTimeZoneFormatTimeType* timeType /*= NULL*/) const { 798103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return parse(style, text, pos, getDefaultParseOptions(), timeType); 799103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 800103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 801103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZone* 802103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::parse(UTimeZoneFormatStyle style, const UnicodeString& text, ParsePosition& pos, 803103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t parseOptions, UTimeZoneFormatTimeType* timeType /* = NULL */) const { 804103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (timeType) { 805103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *timeType = UTZFMT_TIME_TYPE_UNKNOWN; 806103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 807103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 808103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t startIdx = pos.getIndex(); 809103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t maxPos = text.length(); 810103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t offset; 811103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 8128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Styles using localized GMT format as fallback 8138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UBool fallbackLocalizedGMT = 8148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius (style == UTZFMT_STYLE_SPECIFIC_LONG || style == UTZFMT_STYLE_GENERIC_LONG || style == UTZFMT_STYLE_GENERIC_LOCATION); 8158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UBool fallbackShortLocalizedGMT = 8168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius (style == UTZFMT_STYLE_SPECIFIC_SHORT || style == UTZFMT_STYLE_GENERIC_SHORT); 817103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 8188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t evaluated = 0; // bit flags representing already evaluated styles 819103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ParsePosition tmpPos(startIdx); 820103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 821103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t parsedOffset = UNKNOWN_OFFSET; // stores successfully parsed offset for later use 822103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t parsedPos = -1; // stores successfully parsed offset position for later use 823103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 824103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Try localized GMT format first if necessary 8258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (fallbackLocalizedGMT || fallbackShortLocalizedGMT) { 826103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool hasDigitOffset = FALSE; 8278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offset = parseOffsetLocalizedGMT(text, tmpPos, fallbackShortLocalizedGMT, &hasDigitOffset); 828103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (tmpPos.getErrorIndex() == -1) { 829103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Even when the input text was successfully parsed as a localized GMT format text, 830103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // we may still need to evaluate the specified style if - 831103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // 1) GMT zero format was used, and 832103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // 2) The input text was not completely processed 833103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (tmpPos.getIndex() == maxPos || hasDigitOffset) { 834103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(tmpPos.getIndex()); 835103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return createTimeZoneForOffset(offset); 836103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 837103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedOffset = offset; 838103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedPos = tmpPos.getIndex(); 839103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 8408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Note: For now, no distinction between long/short localized GMT format in the parser. 8418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // This might be changed in future. 8428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // evaluated |= (fallbackLocalizedGMT ? STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT] : STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT_SHORT]); 8438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius evaluated |= STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT] | STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT_SHORT]; 844103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 845103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 846103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UErrorCode status = U_ZERO_ERROR; 847103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UnicodeString tzID; 848103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 849103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Try the specified style 850103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius switch (style) { 8518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_LOCALIZED_GMT: 852103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { 8538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setIndex(startIdx); 8548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setErrorIndex(-1); 8558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 8568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offset = parseOffsetLocalizedGMT(text, tmpPos); 857103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (tmpPos.getErrorIndex() == -1) { 858103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(tmpPos.getIndex()); 859103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return createTimeZoneForOffset(offset); 860103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 861103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 8628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Note: For now, no distinction between long/short localized GMT format in the parser. 8638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // This might be changed in future. 8648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius evaluated |= STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT_SHORT]; 8658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 8668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 8678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 8688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_LOCALIZED_GMT_SHORT: 869103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { 8708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setIndex(startIdx); 8718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setErrorIndex(-1); 8728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 8738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offset = parseOffsetShortLocalizedGMT(text, tmpPos); 874103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (tmpPos.getErrorIndex() == -1) { 875103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(tmpPos.getIndex()); 876103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return createTimeZoneForOffset(offset); 877103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 878103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 8798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Note: For now, no distinction between long/short localized GMT format in the parser. 8808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // This might be changed in future. 8818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius evaluated |= STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT]; 8828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 8838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 8848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 8858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_BASIC_SHORT: 8868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_BASIC_FIXED: 8878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_BASIC_FULL: 8888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_EXTENDED_FIXED: 8898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_EXTENDED_FULL: 890103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { 8918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setIndex(startIdx); 8928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setErrorIndex(-1); 8938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 894103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius offset = parseOffsetISO8601(text, tmpPos); 895103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (tmpPos.getErrorIndex() == -1) { 896103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(tmpPos.getIndex()); 897103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return createTimeZoneForOffset(offset); 898103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 8998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 9008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 9018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 9028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 9038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_BASIC_LOCAL_SHORT: 9048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_BASIC_LOCAL_FIXED: 9058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL: 9068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FIXED: 9078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL: 9088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius { 9098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setIndex(startIdx); 9108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setErrorIndex(-1); 9118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 9128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Exclude the case of UTC Indicator "Z" here 9138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UBool hasDigitOffset = FALSE; 9148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offset = parseOffsetISO8601(text, tmpPos, FALSE, &hasDigitOffset); 9158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tmpPos.getErrorIndex() == -1 && hasDigitOffset) { 9168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius pos.setIndex(tmpPos.getIndex()); 9178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return createTimeZoneForOffset(offset); 9188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 9198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 9208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 921103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 922103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 923103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_STYLE_SPECIFIC_LONG: 924103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_STYLE_SPECIFIC_SHORT: 925103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { 926103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Specific styles 927103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t nameTypes = 0; 928103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (style == UTZFMT_STYLE_SPECIFIC_LONG) { 929103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius nameTypes = (UTZNM_LONG_STANDARD | UTZNM_LONG_DAYLIGHT); 930103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 931103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(style == UTZFMT_STYLE_SPECIFIC_SHORT); 932103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius nameTypes = (UTZNM_SHORT_STANDARD | UTZNM_SHORT_DAYLIGHT); 933103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 934103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius LocalPointer<TimeZoneNames::MatchInfoCollection> specificMatches(fTimeZoneNames->find(text, startIdx, nameTypes, status)); 935103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 936103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setErrorIndex(startIdx); 937103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return NULL; 938103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 939103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (!specificMatches.isNull()) { 940103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t matchIdx = -1; 941103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t matchPos = -1; 942103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t i = 0; i < specificMatches->size(); i++) { 943103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius matchPos = startIdx + specificMatches->getMatchLengthAt(i); 944103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (matchPos > parsedPos) { 945103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius matchIdx = i; 946103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedPos = matchPos; 947103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 948103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 949103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (matchIdx >= 0) { 950103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (timeType) { 951103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *timeType = getTimeType(specificMatches->getNameTypeAt(matchIdx)); 952103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 953103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(matchPos); 954103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius getTimeZoneID(specificMatches.getAlias(), matchIdx, tzID); 955103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(!tzID.isEmpty()); 956103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return TimeZone::createTimeZone(tzID); 957103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 958103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 9598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 960103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 961103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_STYLE_GENERIC_LONG: 962103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_STYLE_GENERIC_SHORT: 963103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_STYLE_GENERIC_LOCATION: 964103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius { 965103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t genericNameTypes = 0; 966103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius switch (style) { 967103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_STYLE_GENERIC_LOCATION: 968103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius genericNameTypes = UTZGNM_LOCATION; 969103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 970103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 971103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_STYLE_GENERIC_LONG: 972103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius genericNameTypes = UTZGNM_LONG | UTZGNM_LOCATION; 973103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 974103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 975103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_STYLE_GENERIC_SHORT: 976103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius genericNameTypes = UTZGNM_SHORT | UTZGNM_LOCATION; 977103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 978103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 979103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius default: 980103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(FALSE); 981103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 982103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 983103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t len = 0; 9848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UTimeZoneFormatTimeType tt = UTZFMT_TIME_TYPE_UNKNOWN; 985103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const TimeZoneGenericNames *gnames = getTimeZoneGenericNames(status); 986103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_SUCCESS(status)) { 9878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius len = gnames->findBestMatch(text, startIdx, genericNameTypes, tzID, tt, status); 988103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 989103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 990103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setErrorIndex(startIdx); 991103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return NULL; 992103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 993103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (len > 0) { 994103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Found a match 995103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (timeType) { 9968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius *timeType = tt; 997103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 998103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(startIdx + len); 999103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(!tzID.isEmpty()); 1000103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return TimeZone::createTimeZone(tzID); 1001103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 10028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 10038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 10048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 10058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ZONE_ID: 10068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius { 10078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setIndex(startIdx); 10088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setErrorIndex(-1); 10098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 10108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parseZoneID(text, tmpPos, tzID); 10118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tmpPos.getErrorIndex() == -1) { 10128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius pos.setIndex(tmpPos.getIndex()); 10138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return TimeZone::createTimeZone(tzID); 10148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 10158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 10168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 10178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_ZONE_ID_SHORT: 10188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius { 10198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setIndex(startIdx); 10208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setErrorIndex(-1); 10218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 10228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parseShortZoneID(text, tmpPos, tzID); 10238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tmpPos.getErrorIndex() == -1) { 10248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius pos.setIndex(tmpPos.getIndex()); 10258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return TimeZone::createTimeZone(tzID); 10268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 10278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 10288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 10298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_STYLE_EXEMPLAR_LOCATION: 10308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius { 10318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setIndex(startIdx); 10328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setErrorIndex(-1); 10338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 10348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parseExemplarLocation(text, tmpPos, tzID); 10358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tmpPos.getErrorIndex() == -1) { 10368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius pos.setIndex(tmpPos.getIndex()); 10378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return TimeZone::createTimeZone(tzID); 10388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 10398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 1040103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1041103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 10428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius evaluated |= STYLE_PARSE_FLAGS[style]; 1043103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1044103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1045103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (parsedPos > startIdx) { 1046103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // When the specified style is one of SPECIFIC_XXX or GENERIC_XXX, we tried to parse the input 1047103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // as localized GMT format earlier. If parsedOffset is positive, it means it was successfully 1048103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // parsed as localized GMT format, but offset digits were not detected (more specifically, GMT 1049103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // zero format). Then, it tried to find a match within the set of display names, but could not 1050103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // find a match. At this point, we can safely assume the input text contains the localized 1051103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // GMT format. 1052103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(parsedOffset != UNKNOWN_OFFSET); 1053103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(parsedPos); 1054103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return createTimeZoneForOffset(parsedOffset); 1055103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1056103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1057103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Failed to parse the input text as the time zone format in the specified style. 1058103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Check the longest match among other styles below. 10598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UnicodeString parsedID; 10608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UTimeZoneFormatTimeType parsedTimeType = UTZFMT_TIME_TYPE_UNKNOWN; 10618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1062103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(parsedPos < 0); 1063103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(parsedOffset == UNKNOWN_OFFSET); 1064103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1065103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // ISO 8601 10668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (parsedPos < maxPos && 10678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ((evaluated & ISO_Z_STYLE_FLAG) == 0 || (evaluated & ISO_LOCAL_STYLE_FLAG) == 0)) { 10688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setIndex(startIdx); 10698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setErrorIndex(-1); 10708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1071103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool hasDigitOffset = FALSE; 1072103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius offset = parseOffsetISO8601(text, tmpPos, FALSE, &hasDigitOffset); 1073103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (tmpPos.getErrorIndex() == -1) { 1074103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (tmpPos.getIndex() == maxPos || hasDigitOffset) { 1075103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(tmpPos.getIndex()); 1076103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return createTimeZoneForOffset(offset); 1077103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1078103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Note: When ISO 8601 format contains offset digits, it should not 10798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // collide with other formats. However, ISO 8601 UTC format "Z" (single letter) 10808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // may collide with other names. In this case, we need to evaluate other names. 10818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (parsedPos < tmpPos.getIndex()) { 10828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedOffset = offset; 10838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedID.setToBogus(); 10848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedTimeType = UTZFMT_TIME_TYPE_UNKNOWN; 10858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedPos = tmpPos.getIndex(); 10868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius U_ASSERT(parsedPos == startIdx + 1); // only when "Z" is used 10878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1088103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 10898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 10908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 10918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Localized GMT format 10928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (parsedPos < maxPos && 10938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius (evaluated & STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT]) == 0) { 1094103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius tmpPos.setIndex(startIdx); 1095103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius tmpPos.setErrorIndex(-1); 1096103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 10978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UBool hasDigitOffset = FALSE; 10988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offset = parseOffsetLocalizedGMT(text, tmpPos, FALSE, &hasDigitOffset); 10998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tmpPos.getErrorIndex() == -1) { 11008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tmpPos.getIndex() == maxPos || hasDigitOffset) { 11018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius pos.setIndex(tmpPos.getIndex()); 11028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return createTimeZoneForOffset(offset); 11038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 11048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Evaluate other names - see the comment earlier in this method. 11058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (parsedPos < tmpPos.getIndex()) { 11068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedOffset = offset; 11078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedID.setToBogus(); 11088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedTimeType = UTZFMT_TIME_TYPE_UNKNOWN; 11098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedPos = tmpPos.getIndex(); 11108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 11118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 11128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1113103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 11148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (parsedPos < maxPos && 11158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius (evaluated & STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT_SHORT]) == 0) { 11168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setIndex(startIdx); 11178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setErrorIndex(-1); 1118103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1119103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool hasDigitOffset = FALSE; 11208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offset = parseOffsetLocalizedGMT(text, tmpPos, TRUE, &hasDigitOffset); 1121103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (tmpPos.getErrorIndex() == -1) { 1122103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (tmpPos.getIndex() == maxPos || hasDigitOffset) { 1123103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(tmpPos.getIndex()); 1124103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return createTimeZoneForOffset(offset); 1125103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1126103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Evaluate other names - see the comment earlier in this method. 11278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (parsedPos < tmpPos.getIndex()) { 11288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedOffset = offset; 11298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedID.setToBogus(); 11308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedTimeType = UTZFMT_TIME_TYPE_UNKNOWN; 11318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedPos = tmpPos.getIndex(); 11328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1133103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1134103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1135103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 11368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // When ParseOption.ALL_STYLES is available, we also try to look all possible display names and IDs. 1137103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // For example, when style is GENERIC_LONG, "EST" (SPECIFIC_SHORT) is never 1138103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // used for America/New_York. With parseAllStyles true, this code parses "EST" 1139103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // as America/New_York. 1140103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1141103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Note: Adding all possible names into the trie used by the implementation is quite heavy operation, 1142103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // which we want to avoid normally (note that we cache the trie, so this is applicable to the 1143103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // first time only as long as the cache does not expire). 11448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1145103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (parseOptions & UTZFMT_PARSE_OPTION_ALL_STYLES) { 11468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Try all specific names and exemplar location names 11478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (parsedPos < maxPos) { 11488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius LocalPointer<TimeZoneNames::MatchInfoCollection> specificMatches(fTimeZoneNames->find(text, startIdx, ALL_SIMPLE_NAME_TYPES, status)); 11498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (U_FAILURE(status)) { 11508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius pos.setErrorIndex(startIdx); 11518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return NULL; 11528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 11538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t specificMatchIdx = -1; 1154103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t matchPos = -1; 11558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (!specificMatches.isNull()) { 11568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius for (int32_t i = 0; i < specificMatches->size(); i++) { 11578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (startIdx + specificMatches->getMatchLengthAt(i) > matchPos) { 11588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius specificMatchIdx = i; 11598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius matchPos = startIdx + specificMatches->getMatchLengthAt(i); 11608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1161103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1162103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 11638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (parsedPos < matchPos) { 11648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius U_ASSERT(specificMatchIdx >= 0); 11658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedPos = matchPos; 11668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius getTimeZoneID(specificMatches.getAlias(), specificMatchIdx, parsedID); 11678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedTimeType = getTimeType(specificMatches->getNameTypeAt(specificMatchIdx)); 11688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedOffset = UNKNOWN_OFFSET; 11698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1170103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 11718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Try generic names 1172103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (parsedPos < maxPos) { 11738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t genMatchLen = -1; 11748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UTimeZoneFormatTimeType tt = UTZFMT_TIME_TYPE_UNKNOWN; 11758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1176103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const TimeZoneGenericNames *gnames = getTimeZoneGenericNames(status); 1177103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_SUCCESS(status)) { 11788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius genMatchLen = gnames->findBestMatch(text, startIdx, ALL_GENERIC_NAME_TYPES, tzID, tt, status); 1179103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1180103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 1181103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setErrorIndex(startIdx); 1182103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return NULL; 1183103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 11848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 11858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (parsedPos < startIdx + genMatchLen) { 11868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedPos = startIdx + genMatchLen; 11878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedID.setTo(tzID); 11888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedTimeType = tt; 11898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedOffset = UNKNOWN_OFFSET; 11908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1191103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 11928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 11938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Try time zone ID 11948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (parsedPos < maxPos && (evaluated & STYLE_PARSE_FLAGS[UTZFMT_STYLE_ZONE_ID]) == 0) { 11958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setIndex(startIdx); 11968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setErrorIndex(-1); 11978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 11988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parseZoneID(text, tmpPos, tzID); 11998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tmpPos.getErrorIndex() == -1 && parsedPos < tmpPos.getIndex()) { 12008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedPos = tmpPos.getIndex(); 12018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedID.setTo(tzID); 12028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedTimeType = UTZFMT_TIME_TYPE_UNKNOWN; 12038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedOffset = UNKNOWN_OFFSET; 1204103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 12058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 12068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Try short time zone ID 12078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (parsedPos < maxPos && (evaluated & STYLE_PARSE_FLAGS[UTZFMT_STYLE_ZONE_ID]) == 0) { 12088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setIndex(startIdx); 12098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpPos.setErrorIndex(-1); 12108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 12118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parseShortZoneID(text, tmpPos, tzID); 12128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tmpPos.getErrorIndex() == -1 && parsedPos < tmpPos.getIndex()) { 12138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedPos = tmpPos.getIndex(); 12148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedID.setTo(tzID); 12158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedTimeType = UTZFMT_TIME_TYPE_UNKNOWN; 12168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedOffset = UNKNOWN_OFFSET; 1217103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1218103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1219103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1220103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1221103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (parsedPos > startIdx) { 12228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Parsed successfully 12238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius TimeZone* parsedTZ; 12248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (parsedID.length() > 0) { 12258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedTZ = TimeZone::createTimeZone(parsedID); 12268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else { 12278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius U_ASSERT(parsedOffset != UNKNOWN_OFFSET); 12288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedTZ = createTimeZoneForOffset(parsedOffset); 12298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 12308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (timeType) { 12318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius *timeType = parsedTimeType; 12328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1233103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(parsedPos); 12348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return parsedTZ; 1235103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1236103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1237103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setErrorIndex(startIdx); 1238103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return NULL; 1239103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1240103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1241103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid 1242103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::parseObject(const UnicodeString& source, Formattable& result, 1243103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ParsePosition& parse_pos) const { 1244103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.adoptObject(parse(UTZFMT_STYLE_GENERIC_LOCATION, source, parse_pos, UTZFMT_PARSE_OPTION_ALL_STYLES)); 1245103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1246103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1247103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1248103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// ------------------------------------------------------------------ 1249103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Private zone name format/parse implementation 1250103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1251103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 1252103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::formatGeneric(const TimeZone& tz, int32_t genType, UDate date, UnicodeString& name) const { 1253103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UErrorCode status = U_ZERO_ERROR; 1254103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const TimeZoneGenericNames* gnames = getTimeZoneGenericNames(status); 1255103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 1256103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius name.setToBogus(); 1257103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return name; 1258103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1259103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1260103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (genType == UTZGNM_LOCATION) { 1261103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UChar* canonicalID = ZoneMeta::getCanonicalCLDRID(tz); 1262103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (canonicalID == NULL) { 1263103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius name.setToBogus(); 1264103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return name; 1265103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1266103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return gnames->getGenericLocationName(UnicodeString(canonicalID), name); 1267103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1268103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return gnames->getDisplayName(tz, (UTimeZoneGenericNameType)genType, date, name); 1269103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1270103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1271103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 1272103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::formatSpecific(const TimeZone& tz, UTimeZoneNameType stdType, UTimeZoneNameType dstType, 1273103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UDate date, UnicodeString& name, UTimeZoneFormatTimeType *timeType) const { 1274103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (fTimeZoneNames == NULL) { 1275103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius name.setToBogus(); 1276103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return name; 1277103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1278103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1279103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UErrorCode status = U_ZERO_ERROR; 1280103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool isDaylight = tz.inDaylightTime(date, status); 1281103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UChar* canonicalID = ZoneMeta::getCanonicalCLDRID(tz); 1282103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1283103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status) || canonicalID == NULL) { 1284103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius name.setToBogus(); 1285103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return name; 1286103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1287103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1288103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (isDaylight) { 1289103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fTimeZoneNames->getDisplayName(UnicodeString(canonicalID), dstType, date, name); 1290103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 1291103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fTimeZoneNames->getDisplayName(UnicodeString(canonicalID), stdType, date, name); 1292103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1293103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1294103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (timeType && !name.isEmpty()) { 1295103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *timeType = isDaylight ? UTZFMT_TIME_TYPE_DAYLIGHT : UTZFMT_TIME_TYPE_STANDARD; 1296103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1297103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return name; 1298103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1299103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1300103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusconst TimeZoneGenericNames* 1301103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::getTimeZoneGenericNames(UErrorCode& status) const { 1302103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 1303103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return NULL; 1304103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1305103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 130659d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_lock(&gLock); 130759d709d503bab6e2b61931737e662dd293b40578ccornelius if (fTimeZoneGenericNames == NULL) { 1308103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius TimeZoneFormat *nonConstThis = const_cast<TimeZoneFormat *>(this); 130959d709d503bab6e2b61931737e662dd293b40578ccornelius nonConstThis->fTimeZoneGenericNames = TimeZoneGenericNames::createInstance(fLocale, status); 1310103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 131159d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_unlock(&gLock); 1312103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1313103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return fTimeZoneGenericNames; 1314103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1315103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 13168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUnicodeString& 13178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::formatExemplarLocation(const TimeZone& tz, UnicodeString& name) const { 13188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UnicodeString location; 13198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius const UChar* canonicalID = ZoneMeta::getCanonicalCLDRID(tz); 13208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 13218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (canonicalID) { 13228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius fTimeZoneNames->getExemplarLocationName(UnicodeString(canonicalID), location); 13238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 13248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (location.length() > 0) { 13258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius name.setTo(location); 13268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else { 13278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Use "unknown" location 13288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius fTimeZoneNames->getExemplarLocationName(UnicodeString(UNKNOWN_ZONE_ID), location); 13298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (location.length() > 0) { 13308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius name.setTo(location); 13318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else { 13328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // last resort 13338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius name.setTo(UNKNOWN_LOCATION, -1); 13348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 13358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 13368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return name; 13378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 13388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 13398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1340103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// ------------------------------------------------------------------ 1341103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Zone offset format and parse 1342103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1343103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 13448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::formatOffsetISO8601Basic(int32_t offset, UBool useUtcIndicator, UBool isShort, UBool ignoreSeconds, 13458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UnicodeString& result, UErrorCode& status) const { 13468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return formatOffsetISO8601(offset, TRUE, useUtcIndicator, isShort, ignoreSeconds, result, status); 13478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 1348103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 13498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUnicodeString& 13508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::formatOffsetISO8601Extended(int32_t offset, UBool useUtcIndicator, UBool isShort, UBool ignoreSeconds, 13518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UnicodeString& result, UErrorCode& status) const { 13528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return formatOffsetISO8601(offset, FALSE, useUtcIndicator, isShort, ignoreSeconds, result, status); 1353103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1354103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1355103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 13568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::formatOffsetLocalizedGMT(int32_t offset, UnicodeString& result, UErrorCode& status) const { 13578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return formatOffsetLocalizedGMT(offset, FALSE, result, status); 13588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 1359103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 13608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUnicodeString& 13618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::formatOffsetShortLocalizedGMT(int32_t offset, UnicodeString& result, UErrorCode& status) const { 13628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return formatOffsetLocalizedGMT(offset, TRUE, result, status); 13638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 13648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 13658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusint32_t 13668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::parseOffsetISO8601(const UnicodeString& text, ParsePosition& pos) const { 13678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return parseOffsetISO8601(text, pos, FALSE); 13688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 13698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 13708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusint32_t 13718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::parseOffsetLocalizedGMT(const UnicodeString& text, ParsePosition& pos) const { 13728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return parseOffsetLocalizedGMT(text, pos, FALSE, NULL); 13738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 13748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 13758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusint32_t 13768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::parseOffsetShortLocalizedGMT(const UnicodeString& text, ParsePosition& pos) const { 13778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return parseOffsetLocalizedGMT(text, pos, TRUE, NULL); 1378103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1379103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 13808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius// ------------------------------------------------------------------ 13818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius// Private zone offset format/parse implementation 13828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1383103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 13848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::formatOffsetISO8601(int32_t offset, UBool isBasic, UBool useUtcIndicator, 13858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UBool isShort, UBool ignoreSeconds, UnicodeString& result, UErrorCode& status) const { 1386103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 1387103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.setToBogus(); 1388103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return result; 1389103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 13908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t absOffset = offset < 0 ? -offset : offset; 13918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (useUtcIndicator && (absOffset < MILLIS_PER_SECOND || (ignoreSeconds && absOffset < MILLIS_PER_MINUTE))) { 13928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius result.setTo(ISO8601_UTC); 1393103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return result; 1394103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1395103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 13968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius OffsetFields minFields = isShort ? FIELDS_H : FIELDS_HM; 13978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius OffsetFields maxFields = ignoreSeconds ? FIELDS_HM : FIELDS_HMS; 13988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UChar sep = isBasic ? 0 : ISO8601_SEP; 1399103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 14008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Note: FIELDS_HMS as maxFields is a CLDR/ICU extension. ISO 8601 specification does 14018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // not support seconds field. 14028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 14038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (absOffset >= MAX_OFFSET) { 14048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius result.setToBogus(); 14058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius status = U_ILLEGAL_ARGUMENT_ERROR; 14068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return result; 1407103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1408103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 14098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int fields[3]; 14108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius fields[0] = absOffset / MILLIS_PER_HOUR; 14118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius absOffset = absOffset % MILLIS_PER_HOUR; 14128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius fields[1] = absOffset / MILLIS_PER_MINUTE; 14138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius absOffset = absOffset % MILLIS_PER_MINUTE; 14148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius fields[2] = absOffset / MILLIS_PER_SECOND; 14158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 14168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius U_ASSERT(fields[0] >= 0 && fields[0] <= MAX_OFFSET_HOUR); 14178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius U_ASSERT(fields[1] >= 0 && fields[1] <= MAX_OFFSET_MINUTE); 14188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius U_ASSERT(fields[2] >= 0 && fields[2] <= MAX_OFFSET_SECOND); 14198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 14208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t lastIdx = maxFields; 14218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius while (lastIdx > minFields) { 14228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (fields[lastIdx] != 0) { 14238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 14248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 14258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius lastIdx--; 14268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 14278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 14288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UChar sign = PLUS; 14298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (offset < 0) { 14308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // if all output fields are 0s, do not use negative sign 14318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius for (int32_t idx = 0; idx <= lastIdx; idx++) { 14328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (fields[idx] != 0) { 14338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius sign = MINUS; 14348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 14358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 14368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 14378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 14388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius result.setTo(sign); 14398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 14408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius for (int32_t idx = 0; idx <= lastIdx; idx++) { 14418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (sep && idx != 0) { 14428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius result.append(sep); 14438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 14448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius result.append((UChar)(0x0030 + fields[idx]/10)); 14458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius result.append((UChar)(0x0030 + fields[idx]%10)); 14468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 14478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 14488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return result; 14498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 14508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 14518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUnicodeString& 14528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::formatOffsetLocalizedGMT(int32_t offset, UBool isShort, UnicodeString& result, UErrorCode& status) const { 14538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (U_FAILURE(status)) { 14548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius result.setToBogus(); 14558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return result; 14568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 14578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (offset <= -MAX_OFFSET || offset >= MAX_OFFSET) { 14588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius result.setToBogus(); 14598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius status = U_ILLEGAL_ARGUMENT_ERROR; 14608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return result; 14618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 14628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 14638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (offset == 0) { 14648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius result.setTo(fGMTZeroFormat); 14658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return result; 14668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 14678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 14688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UBool positive = TRUE; 14698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (offset < 0) { 14708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offset = -offset; 14718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius positive = FALSE; 14728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 14738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 14748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t offsetH = offset / MILLIS_PER_HOUR; 14758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offset = offset % MILLIS_PER_HOUR; 14768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t offsetM = offset / MILLIS_PER_MINUTE; 14778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offset = offset % MILLIS_PER_MINUTE; 14788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t offsetS = offset / MILLIS_PER_SECOND; 1479103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1480103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(offsetH <= MAX_OFFSET_HOUR && offsetM <= MAX_OFFSET_MINUTE && offsetS <= MAX_OFFSET_SECOND); 1481103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1482103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UVector* offsetPatternItems = NULL; 1483103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (positive) { 14848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (offsetS != 0) { 14858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offsetPatternItems = fGMTOffsetPatternItems[UTZFMT_PAT_POSITIVE_HMS]; 14868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else if (offsetM != 0 || !isShort) { 14878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offsetPatternItems = fGMTOffsetPatternItems[UTZFMT_PAT_POSITIVE_HM]; 14888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else { 14898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offsetPatternItems = fGMTOffsetPatternItems[UTZFMT_PAT_POSITIVE_H]; 14908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1491103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 14928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (offsetS != 0) { 14938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offsetPatternItems = fGMTOffsetPatternItems[UTZFMT_PAT_NEGATIVE_HMS]; 14948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else if (offsetM != 0 || !isShort) { 14958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offsetPatternItems = fGMTOffsetPatternItems[UTZFMT_PAT_NEGATIVE_HM]; 14968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else { 14978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offsetPatternItems = fGMTOffsetPatternItems[UTZFMT_PAT_NEGATIVE_H]; 14988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1499103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1500103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1501103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(offsetPatternItems != NULL); 1502103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1503103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Building the GMT format string 1504103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.setTo(fGMTPatternPrefix); 1505103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1506103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t i = 0; i < offsetPatternItems->size(); i++) { 1507103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const GMTOffsetField* item = (GMTOffsetField*)offsetPatternItems->elementAt(i); 1508103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius GMTOffsetField::FieldType type = item->getType(); 1509103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1510103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius switch (type) { 1511103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case GMTOffsetField::TEXT: 1512103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.append(item->getPatternText(), -1); 1513103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1514103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1515103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case GMTOffsetField::HOUR: 15168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius appendOffsetDigits(result, offsetH, (isShort ? 1 : 2)); 1517103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1518103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1519103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case GMTOffsetField::MINUTE: 15208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius appendOffsetDigits(result, offsetM, 2); 1521103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1522103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1523103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case GMTOffsetField::SECOND: 15248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius appendOffsetDigits(result, offsetS, 2); 1525103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1526103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1527103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1528103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1529103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.append(fGMTPatternSuffix); 1530103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return result; 1531103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1532103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1533103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusint32_t 1534103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::parseOffsetISO8601(const UnicodeString& text, ParsePosition& pos, UBool extendedOnly, UBool* hasDigitOffset /* = NULL */) const { 1535103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (hasDigitOffset) { 1536103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *hasDigitOffset = FALSE; 1537103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1538103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t start = pos.getIndex(); 1539103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (start >= text.length()) { 1540103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setErrorIndex(start); 1541103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return 0; 1542103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1543103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1544103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar firstChar = text.charAt(start); 1545103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (firstChar == ISO8601_UTC || firstChar == (UChar)(ISO8601_UTC + 0x20)) { 1546103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // "Z" (or "z") - indicates UTC 1547103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(start + 1); 1548103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return 0; 1549103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1550103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1551103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t sign = 1; 1552103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (firstChar == PLUS) { 1553103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius sign = 1; 1554103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else if (firstChar == MINUS) { 1555103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius sign = -1; 1556103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 1557103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Not an ISO 8601 offset string 1558103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setErrorIndex(start); 1559103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return 0; 1560103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1561103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ParsePosition posOffset(start + 1); 15628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t offset = parseAsciiOffsetFields(text, posOffset, ISO8601_SEP, FIELDS_H, FIELDS_HMS); 1563103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (posOffset.getErrorIndex() == -1 && !extendedOnly && (posOffset.getIndex() - start <= 3)) { 1564103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // If the text is successfully parsed as extended format with the options above, it can be also parsed 1565103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // as basic format. For example, "0230" can be parsed as offset 2:00 (only first digits are valid for 1566103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // extended format), but it can be parsed as offset 2:30 with basic format. We use longer result. 1567103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ParsePosition posBasic(start + 1); 1568103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t tmpOffset = parseAbuttingAsciiOffsetFields(text, posBasic, FIELDS_H, FIELDS_HMS, FALSE); 1569103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (posBasic.getErrorIndex() == -1 && posBasic.getIndex() > posOffset.getIndex()) { 1570103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius offset = tmpOffset; 1571103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius posOffset.setIndex(posBasic.getIndex()); 1572103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1573103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1574103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1575103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (posOffset.getErrorIndex() != -1) { 1576103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setErrorIndex(start); 1577103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return 0; 1578103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1579103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1580103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(posOffset.getIndex()); 1581103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (hasDigitOffset) { 1582103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *hasDigitOffset = TRUE; 1583103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1584103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return sign * offset; 1585103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1586103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1587103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusint32_t 15888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::parseOffsetLocalizedGMT(const UnicodeString& text, ParsePosition& pos, UBool isShort, UBool* hasDigitOffset) const { 1589103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t start = pos.getIndex(); 1590103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t offset = 0; 15918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t parsedLength = 0; 1592103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1593103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (hasDigitOffset) { 1594103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *hasDigitOffset = FALSE; 1595103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1596103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 15978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offset = parseOffsetLocalizedGMTPattern(text, start, isShort, parsedLength); 1598103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 15998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // For now, parseOffsetLocalizedGMTPattern handles both long and short 16008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // formats, no matter isShort is true or false. This might be changed in future 16018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // when strict parsing is necessary, or different set of patterns are used for 16028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // short/long formats. 16038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#if 0 16048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (parsedLength == 0) { 16058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offset = parseOffsetLocalizedGMTPattern(text, start, !isShort, parsedLength); 16068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 16078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius#endif 1608103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 16098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (parsedLength > 0) { 1610103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (hasDigitOffset) { 1611103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *hasDigitOffset = TRUE; 1612b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 16138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius pos.setIndex(start + parsedLength); 1614103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return offset; 1615b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1616b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1617103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Try the default patterns 1618103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius offset = parseOffsetDefaultLocalizedGMT(text, start, parsedLength); 1619103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (parsedLength > 0) { 1620103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (hasDigitOffset) { 1621103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius *hasDigitOffset = TRUE; 1622103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1623103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(start + parsedLength); 1624103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return offset; 1625103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1626b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1627103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Check if this is a GMT zero format 1628103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (text.caseCompare(start, fGMTZeroFormat.length(), fGMTZeroFormat, 0) == 0) { 1629103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(start + fGMTZeroFormat.length()); 1630103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return 0; 1631b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1632103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1633103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Check if this is a default GMT zero format 1634103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t i = 0; ALT_GMT_STRINGS[i][0] != 0; i++) { 1635103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UChar* defGMTZero = ALT_GMT_STRINGS[i]; 1636103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t defGMTZeroLen = u_strlen(defGMTZero); 1637103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (text.caseCompare(start, defGMTZeroLen, defGMTZero, 0) == 0) { 1638103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(start + defGMTZeroLen); 1639103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return 0; 1640103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1641b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1642b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1643103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Nothing matched 1644103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setErrorIndex(start); 1645103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return 0; 1646b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1647b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1648103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusint32_t 16498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::parseOffsetLocalizedGMTPattern(const UnicodeString& text, int32_t start, UBool /*isShort*/, int32_t& parsedLen) const { 16508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t idx = start; 16518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t offset = 0; 16528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UBool parsed = FALSE; 16538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 16548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius do { 16558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Prefix part 16568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t len = fGMTPatternPrefix.length(); 16578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (len > 0 && text.caseCompare(idx, len, fGMTPatternPrefix, 0) != 0) { 16588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // prefix match failed 16598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 16608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 16618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius idx += len; 16628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 16638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Offset part 16648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offset = parseOffsetFields(text, idx, FALSE, len); 16658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (len == 0) { 16668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // offset field match failed 16678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 16688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 16698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius idx += len; 16708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 16718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius len = fGMTPatternSuffix.length(); 16728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (len > 0 && text.caseCompare(idx, len, fGMTPatternSuffix, 0) != 0) { 16738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // no suffix match 16748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 16758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 16768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius idx += len; 16778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsed = TRUE; 16788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } while (FALSE); 16798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 16808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedLen = parsed ? idx - start : 0; 16818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return offset; 16828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 16838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 16848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusint32_t 16858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::parseOffsetFields(const UnicodeString& text, int32_t start, UBool /*isShort*/, int32_t& parsedLen) const { 16868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t outLen = 0; 1687103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t offset = 0; 16888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t sign = 1; 1689103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1690103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedLen = 0; 1691103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 16928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t offsetH, offsetM, offsetS; 16938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offsetH = offsetM = offsetS = 0; 16948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1695103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t patidx = 0; PARSE_GMT_OFFSET_TYPES[patidx] >= 0; patidx++) { 1696103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t gmtPatType = PARSE_GMT_OFFSET_TYPES[patidx]; 1697103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UVector* items = fGMTOffsetPatternItems[gmtPatType]; 1698103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(items != NULL); 1699b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 17008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius outLen = parseOffsetFieldsWithPattern(text, start, items, FALSE, offsetH, offsetM, offsetS); 17018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (outLen > 0) { 17028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius sign = (gmtPatType == UTZFMT_PAT_POSITIVE_H || gmtPatType == UTZFMT_PAT_POSITIVE_HM || gmtPatType == UTZFMT_PAT_POSITIVE_HMS) ? 17038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1 : -1; 1704103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1705103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1706b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1707b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 17088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (outLen > 0 && fAbuttingOffsetHoursAndMinutes) { 17098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // When hours field is sabutting minutes field, 17108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // the parse result above may not be appropriate. 17118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // For example, "01020" is parsed as 01:02: above, 17128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // but it should be parsed as 00:10:20. 17138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t tmpLen = 0; 17148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t tmpSign = 1; 17158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t tmpH, tmpM, tmpS; 17168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 17178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius for (int32_t patidx = 0; PARSE_GMT_OFFSET_TYPES[patidx] >= 0; patidx++) { 17188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t gmtPatType = PARSE_GMT_OFFSET_TYPES[patidx]; 17198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UVector* items = fGMTOffsetPatternItems[gmtPatType]; 17208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius U_ASSERT(items != NULL); 17218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 17228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // forcing parse to use single hour digit 17238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpLen = parseOffsetFieldsWithPattern(text, start, items, TRUE, tmpH, tmpM, tmpS); 17248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tmpLen > 0) { 17258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tmpSign = (gmtPatType == UTZFMT_PAT_POSITIVE_H || gmtPatType == UTZFMT_PAT_POSITIVE_HM || gmtPatType == UTZFMT_PAT_POSITIVE_HMS) ? 17268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 1 : -1; 17278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 17288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 17298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 17308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tmpLen > outLen) { 17318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Better parse result with single hour digit 17328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius outLen = tmpLen; 17338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius sign = tmpSign; 17348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offsetH = tmpH; 17358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offsetM = tmpM; 17368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offsetS = tmpS; 17378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 17388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 1739103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 17408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (outLen > 0) { 17418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offset = ((((offsetH * 60) + offsetM) * 60) + offsetS) * 1000 * sign; 17428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedLen = outLen; 1743103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1744103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1745103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return offset; 1746b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1747b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1748103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusint32_t 17498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::parseOffsetFieldsWithPattern(const UnicodeString& text, int32_t start, 17508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UVector* patternItems, UBool forceSingleHourDigit, int32_t& hour, int32_t& min, int32_t& sec) const { 17518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UBool failed = FALSE; 17528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t offsetH, offsetM, offsetS; 17538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offsetH = offsetM = offsetS = 0; 17548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t idx = start; 17558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 17568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius for (int32_t i = 0; i < patternItems->size(); i++) { 17578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t len = 0; 17588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius const GMTOffsetField* field = (const GMTOffsetField*)patternItems->elementAt(i); 17598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius GMTOffsetField::FieldType fieldType = field->getType(); 17608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (fieldType == GMTOffsetField::TEXT) { 17618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius const UChar* patStr = field->getPatternText(); 17628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius len = u_strlen(patStr); 17638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (text.caseCompare(idx, len, patStr, 0) != 0) { 17648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius failed = TRUE; 17658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 17668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 17678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius idx += len; 17688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else { 17698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (fieldType == GMTOffsetField::HOUR) { 17708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius uint8_t maxDigits = forceSingleHourDigit ? 1 : 2; 17718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offsetH = parseOffsetFieldWithLocalizedDigits(text, idx, 1, maxDigits, 0, MAX_OFFSET_HOUR, len); 17728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else if (fieldType == GMTOffsetField::MINUTE) { 17738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offsetM = parseOffsetFieldWithLocalizedDigits(text, idx, 2, 2, 0, MAX_OFFSET_MINUTE, len); 17748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else if (fieldType == GMTOffsetField::SECOND) { 17758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius offsetS = parseOffsetFieldWithLocalizedDigits(text, idx, 2, 2, 0, MAX_OFFSET_SECOND, len); 17768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 17778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 17788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (len == 0) { 17798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius failed = TRUE; 17808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 17818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 17828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius idx += len; 17838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 17848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 17858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 17868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (failed) { 17878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius hour = min = sec = 0; 17888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return 0; 17898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 17908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 17918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius hour = offsetH; 17928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius min = offsetM; 17938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius sec = offsetS; 17948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 17958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return idx - start; 17968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 17978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 17988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusint32_t 1799103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::parseAbuttingOffsetFields(const UnicodeString& text, int32_t start, int32_t& parsedLen) const { 1800103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t digits[MAX_OFFSET_DIGITS]; 1801103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t parsed[MAX_OFFSET_DIGITS]; // accumulative offsets 1802103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1803103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Parse digits into int[] 1804103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t idx = start; 1805103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t len = 0; 1806103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t numDigits = 0; 1807103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t i = 0; i < MAX_OFFSET_DIGITS; i++) { 1808103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius digits[i] = parseSingleLocalizedDigit(text, idx, len); 1809103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (digits[i] < 0) { 1810103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1811103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1812103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius idx += len; 1813103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsed[i] = idx - start; 1814103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius numDigits++; 1815b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1816103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1817103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (numDigits == 0) { 1818103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedLen = 0; 1819103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return 0; 1820b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1821b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1822103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t offset = 0; 1823103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius while (numDigits > 0) { 1824103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t hour = 0; 1825103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t min = 0; 1826103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t sec = 0; 1827103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1828103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(numDigits > 0 && numDigits <= MAX_OFFSET_DIGITS); 1829103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius switch (numDigits) { 1830103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case 1: // H 1831103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius hour = digits[0]; 1832103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1833103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case 2: // HH 1834103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius hour = digits[0] * 10 + digits[1]; 1835103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1836103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case 3: // Hmm 1837103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius hour = digits[0]; 1838103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius min = digits[1] * 10 + digits[2]; 1839103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1840103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case 4: // HHmm 1841103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius hour = digits[0] * 10 + digits[1]; 1842103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius min = digits[2] * 10 + digits[3]; 1843103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1844103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case 5: // Hmmss 1845103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius hour = digits[0]; 1846103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius min = digits[1] * 10 + digits[2]; 1847103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius sec = digits[3] * 10 + digits[4]; 1848103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1849103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case 6: // HHmmss 1850103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius hour = digits[0] * 10 + digits[1]; 1851103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius min = digits[2] * 10 + digits[3]; 1852103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius sec = digits[4] * 10 + digits[5]; 1853103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1854103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1855103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (hour <= MAX_OFFSET_HOUR && min <= MAX_OFFSET_MINUTE && sec <= MAX_OFFSET_SECOND) { 1856103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // found a valid combination 1857103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius offset = hour * MILLIS_PER_HOUR + min * MILLIS_PER_MINUTE + sec * MILLIS_PER_SECOND; 1858103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedLen = parsed[numDigits - 1]; 1859103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1860103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1861103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius numDigits--; 1862b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1863103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return offset; 1864103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1865b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1866103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusint32_t 1867103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::parseOffsetDefaultLocalizedGMT(const UnicodeString& text, int start, int32_t& parsedLen) const { 1868103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t idx = start; 1869103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t offset = 0; 1870103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t parsed = 0; 1871103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1872103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius do { 1873103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // check global default GMT alternatives 1874103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t gmtLen = 0; 1875103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1876103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t i = 0; ALT_GMT_STRINGS[i][0] != 0; i++) { 1877103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius const UChar* gmt = ALT_GMT_STRINGS[i]; 1878103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t len = u_strlen(gmt); 1879103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (text.caseCompare(start, len, gmt, 0) == 0) { 1880103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius gmtLen = len; 1881103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1882103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1883103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1884103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (gmtLen == 0) { 1885103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1886103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1887103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius idx += gmtLen; 1888b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1889103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // offset needs a sign char and a digit at minimum 1890103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (idx + 1 >= text.length()) { 1891103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1892103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1893b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1894103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // parse sign 1895103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t sign = 1; 1896103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar c = text.charAt(idx); 1897103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (c == PLUS) { 1898103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius sign = 1; 1899103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else if (c == MINUS) { 1900103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius sign = -1; 1901103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 1902103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1903103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1904103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius idx++; 1905103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1906103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // offset part 1907103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // try the default pattern with the separator first 1908103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t lenWithSep = 0; 1909103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t offsetWithSep = parseDefaultOffsetFields(text, idx, DEFAULT_GMT_OFFSET_SEP, lenWithSep); 1910103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (lenWithSep == text.length() - idx) { 1911103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // maximum match 1912103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius offset = offsetWithSep * sign; 1913103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius idx += lenWithSep; 1914103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 1915103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // try abutting field pattern 1916103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t lenAbut = 0; 1917103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t offsetAbut = parseAbuttingOffsetFields(text, idx, lenAbut); 1918103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1919103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (lenWithSep > lenAbut) { 1920103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius offset = offsetWithSep * sign; 1921103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius idx += lenWithSep; 1922103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 1923103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius offset = offsetAbut * sign; 1924103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius idx += lenAbut; 1925103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1926103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1927103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsed = idx - start; 1928103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } while (false); 1929b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1930103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedLen = parsed; 1931103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return offset; 1932103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 1933b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1934103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusint32_t 1935103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::parseDefaultOffsetFields(const UnicodeString& text, int32_t start, UChar separator, int32_t& parsedLen) const { 1936103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t max = text.length(); 1937103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t idx = start; 1938103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t len = 0; 1939103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t hour = 0, min = 0, sec = 0; 1940103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1941103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedLen = 0; 1942103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1943103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius do { 1944103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius hour = parseOffsetFieldWithLocalizedDigits(text, idx, 1, 2, 0, MAX_OFFSET_HOUR, len); 1945103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (len == 0) { 1946103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1947b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1948103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius idx += len; 1949103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1950103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (idx + 1 < max && text.charAt(idx) == separator) { 1951103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius min = parseOffsetFieldWithLocalizedDigits(text, idx + 1, 2, 2, 0, MAX_OFFSET_MINUTE, len); 1952103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (len == 0) { 1953b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho break; 1954b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1955103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius idx += (1 + len); 1956103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1957103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (idx + 1 < max && text.charAt(idx) == separator) { 1958103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius sec = parseOffsetFieldWithLocalizedDigits(text, idx + 1, 2, 2, 0, MAX_OFFSET_SECOND, len); 1959103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (len == 0) { 1960103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1961103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1962103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius idx += (1 + len); 1963103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1964b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1965103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } while (FALSE); 1966103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1967103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (idx == start) { 1968103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return 0; 1969b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1970103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1971103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedLen = idx - start; 1972103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return hour * MILLIS_PER_HOUR + min * MILLIS_PER_MINUTE + sec * MILLIS_PER_SECOND; 1973b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 1974b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1975103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusint32_t 1976103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::parseOffsetFieldWithLocalizedDigits(const UnicodeString& text, int32_t start, uint8_t minDigits, uint8_t maxDigits, uint16_t minVal, uint16_t maxVal, int32_t& parsedLen) const { 1977103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedLen = 0; 1978b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1979103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t decVal = 0; 1980103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t numDigits = 0; 1981103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t idx = start; 1982103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t digitLen = 0; 1983103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 1984103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius while (idx < text.length() && numDigits < maxDigits) { 1985103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t digit = parseSingleLocalizedDigit(text, idx, digitLen); 1986103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (digit < 0) { 1987103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1988b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1989103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t tmpVal = decVal * 10 + digit; 1990103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (tmpVal > maxVal) { 1991103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 1992103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 1993103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius decVal = tmpVal; 1994103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius numDigits++; 1995103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius idx += digitLen; 1996b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 1997b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 1998103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Note: maxVal is checked in the while loop 1999103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (numDigits < minDigits || decVal < minVal) { 2000103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius decVal = -1; 2001103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius numDigits = 0; 2002103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 2003103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedLen = idx - start; 2004b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2005b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2006103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return decVal; 2007103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 2008b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2009103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusint32_t 2010103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::parseSingleLocalizedDigit(const UnicodeString& text, int32_t start, int32_t& len) const { 2011103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t digit = -1; 2012103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius len = 0; 2013103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (start < text.length()) { 2014103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar32 cp = text.char32At(start); 2015103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2016103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // First, try digits configured for this instance 2017103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t i = 0; i < 10; i++) { 2018103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (cp == fGMTOffsetDigits[i]) { 2019103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius digit = i; 2020103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2021103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2022103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2023103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // If failed, check if this is a Unicode digit 2024103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (digit < 0) { 2025103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t tmp = u_charDigitValue(cp); 2026103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius digit = (tmp >= 0 && tmp <= 9) ? tmp : -1; 2027103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2028103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2029103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (digit >= 0) { 2030103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t next = text.moveIndex32(start, 1); 2031103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius len = next - start; 2032103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2033b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2034103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return digit; 2035103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 2036b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2037103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 2038103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::formatOffsetWithAsciiDigits(int32_t offset, UChar sep, OffsetFields minFields, OffsetFields maxFields, UnicodeString& result) { 2039103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(maxFields >= minFields); 2040103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(offset > -MAX_OFFSET && offset < MAX_OFFSET); 2041103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2042103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar sign = PLUS; 2043103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (offset < 0) { 2044103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius sign = MINUS; 2045103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius offset = -offset; 2046103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2047103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.setTo(sign); 2048103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2049103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int fields[3]; 2050103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fields[0] = offset / MILLIS_PER_HOUR; 2051103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius offset = offset % MILLIS_PER_HOUR; 2052103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fields[1] = offset / MILLIS_PER_MINUTE; 2053103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius offset = offset % MILLIS_PER_MINUTE; 2054103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fields[2] = offset / MILLIS_PER_SECOND; 2055103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2056103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(fields[0] >= 0 && fields[0] <= MAX_OFFSET_HOUR); 2057103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(fields[1] >= 0 && fields[1] <= MAX_OFFSET_MINUTE); 2058103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(fields[2] >= 0 && fields[2] <= MAX_OFFSET_SECOND); 2059103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2060103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t lastIdx = maxFields; 2061103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius while (lastIdx > minFields) { 2062103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (fields[lastIdx] != 0) { 2063103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2064103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2065103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius lastIdx--; 2066b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2067b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2068103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t idx = 0; idx <= lastIdx; idx++) { 2069103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (sep && idx != 0) { 2070103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.append(sep); 2071103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2072103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.append((UChar)(0x0030 + fields[idx]/10)); 2073103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.append((UChar)(0x0030 + fields[idx]%10)); 2074b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2075103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2076103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return result; 2077b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 2078b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2079103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusint32_t 2080103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::parseAbuttingAsciiOffsetFields(const UnicodeString& text, ParsePosition& pos, OffsetFields minFields, OffsetFields maxFields, UBool fixedHourWidth) { 2081103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t start = pos.getIndex(); 2082b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2083103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t minDigits = 2 * (minFields + 1) - (fixedHourWidth ? 0 : 1); 2084103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t maxDigits = 2 * (maxFields + 1); 2085b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2086103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(maxDigits <= MAX_OFFSET_DIGITS); 2087b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 208854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t digits[MAX_OFFSET_DIGITS] = {}; 2089103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t numDigits = 0; 2090103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t idx = start; 2091103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius while (numDigits < maxDigits && idx < text.length()) { 2092103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar uch = text.charAt(idx); 2093103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t digit = DIGIT_VAL(uch); 2094103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (digit < 0) { 2095103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2096103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2097103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius digits[numDigits] = digit; 2098103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius numDigits++; 2099103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius idx++; 2100103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2101b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2102103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (fixedHourWidth && (numDigits & 1)) { 2103103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Fixed digits, so the number of digits must be even number. Truncating. 2104103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius numDigits--; 2105103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2106b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2107103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (numDigits < minDigits) { 2108103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setErrorIndex(start); 2109103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return 0; 2110103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2111b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2112103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t hour = 0, min = 0, sec = 0; 2113103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool bParsed = FALSE; 2114103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius while (numDigits >= minDigits) { 2115103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius switch (numDigits) { 2116103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case 1: //H 2117103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius hour = digits[0]; 2118103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2119103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case 2: //HH 2120103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius hour = digits[0] * 10 + digits[1]; 2121103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2122103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case 3: //Hmm 2123103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius hour = digits[0]; 2124103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius min = digits[1] * 10 + digits[2]; 2125103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2126103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case 4: //HHmm 2127103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius hour = digits[0] * 10 + digits[1]; 2128103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius min = digits[2] * 10 + digits[3]; 2129103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2130103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case 5: //Hmmss 2131103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius hour = digits[0]; 2132103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius min = digits[1] * 10 + digits[2]; 2133103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius sec = digits[3] * 10 + digits[4]; 2134103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2135103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case 6: //HHmmss 2136103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius hour = digits[0] * 10 + digits[1]; 2137103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius min = digits[2] * 10 + digits[3]; 2138103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius sec = digits[4] * 10 + digits[5]; 2139103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2140103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2141b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2142103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (hour <= MAX_OFFSET_HOUR && min <= MAX_OFFSET_MINUTE && sec <= MAX_OFFSET_SECOND) { 2143103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Successfully parsed 2144103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius bParsed = true; 2145103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2146103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2147b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2148103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Truncating 2149103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius numDigits -= (fixedHourWidth ? 2 : 1); 2150103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius hour = min = sec = 0; 2151103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2152b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2153103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (!bParsed) { 2154103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setErrorIndex(start); 2155103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return 0; 2156b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2157103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(start + numDigits); 2158103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return ((((hour * 60) + min) * 60) + sec) * 1000; 2159b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 2160b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2161103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusint32_t 21628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::parseAsciiOffsetFields(const UnicodeString& text, ParsePosition& pos, UChar sep, OffsetFields minFields, OffsetFields maxFields) { 2163103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t start = pos.getIndex(); 2164103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t fieldVal[] = {0, 0, 0}; 2165103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t fieldLen[] = {0, -1, -1}; 2166103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t idx = start, fieldIdx = 0; idx < text.length() && fieldIdx <= maxFields; idx++) { 2167103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar c = text.charAt(idx); 2168103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (c == sep) { 21698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (fieldIdx == 0) { 21708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (fieldLen[0] == 0) { 21718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // no hours field 21728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 21738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 2174103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // 1 digit hour, move to next field 2175103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 21768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (fieldLen[fieldIdx] != -1) { 21778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // premature minute or seconds field 21788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 21798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 21808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius fieldLen[fieldIdx] = 0; 2181103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2182103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius continue; 21838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else if (fieldLen[fieldIdx] == -1) { 21848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // no separator after 2 digit field 21858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 2186103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2187103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t digit = DIGIT_VAL(c); 2188103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (digit < 0) { 2189103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // not a digit 2190103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2191103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2192103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fieldVal[fieldIdx] = fieldVal[fieldIdx] * 10 + digit; 2193103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fieldLen[fieldIdx]++; 2194103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (fieldLen[fieldIdx] >= 2) { 2195103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // parsed 2 digits, move to next field 2196103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fieldIdx++; 2197103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2198103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2199b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2200103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t offset = 0; 2201103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t parsedLen = 0; 2202103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t parsedFields = -1; 2203103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius do { 2204103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // hour 22058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (fieldLen[0] == 0) { 2206103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2207103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2208103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (fieldVal[0] > MAX_OFFSET_HOUR) { 2209103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius offset = (fieldVal[0] / 10) * MILLIS_PER_HOUR; 2210103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedFields = FIELDS_H; 2211103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedLen = 1; 2212103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2213103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2214103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius offset = fieldVal[0] * MILLIS_PER_HOUR; 2215103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedLen = fieldLen[0]; 2216103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedFields = FIELDS_H; 2217b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2218103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // minute 2219103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (fieldLen[1] != 2 || fieldVal[1] > MAX_OFFSET_MINUTE) { 2220103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2221103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2222103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius offset += fieldVal[1] * MILLIS_PER_MINUTE; 2223103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedLen += (1 + fieldLen[1]); 2224103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedFields = FIELDS_HM; 2225b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2226103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // second 2227103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (fieldLen[2] != 2 || fieldVal[2] > MAX_OFFSET_SECOND) { 2228103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2229103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2230103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius offset += fieldVal[2] * MILLIS_PER_SECOND; 2231103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedLen += (1 + fieldLen[2]); 2232103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius parsedFields = FIELDS_HMS; 2233103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } while (false); 2234103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2235103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (parsedFields < minFields) { 2236103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setErrorIndex(start); 2237103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return 0; 2238103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2239b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2240103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius pos.setIndex(start + parsedLen); 2241103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return offset; 2242103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 2243b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2244103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid 2245103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::appendOffsetDigits(UnicodeString& buf, int32_t n, uint8_t minDigits) const { 2246103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(n >= 0 && n < 60); 2247103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t numDigits = n >= 10 ? 2 : 1; 2248103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t i = 0; i < minDigits - numDigits; i++) { 2249103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius buf.append(fGMTOffsetDigits[0]); 2250103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2251103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (numDigits == 2) { 2252103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius buf.append(fGMTOffsetDigits[n / 10]); 2253103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2254103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius buf.append(fGMTOffsetDigits[n % 10]); 2255103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 2256103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2257103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// ------------------------------------------------------------------ 2258103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius// Private misc 2259103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid 2260103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::initGMTPattern(const UnicodeString& gmtPattern, UErrorCode& status) { 2261103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 2262103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return; 2263103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2264103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // This implementation not perfect, but sufficient practically. 2265103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t idx = gmtPattern.indexOf(ARG0, ARG0_LEN, 0); 2266103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (idx < 0) { 2267103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius status = U_ILLEGAL_ARGUMENT_ERROR; 2268103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return; 2269103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2270103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTPattern.setTo(gmtPattern); 2271103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius unquote(gmtPattern.tempSubString(0, idx), fGMTPatternPrefix); 2272103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius unquote(gmtPattern.tempSubString(idx + ARG0_LEN), fGMTPatternSuffix); 2273103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 2274103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2275103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 2276103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::unquote(const UnicodeString& pattern, UnicodeString& result) { 2277103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (pattern.indexOf(SINGLEQUOTE) < 0) { 2278103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.setTo(pattern); 2279103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return result; 2280103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2281103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.remove(); 2282103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool isPrevQuote = FALSE; 2283103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool inQuote = FALSE; 2284103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t i = 0; i < pattern.length(); i++) { 2285103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar c = pattern.charAt(i); 2286103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (c == SINGLEQUOTE) { 2287103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (isPrevQuote) { 2288103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.append(c); 2289103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius isPrevQuote = FALSE; 2290103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 2291103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius isPrevQuote = TRUE; 2292b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2293103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius inQuote = !inQuote; 2294103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 2295103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius isPrevQuote = FALSE; 2296103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.append(c); 2297b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2298b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2299103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return result; 2300103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 2301b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2302103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUVector* 2303103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::parseOffsetPattern(const UnicodeString& pattern, OffsetFields required, UErrorCode& status) { 2304103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 2305103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return NULL; 2306103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2307103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UVector* result = new UVector(deleteGMTOffsetField, NULL, status); 2308103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (result == NULL) { 2309103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius status = U_MEMORY_ALLOCATION_ERROR; 2310103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return NULL; 2311103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2312b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2313103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t checkBits = 0; 2314103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool isPrevQuote = FALSE; 2315103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UBool inQuote = FALSE; 2316103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UnicodeString text; 2317103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius GMTOffsetField::FieldType itemType = GMTOffsetField::TEXT; 2318103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t itemLength = 1; 2319103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2320103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t i = 0; i < pattern.length(); i++) { 2321103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UChar ch = pattern.charAt(i); 2322103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (ch == SINGLEQUOTE) { 2323103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (isPrevQuote) { 2324103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius text.append(SINGLEQUOTE); 2325103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius isPrevQuote = FALSE; 2326103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 2327103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius isPrevQuote = TRUE; 2328103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (itemType != GMTOffsetField::TEXT) { 2329103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (GMTOffsetField::isValid(itemType, itemLength)) { 2330103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, (uint8_t)itemLength, status); 2331103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result->addElement(fld, status); 2332103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 2333103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2334103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2335103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 2336103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius status = U_ILLEGAL_ARGUMENT_ERROR; 2337103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2338103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2339103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius itemType = GMTOffsetField::TEXT; 2340b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2341b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2342103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius inQuote = !inQuote; 2343103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 2344103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius isPrevQuote = FALSE; 2345103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (inQuote) { 2346103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius text.append(ch); 2347103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 2348103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius GMTOffsetField::FieldType tmpType = GMTOffsetField::getTypeByLetter(ch); 2349103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (tmpType != GMTOffsetField::TEXT) { 2350103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // an offset time pattern character 2351103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (tmpType == itemType) { 2352103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius itemLength++; 2353103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 2354103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (itemType == GMTOffsetField::TEXT) { 2355103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (text.length() > 0) { 2356103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius GMTOffsetField* textfld = GMTOffsetField::createText(text, status); 2357103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result->addElement(textfld, status); 2358103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 2359103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2360103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2361103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius text.remove(); 2362103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2363103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 2364103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (GMTOffsetField::isValid(itemType, itemLength)) { 2365103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, itemLength, status); 2366103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result->addElement(fld, status); 2367103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 2368103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2369103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2370103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 2371103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius status = U_ILLEGAL_ARGUMENT_ERROR; 2372103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2373103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2374103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2375103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius itemType = tmpType; 2376103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius itemLength = 1; 2377103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius checkBits |= tmpType; 2378103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2379b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 2380103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // a string literal 2381103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (itemType != GMTOffsetField::TEXT) { 2382103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (GMTOffsetField::isValid(itemType, itemLength)) { 2383103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, itemLength, status); 2384103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result->addElement(fld, status); 2385103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_FAILURE(status)) { 2386103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2387103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2388103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 2389103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius status = U_ILLEGAL_ARGUMENT_ERROR; 2390103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2391103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2392103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius itemType = GMTOffsetField::TEXT; 2393103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2394103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius text.append(ch); 2395b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2396b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2397103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2398103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2399103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // handle last item 2400103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_SUCCESS(status)) { 2401103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (itemType == GMTOffsetField::TEXT) { 2402103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (text.length() > 0) { 2403103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius GMTOffsetField* tfld = GMTOffsetField::createText(text, status); 2404103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result->addElement(tfld, status); 2405b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2406b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } else { 2407103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (GMTOffsetField::isValid(itemType, itemLength)) { 2408103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius GMTOffsetField* fld = GMTOffsetField::createTimeField(itemType, itemLength, status); 2409103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result->addElement(fld, status); 2410103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } else { 2411103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius status = U_ILLEGAL_ARGUMENT_ERROR; 2412103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2413b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2414103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2415103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // Check all required fields are set 2416103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (U_SUCCESS(status)) { 2417103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t reqBits = 0; 2418103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius switch (required) { 2419103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case FIELDS_H: 2420103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius reqBits = GMTOffsetField::HOUR; 2421103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2422103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case FIELDS_HM: 2423103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius reqBits = GMTOffsetField::HOUR | GMTOffsetField::MINUTE; 2424103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2425103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case FIELDS_HMS: 2426103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius reqBits = GMTOffsetField::HOUR | GMTOffsetField::MINUTE | GMTOffsetField::SECOND; 2427103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2428103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2429103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (checkBits == reqBits) { 2430103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // all required fields are set, no extra fields 2431103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return result; 2432103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2433b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2434b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2435b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2436103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // error 2437103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius delete result; 2438103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return NULL; 2439b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 2440b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2441103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 24428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::expandOffsetPattern(const UnicodeString& offsetHM, UnicodeString& result, UErrorCode& status) { 24438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius result.setToBogus(); 24448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (U_FAILURE(status)) { 24458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return result; 24468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 2447103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(u_strlen(DEFAULT_GMT_OFFSET_MINUTE_PATTERN) == 2); 2448103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2449103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t idx_mm = offsetHM.indexOf(DEFAULT_GMT_OFFSET_MINUTE_PATTERN, 2, 0); 2450103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (idx_mm < 0) { 24518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Bad time zone hour pattern data 24528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius status = U_ILLEGAL_ARGUMENT_ERROR; 2453103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return result; 2454b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2455b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2456103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UnicodeString sep; 245754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t idx_H = offsetHM.tempSubString(0, idx_mm).lastIndexOf((UChar)0x0048 /* H */); 2458103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (idx_H >= 0) { 2459103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius sep = offsetHM.tempSubString(idx_H + 1, idx_mm - (idx_H + 1)); 2460103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2461103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.setTo(offsetHM.tempSubString(0, idx_mm + 2)); 2462103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.append(sep); 2463103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.append(DEFAULT_GMT_OFFSET_SECOND_PATTERN, -1); 2464103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius result.append(offsetHM.tempSubString(idx_mm + 2)); 2465103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return result; 2466b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 2467b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 24688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUnicodeString& 24698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::truncateOffsetPattern(const UnicodeString& offsetHM, UnicodeString& result, UErrorCode& status) { 24708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius result.setToBogus(); 24718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (U_FAILURE(status)) { 24728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return result; 24738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 24748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius U_ASSERT(u_strlen(DEFAULT_GMT_OFFSET_MINUTE_PATTERN) == 2); 24758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 24768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t idx_mm = offsetHM.indexOf(DEFAULT_GMT_OFFSET_MINUTE_PATTERN, 2, 0); 24778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (idx_mm < 0) { 24788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Bad time zone hour pattern data 24798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius status = U_ILLEGAL_ARGUMENT_ERROR; 24808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return result; 24818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 24828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UChar HH[] = {0x0048, 0x0048}; 24838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t idx_HH = offsetHM.tempSubString(0, idx_mm).lastIndexOf(HH, 2, 0); 24848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (idx_HH >= 0) { 24858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return result.setTo(offsetHM.tempSubString(0, idx_HH + 2)); 24868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 24878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t idx_H = offsetHM.tempSubString(0, idx_mm).lastIndexOf((UChar)0x0048, 0); 24888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (idx_H >= 0) { 24898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return result.setTo(offsetHM.tempSubString(0, idx_H + 1)); 24908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 24918393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius // Bad time zone hour pattern data 24928393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius status = U_ILLEGAL_ARGUMENT_ERROR; 24938393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return result; 24948393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 24958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 2496103e9ffba2cba345d0078eb8b8db33249f81840aCraig Corneliusvoid 2497103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::initGMTOffsetPatterns(UErrorCode& status) { 24988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius for (int32_t type = 0; type < UTZFMT_PAT_COUNT; type++) { 2499103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius switch (type) { 25008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_PAT_POSITIVE_H: 25018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius case UTZFMT_PAT_NEGATIVE_H: 25028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius fGMTOffsetPatternItems[type] = parseOffsetPattern(fGMTOffsetPatterns[type], FIELDS_H, status); 25038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 2504103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_PAT_POSITIVE_HM: 2505103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_PAT_NEGATIVE_HM: 2506103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTOffsetPatternItems[type] = parseOffsetPattern(fGMTOffsetPatterns[type], FIELDS_HM, status); 2507103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2508103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_PAT_POSITIVE_HMS: 2509103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZFMT_PAT_NEGATIVE_HMS: 2510103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fGMTOffsetPatternItems[type] = parseOffsetPattern(fGMTOffsetPatterns[type], FIELDS_HMS, status); 2511103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius break; 2512103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2513103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 25148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius checkAbuttingHoursAndMinutes(); 25158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 25168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 25178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusvoid 25188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::checkAbuttingHoursAndMinutes() { 25198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius fAbuttingOffsetHoursAndMinutes= FALSE; 25208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius for (int32_t type = 0; type < UTZFMT_PAT_COUNT; type++) { 25218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UBool afterH = FALSE; 25228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UVector *items = fGMTOffsetPatternItems[type]; 25238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius for (int32_t i = 0; i < items->size(); i++) { 25248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius const GMTOffsetField* item = (GMTOffsetField*)items->elementAt(i); 25258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius GMTOffsetField::FieldType type = item->getType(); 25268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (type != GMTOffsetField::TEXT) { 25278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (afterH) { 25288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius fAbuttingOffsetHoursAndMinutes = TRUE; 25298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 25308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else if (type == GMTOffsetField::HOUR) { 25318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius afterH = TRUE; 25328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 25338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else if (afterH) { 25348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 25358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 25368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 25378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (fAbuttingOffsetHoursAndMinutes) { 25388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius break; 25398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 25408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 2541b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 2542b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2543103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUBool 2544103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::toCodePoints(const UnicodeString& str, UChar32* codeArray, int32_t size) { 2545103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius int32_t count = str.countChar32(); 2546103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (count != size) { 2547103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return FALSE; 2548103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2549b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2550103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius for (int32_t idx = 0, start = 0; idx < size; idx++) { 2551103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius codeArray[idx] = str.char32At(start); 2552103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius start = str.moveIndex32(start, 1); 2553103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2554b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2555103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return TRUE; 2556b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 2557b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2558b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoTimeZone* 2559103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::createTimeZoneForOffset(int32_t offset) const { 2560103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (offset == 0) { 2561103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius // when offset is 0, we should use "Etc/GMT" 2562103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return TimeZone::createTimeZone(UnicodeString(TZID_GMT)); 2563b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2564103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return ZoneMeta::createCustomTimeZone(offset); 2565b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 2566b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2567103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUTimeZoneFormatTimeType 2568103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::getTimeType(UTimeZoneNameType nameType) { 2569103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius switch (nameType) { 2570103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZNM_LONG_STANDARD: 2571103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZNM_SHORT_STANDARD: 2572103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return UTZFMT_TIME_TYPE_STANDARD; 2573103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2574103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZNM_LONG_DAYLIGHT: 2575103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius case UTZNM_SHORT_DAYLIGHT: 2576103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return UTZFMT_TIME_TYPE_DAYLIGHT; 2577103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 2578103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius default: 2579103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius U_ASSERT(FALSE); 2580b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho } 2581103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return UTZFMT_TIME_TYPE_UNKNOWN; 2582b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho} 2583b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2584103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusUnicodeString& 2585103e9ffba2cba345d0078eb8b8db33249f81840aCraig CorneliusTimeZoneFormat::getTimeZoneID(const TimeZoneNames::MatchInfoCollection* matches, int32_t idx, UnicodeString& tzID) const { 2586103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (!matches->getTimeZoneIDAt(idx, tzID)) { 2587103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius UnicodeString mzID; 2588103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius if (matches->getMetaZoneIDAt(idx, mzID)) { 2589103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius fTimeZoneNames->getReferenceZoneID(mzID, fTargetRegion, tzID); 2590103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2591103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius } 2592103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius return tzID; 2593103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius} 2594b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 25958393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 25968393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusclass ZoneIdMatchHandler : public TextTrieMapSearchResultHandler { 25978393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliuspublic: 25988393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius ZoneIdMatchHandler(); 25998393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius virtual ~ZoneIdMatchHandler(); 26008393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 26018393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UBool handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status); 26028393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius const UChar* getID(); 26038393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t getMatchLen(); 26048393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusprivate: 26058393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t fLen; 26068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius const UChar* fID; 26078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius}; 26088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 26098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusZoneIdMatchHandler::ZoneIdMatchHandler() 26108393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius: fLen(0), fID(NULL) { 26118393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 26128393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 26138393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusZoneIdMatchHandler::~ZoneIdMatchHandler() { 26148393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 26158393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 26168393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUBool 26178393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusZoneIdMatchHandler::handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status) { 26188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (U_FAILURE(status)) { 26198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return FALSE; 26208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 26218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (node->hasValues()) { 26228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius const UChar* id = (const UChar*)node->getValue(0); 26238393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (id != NULL) { 26248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (fLen < matchLength) { 26258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius fID = id; 26268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius fLen = matchLength; 26278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 26288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 26298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 26308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return TRUE; 26318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 26328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 26338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusconst UChar* 26348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusZoneIdMatchHandler::getID() { 26358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return fID; 26368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 26378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 26388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Corneliusint32_t 26398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusZoneIdMatchHandler::getMatchLen() { 26408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return fLen; 26418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 26428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 264359d709d503bab6e2b61931737e662dd293b40578ccornelius 264459d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void U_CALLCONV initZoneIdTrie(UErrorCode &status) { 264559d709d503bab6e2b61931737e662dd293b40578ccornelius U_ASSERT(gZoneIdTrie == NULL); 264659d709d503bab6e2b61931737e662dd293b40578ccornelius ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONEFORMAT, tzfmt_cleanup); 264759d709d503bab6e2b61931737e662dd293b40578ccornelius gZoneIdTrie = new TextTrieMap(TRUE, NULL); // No deleter, because values are pooled by ZoneMeta 264859d709d503bab6e2b61931737e662dd293b40578ccornelius if (gZoneIdTrie == NULL) { 264959d709d503bab6e2b61931737e662dd293b40578ccornelius status = U_MEMORY_ALLOCATION_ERROR; 265059d709d503bab6e2b61931737e662dd293b40578ccornelius return; 265159d709d503bab6e2b61931737e662dd293b40578ccornelius } 265259d709d503bab6e2b61931737e662dd293b40578ccornelius StringEnumeration *tzenum = TimeZone::createEnumeration(); 265359d709d503bab6e2b61931737e662dd293b40578ccornelius const UnicodeString *id; 265459d709d503bab6e2b61931737e662dd293b40578ccornelius while ((id = tzenum->snext(status))) { 265559d709d503bab6e2b61931737e662dd293b40578ccornelius const UChar* uid = ZoneMeta::findTimeZoneID(*id); 265659d709d503bab6e2b61931737e662dd293b40578ccornelius if (uid) { 265759d709d503bab6e2b61931737e662dd293b40578ccornelius gZoneIdTrie->put(uid, const_cast<UChar *>(uid), status); 265859d709d503bab6e2b61931737e662dd293b40578ccornelius } 265959d709d503bab6e2b61931737e662dd293b40578ccornelius } 266059d709d503bab6e2b61931737e662dd293b40578ccornelius delete tzenum; 266159d709d503bab6e2b61931737e662dd293b40578ccornelius} 266259d709d503bab6e2b61931737e662dd293b40578ccornelius 266359d709d503bab6e2b61931737e662dd293b40578ccornelius 26648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUnicodeString& 26658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::parseZoneID(const UnicodeString& text, ParsePosition& pos, UnicodeString& tzID) const { 26668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UErrorCode status = U_ZERO_ERROR; 266759d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_initOnce(gZoneIdTrieInitOnce, &initZoneIdTrie, status); 26688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 26698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t start = pos.getIndex(); 26708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t len = 0; 26718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tzID.setToBogus(); 26728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 267359d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_SUCCESS(status)) { 26748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius LocalPointer<ZoneIdMatchHandler> handler(new ZoneIdMatchHandler()); 26758393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius gZoneIdTrie->search(text, start, handler.getAlias(), status); 26768393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius len = handler->getMatchLen(); 26778393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (len > 0) { 26788393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tzID.setTo(handler->getID(), -1); 26798393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 26808393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 26818393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 26828393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (len > 0) { 26838393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius pos.setIndex(start + len); 26848393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else { 26858393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius pos.setErrorIndex(start); 26868393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 26878393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 26888393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return tzID; 26898393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 26908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 269159d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void U_CALLCONV initShortZoneIdTrie(UErrorCode &status) { 269259d709d503bab6e2b61931737e662dd293b40578ccornelius U_ASSERT(gShortZoneIdTrie == NULL); 269359d709d503bab6e2b61931737e662dd293b40578ccornelius ucln_i18n_registerCleanup(UCLN_I18N_TIMEZONEFORMAT, tzfmt_cleanup); 269459d709d503bab6e2b61931737e662dd293b40578ccornelius StringEnumeration *tzenum = TimeZone::createTimeZoneIDEnumeration(UCAL_ZONE_TYPE_CANONICAL, NULL, NULL, status); 269559d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_SUCCESS(status)) { 269659d709d503bab6e2b61931737e662dd293b40578ccornelius gShortZoneIdTrie = new TextTrieMap(TRUE, NULL); // No deleter, because values are pooled by ZoneMeta 269759d709d503bab6e2b61931737e662dd293b40578ccornelius if (gShortZoneIdTrie == NULL) { 269859d709d503bab6e2b61931737e662dd293b40578ccornelius status = U_MEMORY_ALLOCATION_ERROR; 269959d709d503bab6e2b61931737e662dd293b40578ccornelius } else { 270059d709d503bab6e2b61931737e662dd293b40578ccornelius const UnicodeString *id; 270159d709d503bab6e2b61931737e662dd293b40578ccornelius while ((id = tzenum->snext(status))) { 270259d709d503bab6e2b61931737e662dd293b40578ccornelius const UChar* uID = ZoneMeta::findTimeZoneID(*id); 270359d709d503bab6e2b61931737e662dd293b40578ccornelius const UChar* shortID = ZoneMeta::getShortID(*id); 270459d709d503bab6e2b61931737e662dd293b40578ccornelius if (shortID && uID) { 270559d709d503bab6e2b61931737e662dd293b40578ccornelius gShortZoneIdTrie->put(shortID, const_cast<UChar *>(uID), status); 27068393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 27078393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 27088393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 27098393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 271059d709d503bab6e2b61931737e662dd293b40578ccornelius delete tzenum; 271159d709d503bab6e2b61931737e662dd293b40578ccornelius} 271259d709d503bab6e2b61931737e662dd293b40578ccornelius 271359d709d503bab6e2b61931737e662dd293b40578ccornelius 271459d709d503bab6e2b61931737e662dd293b40578ccorneliusUnicodeString& 271559d709d503bab6e2b61931737e662dd293b40578ccorneliusTimeZoneFormat::parseShortZoneID(const UnicodeString& text, ParsePosition& pos, UnicodeString& tzID) const { 271659d709d503bab6e2b61931737e662dd293b40578ccornelius UErrorCode status = U_ZERO_ERROR; 271759d709d503bab6e2b61931737e662dd293b40578ccornelius umtx_initOnce(gShortZoneIdTrieInitOnce, &initShortZoneIdTrie, status); 27188393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 27198393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t start = pos.getIndex(); 27208393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t len = 0; 27218393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tzID.setToBogus(); 27228393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 272359d709d503bab6e2b61931737e662dd293b40578ccornelius if (U_SUCCESS(status)) { 27248393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius LocalPointer<ZoneIdMatchHandler> handler(new ZoneIdMatchHandler()); 27258393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius gShortZoneIdTrie->search(text, start, handler.getAlias(), status); 27268393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius len = handler->getMatchLen(); 27278393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (len > 0) { 27288393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tzID.setTo(handler->getID(), -1); 27298393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 27308393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 27318393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 27328393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (len > 0) { 27338393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius pos.setIndex(start + len); 27348393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } else { 27358393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius pos.setErrorIndex(start); 27368393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 27378393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 27388393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return tzID; 27398393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 27408393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 27418393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 27428393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusUnicodeString& 27438393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig CorneliusTimeZoneFormat::parseExemplarLocation(const UnicodeString& text, ParsePosition& pos, UnicodeString& tzID) const { 27448393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t startIdx = pos.getIndex(); 27458393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t parsedPos = -1; 27468393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius tzID.setToBogus(); 27478393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 27488393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius UErrorCode status = U_ZERO_ERROR; 27498393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius LocalPointer<TimeZoneNames::MatchInfoCollection> exemplarMatches(fTimeZoneNames->find(text, startIdx, UTZNM_EXEMPLAR_LOCATION, status)); 27508393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (U_FAILURE(status)) { 27518393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius pos.setErrorIndex(startIdx); 27528393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return tzID; 27538393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 27548393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius int32_t matchIdx = -1; 27558393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (!exemplarMatches.isNull()) { 27568393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius for (int32_t i = 0; i < exemplarMatches->size(); i++) { 27578393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (startIdx + exemplarMatches->getMatchLengthAt(i) > parsedPos) { 27588393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius matchIdx = i; 27598393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius parsedPos = startIdx + exemplarMatches->getMatchLengthAt(i); 27608393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 27618393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 27628393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (parsedPos > 0) { 27638393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius pos.setIndex(parsedPos); 27648393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius getTimeZoneID(exemplarMatches.getAlias(), matchIdx, tzID); 27658393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 27668393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 27678393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 27688393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius if (tzID.length() == 0) { 27698393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius pos.setErrorIndex(startIdx); 27708393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius } 27718393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 27728393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius return tzID; 27738393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius} 27748393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius 2775b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2clairehoU_NAMESPACE_END 2776b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho 2777b26ce3a7367e4ed2ee7ddddcdc3f3d3377a455c2claireho#endif 2778