mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-21 12:40:02 +00:00
ICU-7489 Optimize tz canonicalization for zones that are already canonical
X-SVN-Rev: 28535
This commit is contained in:
parent
590648b41e
commit
090df3b5a4
2 changed files with 77 additions and 43 deletions
|
@ -85,19 +85,6 @@ timezoneTypes:table(nofallback){
|
|||
"Pacific:Pohnpei"{"Pacific/Ponape"}
|
||||
"Pacific:Samoa"{"Pacific/Pago_Pago"}
|
||||
"Pacific:Yap"{"Pacific/Truk"}
|
||||
"SystemV:AST4"{"Etc/GMT+4"}
|
||||
"SystemV:AST4ADT"{"America/Halifax"}
|
||||
"SystemV:CST6"{"Etc/GMT+6"}
|
||||
"SystemV:CST6CDT"{"CST6CDT"}
|
||||
"SystemV:EST5"{"Etc/GMT+5"}
|
||||
"SystemV:EST5EDT"{"EST5EDT"}
|
||||
"SystemV:HST10"{"Etc/GMT+10"}
|
||||
"SystemV:MST7"{"Etc/GMT+7"}
|
||||
"SystemV:MST7MDT"{"MST7MDT"}
|
||||
"SystemV:PST8"{"Etc/GMT+8"}
|
||||
"SystemV:PST8PDT"{"PST8PDT"}
|
||||
"SystemV:YST9"{"Etc/GMT+9"}
|
||||
"SystemV:YST9YDT"{"America/Anchorage"}
|
||||
"US:Alaska"{"America/Anchorage"}
|
||||
"US:Aleutian"{"America/Adak"}
|
||||
"US:Arizona"{"America/Phoenix"}
|
||||
|
|
|
@ -93,8 +93,9 @@ static const char gMetaZones[] = "metaZones";
|
|||
static const char gMetazoneInfo[] = "metazoneInfo";
|
||||
static const char gMapTimezonesTag[] = "mapTimezones";
|
||||
|
||||
static const char gKeyTypeData[] = "keyTypeData";
|
||||
static const char gTimeZoneTypes[] = "timezoneTypes";
|
||||
static const char gTypeAliasTag[] = "typeAlias";
|
||||
static const char gTypeMapTag[] = "typeMap";
|
||||
static const char gTimezoneTag[] = "timezone";
|
||||
|
||||
static const char gWorldTag[] = "001";
|
||||
|
@ -185,43 +186,89 @@ parseDate (const UChar *text, UErrorCode &status) {
|
|||
|
||||
UnicodeString& U_EXPORT2
|
||||
ZoneMeta::getCanonicalSystemID(const UnicodeString &tzid, UnicodeString &systemID, UErrorCode& status) {
|
||||
// Dereference the input ID using the tz data first
|
||||
const UChar *canonical = TimeZone::dereferOlsonLink(tzid);
|
||||
if (canonical != NULL) {
|
||||
// check canonical mapping in CLDR
|
||||
char id[ZID_KEY_MAX];
|
||||
int32_t len = u_strlen(canonical);
|
||||
if (len < (int32_t)sizeof(id)) {
|
||||
u_UCharsToChars(canonical, id, len + 1 /* include the terminator */);
|
||||
// replace '/' with ':'
|
||||
char *p = id;
|
||||
while (*p) {
|
||||
if (*p == '/') {
|
||||
*p = ':';
|
||||
}
|
||||
p++;
|
||||
}
|
||||
int32_t len = tzid.length();
|
||||
if ( len >= ZID_KEY_MAX ) {
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
systemID.remove();
|
||||
return systemID;
|
||||
}
|
||||
|
||||
UErrorCode tmpStatus = U_ZERO_ERROR;
|
||||
UResourceBundle *rb = ures_openDirect(NULL, gKeyTypeData, &tmpStatus);
|
||||
ures_getByKey(rb, gTypeAliasTag, rb, &tmpStatus);
|
||||
ures_getByKey(rb, gTimezoneTag, rb, &tmpStatus);
|
||||
const UChar *cldrCanonical = ures_getStringByKey(rb, id, NULL, &tmpStatus);
|
||||
if (U_SUCCESS(tmpStatus)) {
|
||||
// canonical map found
|
||||
canonical = cldrCanonical;
|
||||
}
|
||||
ures_close(rb);
|
||||
char id[ZID_KEY_MAX];
|
||||
const UChar* idChars = tzid.getBuffer();
|
||||
|
||||
u_UCharsToChars(idChars,id,len);
|
||||
id[len] = (char) 0; // Make sure it is null terminated.
|
||||
|
||||
// replace '/' with ':'
|
||||
char *p = id;
|
||||
while (*p++) {
|
||||
if (*p == '/') {
|
||||
*p = ':';
|
||||
}
|
||||
}
|
||||
if (canonical == NULL) {
|
||||
|
||||
|
||||
UErrorCode tmpStatus = U_ZERO_ERROR;
|
||||
UResourceBundle *top = ures_openDirect(NULL, gTimeZoneTypes, &tmpStatus);
|
||||
UResourceBundle *rb = ures_getByKey(top, gTypeMapTag, NULL, &tmpStatus);
|
||||
ures_getByKey(rb, gTimezoneTag, rb, &tmpStatus);
|
||||
ures_getByKey(rb, id, rb, &tmpStatus);
|
||||
if (U_SUCCESS(tmpStatus)) {
|
||||
// direct map found
|
||||
systemID.setTo(tzid);
|
||||
ures_close(rb);
|
||||
ures_close(top);
|
||||
return systemID;
|
||||
}
|
||||
|
||||
// If a map element not found, then look for an alias
|
||||
tmpStatus = U_ZERO_ERROR;
|
||||
ures_getByKey(top, gTypeAliasTag, rb, &tmpStatus);
|
||||
ures_getByKey(rb, gTimezoneTag, rb, &tmpStatus);
|
||||
const UChar *alias = ures_getStringByKey(rb,id,NULL,&tmpStatus);
|
||||
if (U_SUCCESS(tmpStatus)) {
|
||||
// alias found
|
||||
ures_close(rb);
|
||||
ures_close(top);
|
||||
systemID.setTo(alias);
|
||||
return systemID;
|
||||
}
|
||||
|
||||
// Dereference the input ID using the tz data
|
||||
const UChar *derefer = TimeZone::dereferOlsonLink(tzid);
|
||||
if (derefer == NULL) {
|
||||
systemID.remove();
|
||||
status = U_ILLEGAL_ARGUMENT_ERROR;
|
||||
} else {
|
||||
systemID.setTo(canonical);
|
||||
|
||||
len = u_strlen(derefer);
|
||||
u_UCharsToChars(derefer,id,len);
|
||||
id[len] = (char) 0; // Make sure it is null terminated.
|
||||
|
||||
// replace '/' with ':'
|
||||
char *p = id;
|
||||
while (*p++) {
|
||||
if (*p == '/') {
|
||||
*p = ':';
|
||||
}
|
||||
}
|
||||
|
||||
// If a dereference turned something up then look for an alias.
|
||||
// rb still points to the alias table, so we don't have to go looking
|
||||
// for it.
|
||||
tmpStatus = U_ZERO_ERROR;
|
||||
const UChar *alias = ures_getStringByKey(rb,id,NULL,&tmpStatus);
|
||||
if (U_SUCCESS(tmpStatus)) {
|
||||
// alias found
|
||||
systemID.setTo(alias);
|
||||
} else {
|
||||
systemID.setTo(derefer);
|
||||
}
|
||||
}
|
||||
|
||||
return systemID;
|
||||
ures_close(rb);
|
||||
ures_close(top);
|
||||
return systemID;
|
||||
}
|
||||
|
||||
UnicodeString& U_EXPORT2
|
||||
|
|
Loading…
Add table
Reference in a new issue