mirror of
https://github.com/unicode-org/icu.git
synced 2025-04-13 08:53:20 +00:00
ICU-10934 The tz database abbreviation support in ICU4C
X-SVN-Rev: 36080
This commit is contained in:
parent
133a0ebab9
commit
ae3f6f13a4
13 changed files with 1732 additions and 40 deletions
1
.gitattributes
vendored
1
.gitattributes
vendored
|
@ -70,6 +70,7 @@ icu4c/source/data/makedata.vcxproj -text
|
|||
icu4c/source/data/makedata.vcxproj.filters -text
|
||||
icu4c/source/data/region/pool.res -text
|
||||
icu4c/source/data/zone/pool.res -text
|
||||
icu4c/source/data/zone/tzdbNames.txt -text
|
||||
icu4c/source/extra/uconv/uconv.vcxproj -text
|
||||
icu4c/source/extra/uconv/uconv.vcxproj.filters -text
|
||||
icu4c/source/i18n/i18n.vcxproj -text
|
||||
|
|
|
@ -322,7 +322,7 @@ REGION_SRC_FILES = $(REGION_SRC:%=$(REGIONSRCDIR)/%)
|
|||
INSTALLED_REGION_FILES = $(REGION_SOURCE:%.txt=%) $(REGION_SOURCE_LOCAL:%.txt=%)
|
||||
endif
|
||||
ifdef ZONE_SOURCE
|
||||
ZONE_SRC= root.txt $(ZONE_SOURCE) $(ZONE_ALIAS_SOURCE) $(ZONE_SOURCE_LOCAL)
|
||||
ZONE_SRC= root.txt $(ZONE_SOURCE) $(ZONE_ALIAS_SOURCE) $(ZONE_SOURCE_LOCAL) tzdbNames.txt
|
||||
ZONE_SRC_FILES = $(ZONE_SRC:%=$(ZONESRCDIR)/%)
|
||||
INSTALLED_ZONE_FILES = $(ZONE_SOURCE:%.txt=%) $(ZONE_SOURCE_LOCAL:%.txt=%)
|
||||
endif
|
||||
|
|
|
@ -116,5 +116,6 @@ ZONE_SOURCE = af.txt agq.txt ak.txt am.txt\
|
|||
vai.txt vai_Latn.txt vai_Vaii.txt vi.txt vun.txt\
|
||||
xog.txt yav.txt yo.txt zgh.txt zh.txt\
|
||||
zh_Hans.txt zh_Hans_HK.txt zh_Hans_MO.txt zh_Hans_SG.txt zh_Hant.txt\
|
||||
zh_Hant_HK.txt zh_Hant_MO.txt zu.txt
|
||||
zh_Hant_HK.txt zh_Hant_MO.txt zu.txt\
|
||||
tzdbNames.txt
|
||||
|
||||
|
|
709
icu4c/source/data/zone/tzdbNames.txt
Normal file
709
icu4c/source/data/zone/tzdbNames.txt
Normal file
|
@ -0,0 +1,709 @@
|
|||
// ***************************************************************************
|
||||
// *
|
||||
// * Copyright (C) 2014 International Business Machines
|
||||
// * Corporation and others. All Rights Reserved.
|
||||
// *
|
||||
// * This file is manually edited for supporting the tz database name
|
||||
// * compatibility.
|
||||
// *
|
||||
// ***************************************************************************#
|
||||
tzdbNames{
|
||||
zoneStrings{
|
||||
"meta:Acre"{
|
||||
sd{"ACST"}
|
||||
ss{"ACT"}
|
||||
}
|
||||
"meta:Afghanistan"{
|
||||
ss{"AFT"}
|
||||
}
|
||||
"meta:Africa_Central"{
|
||||
sd{"CAST"}
|
||||
ss{"CAT"}
|
||||
}
|
||||
"meta:Africa_Eastern"{
|
||||
sd{"EAST"}
|
||||
ss{"EAT"}
|
||||
}
|
||||
"meta:Africa_FarWestern"{
|
||||
ss{"WAT"}
|
||||
parseRegions{""} // this metazone is never used for parsing
|
||||
}
|
||||
"meta:Africa_Southern"{
|
||||
ss{"SAST"}
|
||||
}
|
||||
"meta:Africa_Western"{
|
||||
sd{"WAST"}
|
||||
ss{"WAT"}
|
||||
}
|
||||
"meta:Aktyubinsk"{
|
||||
sd{"AKTST"}
|
||||
ss{"AKTT"}
|
||||
}
|
||||
"meta:Alaska"{
|
||||
sd{"AKDT"}
|
||||
ss{"AKST"}
|
||||
}
|
||||
"meta:Alaska_Hawaii"{
|
||||
sd{"AHDT"}
|
||||
ss{"AHST"}
|
||||
}
|
||||
"meta:Almaty"{
|
||||
sd{"ALMST"}
|
||||
ss{"ALMT"}
|
||||
parseRegions{""} // this metazone is never used for parsing
|
||||
}
|
||||
"meta:Amazon"{
|
||||
sd{"AMST"}
|
||||
ss{"AMT"}
|
||||
}
|
||||
"meta:America_Central"{
|
||||
sd{"CDT"}
|
||||
ss{"CST"}
|
||||
}
|
||||
"meta:America_Eastern"{
|
||||
sd{"EDT"}
|
||||
ss{"EST"}
|
||||
}
|
||||
"meta:America_Mountain"{
|
||||
sd{"MDT"}
|
||||
ss{"MST"}
|
||||
}
|
||||
"meta:America_Pacific"{
|
||||
sd{"PDT"}
|
||||
ss{"PST"}
|
||||
}
|
||||
"meta:Anadyr"{
|
||||
sd{"ANAST"}
|
||||
ss{"ANAT"}
|
||||
}
|
||||
"meta:Aqtau"{
|
||||
sd{"AQTST"}
|
||||
ss{"AQTT"}
|
||||
parseRegions{""} // this metazone is never used for parsing
|
||||
}
|
||||
"meta:Aqtobe"{
|
||||
sd{"AQTST"}
|
||||
ss{"AQTT"}
|
||||
parseRegions{""} // this metazone is never used for parsing
|
||||
}
|
||||
"meta:Arabian"{
|
||||
sd{"ADT"}
|
||||
ss{"AST"}
|
||||
parseRegions{"BH", "IQ", "KW", "QA", "SA", "YE"}
|
||||
}
|
||||
"meta:Argentina"{
|
||||
sd{"ARST"}
|
||||
ss{"ART"}
|
||||
}
|
||||
"meta:Argentina_Western"{
|
||||
sd{"WARST"}
|
||||
ss{"WART"}
|
||||
}
|
||||
"meta:Armenia"{
|
||||
sd{"AMST"}
|
||||
ss{"AMT"}
|
||||
parseRegions{"AM"}
|
||||
}
|
||||
"meta:Ashkhabad"{
|
||||
sd{"ASHST"}
|
||||
ss{"ASHT"}
|
||||
}
|
||||
"meta:Atlantic"{
|
||||
sd{"ADT"}
|
||||
ss{"AST"}
|
||||
}
|
||||
"meta:Australia_Central"{
|
||||
sd{"CST"}
|
||||
ss{"CST"}
|
||||
parseRegions{"AU"}
|
||||
}
|
||||
"meta:Australia_CentralWestern"{
|
||||
sd{"CWST"}
|
||||
ss{"CWST"}
|
||||
}
|
||||
"meta:Australia_Eastern"{
|
||||
sd{"EST"}
|
||||
ss{"EST"}
|
||||
parseRegions{"AU"}
|
||||
}
|
||||
"meta:Australia_Western"{
|
||||
sd{"WST"}
|
||||
ss{"WST"}
|
||||
}
|
||||
"meta:Azerbaijan"{
|
||||
sd{"AZT"}
|
||||
ss{"AZST"}
|
||||
}
|
||||
"meta:Azores"{
|
||||
sd{"AZOST"}
|
||||
ss{"AZOT"}
|
||||
}
|
||||
"meta:Baku"{
|
||||
sd{"BAKST"}
|
||||
ss{"BAKT"}
|
||||
}
|
||||
"meta:Bangladesh"{
|
||||
sd{"BDST"}
|
||||
ss{"BDT"}
|
||||
}
|
||||
"meta:Bering"{
|
||||
sd{"BDT"}
|
||||
ss{"BST"}
|
||||
parseRegions{""} // this metazone is never used for parsing
|
||||
}
|
||||
"meta:Bhutan"{
|
||||
ss{"BTT"}
|
||||
}
|
||||
"meta:Bolivia"{
|
||||
ss{"BOT"}
|
||||
}
|
||||
"meta:Borneo"{
|
||||
ss{"BORT"}
|
||||
}
|
||||
"meta:Brasilia"{
|
||||
sd{"BRST"}
|
||||
ss{"BRT"}
|
||||
}
|
||||
"meta:British"{
|
||||
sd{"BST"}
|
||||
parseRegions{""} // this metazone is never used for parsing
|
||||
}
|
||||
"meta:Brunei"{
|
||||
ss{"BNT"}
|
||||
}
|
||||
"meta:Cape_Verde"{
|
||||
sd{"CVST"}
|
||||
ss{"CVT"}
|
||||
}
|
||||
"meta:Casey"{
|
||||
ss{"CAST"}
|
||||
parseRegions{"AQ"}
|
||||
}
|
||||
"meta:Chamorro"{
|
||||
ss{"ChST"}
|
||||
}
|
||||
"meta:Changbai"{
|
||||
ss{"CHAT"}
|
||||
}
|
||||
"meta:Chatham"{
|
||||
sd{"CHAST"}
|
||||
ss{"CHADT"}
|
||||
}
|
||||
"meta:Chile"{
|
||||
sd{"CLST"}
|
||||
ss{"CLT"}
|
||||
}
|
||||
"meta:China"{
|
||||
sd{"CDT"}
|
||||
ss{"CST"}
|
||||
parseRegions{"CN", "MO", "TW"}
|
||||
}
|
||||
"meta:Choibalsan"{
|
||||
sd{"CHOST"}
|
||||
ss{"CHOT"}
|
||||
}
|
||||
"meta:Christmas"{
|
||||
ss{"CXT"}
|
||||
}
|
||||
"meta:Cocos"{
|
||||
ss{"CCT"}
|
||||
}
|
||||
"meta:Colombia"{
|
||||
sd{"COST"}
|
||||
ss{"COT"}
|
||||
}
|
||||
"meta:Cook"{
|
||||
sd{"CKHST"}
|
||||
ss{"CKT"}
|
||||
}
|
||||
"meta:Cuba"{
|
||||
sd{"CDT"}
|
||||
ss{"CST"}
|
||||
parseRegions{"CU"}
|
||||
}
|
||||
"meta:Dacca"{
|
||||
ss{"DACT"}
|
||||
}
|
||||
"meta:Davis"{
|
||||
ss{"DAVT"}
|
||||
}
|
||||
"meta:Dominican"{
|
||||
sd{"EHDT"}
|
||||
ss{"EST"}
|
||||
}
|
||||
"meta:DumontDUrville"{
|
||||
ss{"DDUT"}
|
||||
}
|
||||
"meta:Dushanbe"{
|
||||
sd{"DUSST"}
|
||||
ss{"DUST"}
|
||||
}
|
||||
"meta:Dutch_Guiana"{
|
||||
ss{"NEGT"}
|
||||
}
|
||||
"meta:East_Timor"{
|
||||
ss{"TLT"}
|
||||
}
|
||||
"meta:Easter"{
|
||||
sd{"EASST"}
|
||||
ss{"EAST"}
|
||||
parseRegions{"CL"}
|
||||
}
|
||||
"meta:Ecuador"{
|
||||
ss{"ECT"}
|
||||
}
|
||||
"meta:Europe_Central"{
|
||||
sd{"CEST"}
|
||||
ss{"CET"}
|
||||
}
|
||||
"meta:Europe_Eastern"{
|
||||
sd{"EEST"}
|
||||
ss{"EET"}
|
||||
}
|
||||
"meta:Europe_Western"{
|
||||
sd{"WEST"}
|
||||
ss{"WET"}
|
||||
}
|
||||
"meta:Falkland"{
|
||||
ss{"FKST"}
|
||||
}
|
||||
"meta:Fiji"{
|
||||
sd{"FJST"}
|
||||
ss{"FJT"}
|
||||
}
|
||||
"meta:French_Guiana"{
|
||||
ss{"GFT"}
|
||||
}
|
||||
"meta:French_Southern"{
|
||||
ss{"TFT"}
|
||||
}
|
||||
"meta:Frunze"{
|
||||
sd{"FRUST"}
|
||||
ss{"FRUT"}
|
||||
}
|
||||
"meta:GMT"{
|
||||
ss{"GMT"}
|
||||
}
|
||||
"meta:Galapagos"{
|
||||
ss{"GALT"}
|
||||
}
|
||||
"meta:Gambier"{
|
||||
ss{"GAMT"}
|
||||
}
|
||||
"meta:Georgia"{
|
||||
sd{"GEST"}
|
||||
ss{"GET"}
|
||||
}
|
||||
"meta:Gilbert_Islands"{
|
||||
ss{"GILT"}
|
||||
}
|
||||
"meta:Goose_Bay"{
|
||||
sd{"ADT"}
|
||||
ss{"AST"}
|
||||
parseRegions{"CA"}
|
||||
}
|
||||
"meta:Greenland_Central"{
|
||||
sd{"CGST"}
|
||||
ss{"CGT"}
|
||||
}
|
||||
"meta:Greenland_Eastern"{
|
||||
sd{"EGST"}
|
||||
ss{"EGT"}
|
||||
}
|
||||
"meta:Greenland_Western"{
|
||||
sd{"WGST"}
|
||||
ss{"WGT"}
|
||||
}
|
||||
"meta:Guam"{
|
||||
ss{"GST"}
|
||||
parseRegions{""} // this metazone is never used for parsing
|
||||
}
|
||||
"meta:Gulf"{
|
||||
ss{"GST"}
|
||||
}
|
||||
"meta:Guyana"{
|
||||
ss{"GYT"}
|
||||
}
|
||||
"meta:Hawaii_Aleutian"{
|
||||
sd{"HDT"}
|
||||
ss{"HST"}
|
||||
}
|
||||
"meta:Hong_Kong"{
|
||||
sd{"HKST"}
|
||||
ss{"HKT"}
|
||||
}
|
||||
"meta:Hovd"{
|
||||
sd{"HOVST"}
|
||||
ss{"HOVT"}
|
||||
}
|
||||
"meta:India"{
|
||||
ss{"IST"}
|
||||
}
|
||||
"meta:Indian_Ocean"{
|
||||
ss{"IOT"}
|
||||
}
|
||||
"meta:Indochina"{
|
||||
ss{"ICT"}
|
||||
}
|
||||
"meta:Indonesia_Central"{
|
||||
ss{"WITA"}
|
||||
}
|
||||
"meta:Indonesia_Eastern"{
|
||||
ss{"WIT"}
|
||||
}
|
||||
"meta:Indonesia_Western"{
|
||||
ss{"WIB"}
|
||||
}
|
||||
"meta:Iran"{
|
||||
sd{"IRDT"}
|
||||
ss{"IRST"}
|
||||
}
|
||||
"meta:Irkutsk"{
|
||||
sd{"IRKST"}
|
||||
ss{"IRKT"}
|
||||
}
|
||||
"meta:Israel"{
|
||||
sd{"IDT"}
|
||||
ss{"IST"}
|
||||
parseRegions{"IL", "PS"}
|
||||
}
|
||||
"meta:Japan"{
|
||||
sd{"JDT"}
|
||||
ss{"JST"}
|
||||
}
|
||||
"meta:Kamchatka"{
|
||||
sd{"PETST"}
|
||||
ss{"PETT"}
|
||||
}
|
||||
"meta:Karachi"{
|
||||
ss{"KART"}
|
||||
}
|
||||
"meta:Kashgar"{
|
||||
ss{"KAST"}
|
||||
}
|
||||
"meta:Kazakhstan_Eastern"{
|
||||
sd{"ALMST"}
|
||||
ss{"ALMT"}
|
||||
}
|
||||
"meta:Kazakhstan_Western"{
|
||||
sd{"AQTST"}
|
||||
ss{"AQTT"}
|
||||
}
|
||||
"meta:Kizilorda"{
|
||||
sd{"KIZST"}
|
||||
ss{"KIZT"}
|
||||
}
|
||||
"meta:Korea"{
|
||||
sd{"KDT"}
|
||||
ss{"KST"}
|
||||
}
|
||||
"meta:Kosrae"{
|
||||
ss{"KOST"}
|
||||
}
|
||||
"meta:Krasnoyarsk"{
|
||||
sd{"KRAST"}
|
||||
ss{"KRAT"}
|
||||
}
|
||||
"meta:Kuybyshev"{
|
||||
sd{"KUYST"}
|
||||
ss{"KUYT"}
|
||||
}
|
||||
"meta:Kwajalein"{
|
||||
ss{"KWAT"}
|
||||
}
|
||||
"meta:Kyrgystan"{
|
||||
sd{"KGST"}
|
||||
ss{"KGT"}
|
||||
}
|
||||
"meta:Lanka"{
|
||||
ss{"LKT"}
|
||||
}
|
||||
"meta:Liberia"{
|
||||
ss{"LRT"}
|
||||
}
|
||||
"meta:Line_Islands"{
|
||||
ss{"LINT"}
|
||||
}
|
||||
"meta:Long_Shu"{
|
||||
ss{"LONT"}
|
||||
}
|
||||
"meta:Lord_Howe"{
|
||||
ss{"LHST"}
|
||||
}
|
||||
"meta:Macau"{
|
||||
sd{"MOST"}
|
||||
ss{"MOT"}
|
||||
}
|
||||
"meta:Macquarie"{
|
||||
ss{"MIST"}
|
||||
}
|
||||
"meta:Magadan"{
|
||||
sd{"MAGST"}
|
||||
ss{"MAGT"}
|
||||
}
|
||||
"meta:Malaya"{
|
||||
ss{"MALT"}
|
||||
}
|
||||
"meta:Malaysia"{
|
||||
ss{"MYT"}
|
||||
}
|
||||
"meta:Maldives"{
|
||||
ss{"MVT"}
|
||||
}
|
||||
"meta:Marquesas"{
|
||||
ss{"MART"}
|
||||
}
|
||||
"meta:Marshall_Islands"{
|
||||
ss{"MHT"}
|
||||
}
|
||||
"meta:Mauritius"{
|
||||
sd{"MUST"}
|
||||
ss{"MUT"}
|
||||
}
|
||||
"meta:Mawson"{
|
||||
ss{"MAWT"}
|
||||
}
|
||||
"meta:Mexico_Northwest"{
|
||||
sd{"PDT"}
|
||||
ss{"PST"}
|
||||
}
|
||||
"meta:Mexico_Pacific"{
|
||||
sd{"MDT"}
|
||||
ss{"MST"}
|
||||
parseRegions{"MX"}
|
||||
}
|
||||
"meta:Mongolia"{
|
||||
sd{"ULAST"}
|
||||
ss{"ULAT"}
|
||||
}
|
||||
"meta:Moscow"{
|
||||
sd{"MSD"}
|
||||
ss{"MSK"}
|
||||
}
|
||||
"meta:Myanmar"{
|
||||
ss{"MMT"}
|
||||
}
|
||||
"meta:Nauru"{
|
||||
ss{"NRT"}
|
||||
}
|
||||
"meta:Nepal"{
|
||||
ss{"NPT"}
|
||||
}
|
||||
"meta:New_Caledonia"{
|
||||
sd{"NCST"}
|
||||
ss{"NCT"}
|
||||
}
|
||||
"meta:New_Zealand"{
|
||||
sd{"NZDT"}
|
||||
ss{"NZST"}
|
||||
}
|
||||
"meta:Newfoundland"{
|
||||
sd{"NDT"}
|
||||
ss{"NST"}
|
||||
}
|
||||
"meta:Niue"{
|
||||
ss{"NUT"}
|
||||
}
|
||||
"meta:Norfolk"{
|
||||
ss{"NFT"}
|
||||
}
|
||||
"meta:Noronha"{
|
||||
sd{"FNST"}
|
||||
ss{"FNT"}
|
||||
}
|
||||
"meta:North_Mariana"{
|
||||
ss{"MPT"}
|
||||
}
|
||||
"meta:Novosibirsk"{
|
||||
sd{"NOVST"}
|
||||
ss{"NOVT"}
|
||||
}
|
||||
"meta:Omsk"{
|
||||
sd{"OMSST"}
|
||||
ss{"OMST"}
|
||||
}
|
||||
"meta:Oral"{
|
||||
sd{"ORAST"}
|
||||
ss{"ORAT"}
|
||||
}
|
||||
"meta:Pakistan"{
|
||||
sd{"PKST"}
|
||||
ss{"PKT"}
|
||||
}
|
||||
"meta:Palau"{
|
||||
ss{"PWT"}
|
||||
}
|
||||
"meta:Papua_New_Guinea"{
|
||||
ss{"PGT"}
|
||||
}
|
||||
"meta:Paraguay"{
|
||||
sd{"PYST"}
|
||||
ss{"PYT"}
|
||||
}
|
||||
"meta:Peru"{
|
||||
sd{"PEST"}
|
||||
ss{"PET"}
|
||||
}
|
||||
"meta:Philippines"{
|
||||
sd{"PHST"}
|
||||
ss{"PHT"}
|
||||
}
|
||||
"meta:Phoenix_Islands"{
|
||||
ss{"PHOT"}
|
||||
}
|
||||
"meta:Pierre_Miquelon"{
|
||||
sd{"PMDT"}
|
||||
ss{"PMST"}
|
||||
}
|
||||
"meta:Pitcairn"{
|
||||
ss{"PST"}
|
||||
parseRegions{"PN"}
|
||||
}
|
||||
"meta:Ponape"{
|
||||
ss{"PONT"}
|
||||
}
|
||||
"meta:Qyzylorda"{
|
||||
sd{"QYZST"}
|
||||
ss{"QYZT"}
|
||||
}
|
||||
"meta:Reunion"{
|
||||
ss{"RET"}
|
||||
}
|
||||
"meta:Rothera"{
|
||||
ss{"ROTT"}
|
||||
}
|
||||
"meta:Sakhalin"{
|
||||
sd{"SAKST"}
|
||||
ss{"SAKT"}
|
||||
}
|
||||
"meta:Samara"{
|
||||
sd{"SAMST"}
|
||||
ss{"SAMT"}
|
||||
}
|
||||
"meta:Samarkand"{
|
||||
sd{"SAMST"}
|
||||
ss{"SAMT"}
|
||||
parseRegions{"UZ"}
|
||||
}
|
||||
"meta:Samoa"{
|
||||
ss{"SST"}
|
||||
}
|
||||
"meta:Seychelles"{
|
||||
ss{"SCT"}
|
||||
}
|
||||
"meta:Shevchenko"{
|
||||
sd{"SHEST"}
|
||||
ss{"SHET"}
|
||||
}
|
||||
"meta:Singapore"{
|
||||
ss{"SGT"}
|
||||
}
|
||||
"meta:Solomon"{
|
||||
ss{"SBT"}
|
||||
}
|
||||
"meta:South_Georgia"{
|
||||
ss{"GST"}
|
||||
parseRegions{"GS"}
|
||||
}
|
||||
"meta:Suriname"{
|
||||
ss{"SRT"}
|
||||
}
|
||||
"meta:Syowa"{
|
||||
ss{"SYOT"}
|
||||
}
|
||||
"meta:Tahiti"{
|
||||
ss{"TAHT"}
|
||||
}
|
||||
"meta:Taipei"{
|
||||
sd{"CDT"}
|
||||
ss{"CST"}
|
||||
}
|
||||
"meta:Tajikistan"{
|
||||
ss{"TJT"}
|
||||
}
|
||||
"meta:Tashkent"{
|
||||
sd{"TASST"}
|
||||
ss{"TAST"}
|
||||
}
|
||||
"meta:Tbilisi"{
|
||||
sd{"TBIST"}
|
||||
ss{"TBIT"}
|
||||
}
|
||||
"meta:Tokelau"{
|
||||
ss{"TKT"}
|
||||
}
|
||||
"meta:Tonga"{
|
||||
sd{"TOST"}
|
||||
ss{"TOT"}
|
||||
}
|
||||
"meta:Truk"{
|
||||
ss{"CHUT"}
|
||||
}
|
||||
"meta:Turkey"{
|
||||
sd{"TRST"}
|
||||
ss{"TRT"}
|
||||
}
|
||||
"meta:Turkmenistan"{
|
||||
sd{"TMST"}
|
||||
ss{"TMT"}
|
||||
}
|
||||
"meta:Tuvalu"{
|
||||
ss{"TVT"}
|
||||
}
|
||||
"meta:Uralsk"{
|
||||
sd{"URAST"}
|
||||
ss{"URAT"}
|
||||
}
|
||||
"meta:Uruguay"{
|
||||
sd{"UYST"}
|
||||
ss{"UYT"}
|
||||
}
|
||||
"meta:Urumqi"{
|
||||
ss{"URUT"}
|
||||
}
|
||||
"meta:Uzbekistan"{
|
||||
sd{"UZST"}
|
||||
ss{"UZT"}
|
||||
}
|
||||
"meta:Vanuatu"{
|
||||
sd{"VUST"}
|
||||
ss{"VUT"}
|
||||
}
|
||||
"meta:Venezuela"{
|
||||
ss{"VET"}
|
||||
}
|
||||
"meta:Vladivostok"{
|
||||
sd{"VLAST"}
|
||||
ss{"VLAT"}
|
||||
}
|
||||
"meta:Volgograd"{
|
||||
sd{"VOLST"}
|
||||
ss{"VOLT"}
|
||||
}
|
||||
"meta:Vostok"{
|
||||
ss{"VOST"}
|
||||
}
|
||||
"meta:Wake"{
|
||||
ss{"WAKT"}
|
||||
}
|
||||
"meta:Wallis"{
|
||||
ss{"WFT"}
|
||||
}
|
||||
"meta:Yakutsk"{
|
||||
sd{"YAKST"}
|
||||
ss{"YAKT"}
|
||||
}
|
||||
"meta:Yekaterinburg"{
|
||||
sd{"YEKST"}
|
||||
ss{"YEKT"}
|
||||
}
|
||||
"meta:Yerevan"{
|
||||
sd{"YERST"}
|
||||
ss{"YERT"}
|
||||
}
|
||||
"meta:Yukon"{
|
||||
sd{"YDT"}
|
||||
ss{"YST"}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2011-2013, International Business Machines Corporation and
|
||||
* Copyright (C) 2011-2014, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
@ -308,7 +308,8 @@ U_CDECL_END
|
|||
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeZoneFormat)
|
||||
|
||||
TimeZoneFormat::TimeZoneFormat(const Locale& locale, UErrorCode& status)
|
||||
: fLocale(locale), fTimeZoneNames(NULL), fTimeZoneGenericNames(NULL), fDefParseOptionFlags(0) {
|
||||
: fLocale(locale), fTimeZoneNames(NULL), fTimeZoneGenericNames(NULL),
|
||||
fDefParseOptionFlags(0), fTZDBTimeZoneNames(NULL) {
|
||||
|
||||
for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) {
|
||||
fGMTOffsetPatternItems[i] = NULL;
|
||||
|
@ -418,6 +419,7 @@ TimeZoneFormat::TimeZoneFormat(const TimeZoneFormat& other)
|
|||
TimeZoneFormat::~TimeZoneFormat() {
|
||||
delete fTimeZoneNames;
|
||||
delete fTimeZoneGenericNames;
|
||||
delete fTZDBTimeZoneNames;
|
||||
for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) {
|
||||
delete fGMTOffsetPatternItems[i];
|
||||
}
|
||||
|
@ -846,6 +848,8 @@ TimeZoneFormat::parse(UTimeZoneFormatStyle style, const UnicodeString& text, Par
|
|||
UErrorCode status = U_ZERO_ERROR;
|
||||
UnicodeString tzID;
|
||||
|
||||
UBool parseTZDBAbbrev = ((parseOptions & UTZFMT_PARSE_OPTION_TZ_DATABASE_ABBREVIATIONS) != 0);
|
||||
|
||||
// Try the specified style
|
||||
switch (style) {
|
||||
case UTZFMT_STYLE_LOCALIZED_GMT:
|
||||
|
@ -956,6 +960,41 @@ TimeZoneFormat::parse(UTimeZoneFormatStyle style, const UnicodeString& text, Par
|
|||
return TimeZone::createTimeZone(tzID);
|
||||
}
|
||||
}
|
||||
|
||||
if (parseTZDBAbbrev && style == UTZFMT_STYLE_SPECIFIC_SHORT) {
|
||||
U_ASSERT((nameTypes & UTZNM_SHORT_STANDARD) != 0);
|
||||
U_ASSERT((nameTypes & UTZNM_SHORT_DAYLIGHT) != 0);
|
||||
|
||||
const TZDBTimeZoneNames *tzdbTimeZoneNames = getTZDBTimeZoneNames(status);
|
||||
if (U_SUCCESS(status)) {
|
||||
LocalPointer<TimeZoneNames::MatchInfoCollection> tzdbNameMatches(
|
||||
tzdbTimeZoneNames->find(text, startIdx, nameTypes, status));
|
||||
if (U_FAILURE(status)) {
|
||||
pos.setErrorIndex(startIdx);
|
||||
return NULL;
|
||||
}
|
||||
if (!tzdbNameMatches.isNull()) {
|
||||
int32_t matchIdx = -1;
|
||||
int32_t matchPos = -1;
|
||||
for (int32_t i = 0; i < tzdbNameMatches->size(); i++) {
|
||||
matchPos = startIdx + tzdbNameMatches->getMatchLengthAt(i);
|
||||
if (matchPos > parsedPos) {
|
||||
matchIdx = i;
|
||||
parsedPos = matchPos;
|
||||
}
|
||||
}
|
||||
if (matchIdx >= 0) {
|
||||
if (timeType) {
|
||||
*timeType = getTimeType(tzdbNameMatches->getNameTypeAt(matchIdx));
|
||||
}
|
||||
pos.setIndex(matchPos);
|
||||
getTimeZoneID(tzdbNameMatches.getAlias(), matchIdx, tzID);
|
||||
U_ASSERT(!tzID.isEmpty());
|
||||
return TimeZone::createTimeZone(tzID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case UTZFMT_STYLE_GENERIC_LONG:
|
||||
|
@ -1168,6 +1207,34 @@ TimeZoneFormat::parse(UTimeZoneFormatStyle style, const UnicodeString& text, Par
|
|||
parsedOffset = UNKNOWN_OFFSET;
|
||||
}
|
||||
}
|
||||
if (parseTZDBAbbrev && parsedPos < maxPos && (evaluated & STYLE_PARSE_FLAGS[UTZFMT_STYLE_SPECIFIC_SHORT]) == 0) {
|
||||
const TZDBTimeZoneNames *tzdbTimeZoneNames = getTZDBTimeZoneNames(status);
|
||||
if (U_SUCCESS(status)) {
|
||||
LocalPointer<TimeZoneNames::MatchInfoCollection> tzdbNameMatches(
|
||||
tzdbTimeZoneNames->find(text, startIdx, ALL_SIMPLE_NAME_TYPES, status));
|
||||
if (U_FAILURE(status)) {
|
||||
pos.setErrorIndex(startIdx);
|
||||
return NULL;
|
||||
}
|
||||
int32_t tzdbNameMatchIdx = -1;
|
||||
int32_t matchPos = -1;
|
||||
if (!tzdbNameMatches.isNull()) {
|
||||
for (int32_t i = 0; i < tzdbNameMatches->size(); i++) {
|
||||
if (startIdx + tzdbNameMatches->getMatchLengthAt(i) > matchPos) {
|
||||
tzdbNameMatchIdx = i;
|
||||
matchPos = startIdx + tzdbNameMatches->getMatchLengthAt(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (parsedPos < matchPos) {
|
||||
U_ASSERT(tzdbNameMatchIdx >= 0);
|
||||
parsedPos = matchPos;
|
||||
getTimeZoneID(tzdbNameMatches.getAlias(), tzdbNameMatchIdx, parsedID);
|
||||
parsedTimeType = getTimeType(tzdbNameMatches->getNameTypeAt(tzdbNameMatchIdx));
|
||||
parsedOffset = UNKNOWN_OFFSET;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Try generic names
|
||||
if (parsedPos < maxPos) {
|
||||
int32_t genMatchLen = -1;
|
||||
|
@ -1182,7 +1249,7 @@ TimeZoneFormat::parse(UTimeZoneFormatStyle style, const UnicodeString& text, Par
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (parsedPos < startIdx + genMatchLen) {
|
||||
if (genMatchLen > 0 && parsedPos < startIdx + genMatchLen) {
|
||||
parsedPos = startIdx + genMatchLen;
|
||||
parsedID.setTo(tzID);
|
||||
parsedTimeType = tt;
|
||||
|
@ -1313,6 +1380,27 @@ TimeZoneFormat::getTimeZoneGenericNames(UErrorCode& status) const {
|
|||
return fTimeZoneGenericNames;
|
||||
}
|
||||
|
||||
const TZDBTimeZoneNames*
|
||||
TimeZoneFormat::getTZDBTimeZoneNames(UErrorCode& status) const {
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
umtx_lock(&gLock);
|
||||
if (fTZDBTimeZoneNames == NULL) {
|
||||
TZDBTimeZoneNames *tzdbNames = new TZDBTimeZoneNames(fLocale);
|
||||
if (tzdbNames == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
} else {
|
||||
TimeZoneFormat *nonConstThis = const_cast<TimeZoneFormat *>(this);
|
||||
nonConstThis->fTZDBTimeZoneNames = tzdbNames;
|
||||
}
|
||||
}
|
||||
umtx_unlock(&gLock);
|
||||
|
||||
return fTZDBTimeZoneNames;
|
||||
}
|
||||
|
||||
UnicodeString&
|
||||
TimeZoneFormat::formatExemplarLocation(const TimeZone& tz, UnicodeString& name) const {
|
||||
UnicodeString location;
|
||||
|
@ -2576,9 +2664,8 @@ TimeZoneFormat::getTimeType(UTimeZoneNameType nameType) {
|
|||
return UTZFMT_TIME_TYPE_DAYLIGHT;
|
||||
|
||||
default:
|
||||
U_ASSERT(FALSE);
|
||||
return UTZFMT_TIME_TYPE_UNKNOWN;
|
||||
}
|
||||
return UTZFMT_TIME_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
UnicodeString&
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2011-2013, International Business Machines Corporation and *
|
||||
* Copyright (C) 2011-2014, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
@ -291,9 +291,30 @@ TimeZoneNames::~TimeZoneNames() {
|
|||
|
||||
TimeZoneNames*
|
||||
TimeZoneNames::createInstance(const Locale& locale, UErrorCode& status) {
|
||||
return new TimeZoneNamesDelegate(locale, status);
|
||||
TimeZoneNames *instance = NULL;
|
||||
if (U_SUCCESS(status)) {
|
||||
instance = new TimeZoneNamesDelegate(locale, status);
|
||||
if (instance == NULL && U_SUCCESS(status)) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
#ifndef U_HIDE_DRAFT_API
|
||||
TimeZoneNames*
|
||||
TimeZoneNames::createTZDBInstance(const Locale& locale, UErrorCode& status) {
|
||||
TimeZoneNames *instance = NULL;
|
||||
if (U_SUCCESS(status)) {
|
||||
instance = new TZDBTimeZoneNames(locale);
|
||||
if (instance == NULL && U_SUCCESS(status)) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
#endif /* U_HIDE_DRAFT_API */
|
||||
|
||||
UnicodeString&
|
||||
TimeZoneNames::getExemplarLocationName(const UnicodeString& tzID, UnicodeString& name) const {
|
||||
return TimeZoneNamesImpl::getDefaultExemplarLocationName(tzID, name);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2011-2013, International Business Machines Corporation and
|
||||
* Copyright (C) 2011-2014, International Business Machines Corporation and
|
||||
* others. All Rights Reserved.
|
||||
*******************************************************************************
|
||||
*
|
||||
|
@ -51,6 +51,36 @@ static const UTimeZoneNameType ALL_NAME_TYPES[] = {
|
|||
UTZNM_UNKNOWN // unknown as the last one
|
||||
};
|
||||
|
||||
// stuff for TZDBTimeZoneNames
|
||||
static const char* TZDBNAMES_KEYS[] = {"ss", "sd"};
|
||||
static const int32_t TZDBNAMES_KEYS_SIZE = (sizeof TZDBNAMES_KEYS / sizeof TZDBNAMES_KEYS[0]);
|
||||
|
||||
static UMutex gTZDBNamesMapLock = U_MUTEX_INITIALIZER;
|
||||
|
||||
static UHashtable* gTZDBNamesMap = NULL;
|
||||
static icu::UInitOnce gTZDBNamesMapInitOnce = U_INITONCE_INITIALIZER;
|
||||
|
||||
static TextTrieMap* gTZDBNamesTrie = NULL;
|
||||
static icu::UInitOnce gTZDBNamesTrieInitOnce = U_INITONCE_INITIALIZER;
|
||||
|
||||
U_CDECL_BEGIN
|
||||
static UBool U_CALLCONV tzdbTimeZoneNames_cleanup(void) {
|
||||
if (gTZDBNamesMap != NULL) {
|
||||
uhash_close(gTZDBNamesMap);
|
||||
gTZDBNamesMap = NULL;
|
||||
}
|
||||
gTZDBNamesMapInitOnce.reset();
|
||||
|
||||
if (gTZDBNamesTrie != NULL) {
|
||||
delete gTZDBNamesTrie;
|
||||
gTZDBNamesTrie = NULL;
|
||||
}
|
||||
gTZDBNamesTrieInitOnce.reset();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
U_CDECL_END
|
||||
|
||||
#define DEFAULT_CHARACTERNODE_CAPACITY 1
|
||||
|
||||
// ---------------------------------------------------
|
||||
|
@ -799,7 +829,7 @@ ZNameSearchHandler::handleMatch(int32_t matchLength, const CharacterNode *node,
|
|||
for (int32_t i = 0; i < valuesCount; i++) {
|
||||
ZNameInfo *nameinfo = (ZNameInfo *)node->getValue(i);
|
||||
if (nameinfo == NULL) {
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if ((nameinfo->type & fTypes) != 0) {
|
||||
// matches a requested type
|
||||
|
@ -986,6 +1016,12 @@ TimeZoneNamesImpl::clone() const {
|
|||
|
||||
StringEnumeration*
|
||||
TimeZoneNamesImpl::getAvailableMetaZoneIDs(UErrorCode& status) const {
|
||||
return TimeZoneNamesImpl::_getAvailableMetaZoneIDs(status);
|
||||
}
|
||||
|
||||
// static implementation of getAvailableMetaZoneIDs(UErrorCode&)
|
||||
StringEnumeration*
|
||||
TimeZoneNamesImpl::_getAvailableMetaZoneIDs(UErrorCode& status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -998,6 +1034,12 @@ TimeZoneNamesImpl::getAvailableMetaZoneIDs(UErrorCode& status) const {
|
|||
|
||||
StringEnumeration*
|
||||
TimeZoneNamesImpl::getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const {
|
||||
return TimeZoneNamesImpl::_getAvailableMetaZoneIDs(tzID, status);
|
||||
}
|
||||
|
||||
// static implementation of getAvailableMetaZoneIDs(const UnicodeString&, UErrorCode&)
|
||||
StringEnumeration*
|
||||
TimeZoneNamesImpl::_getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
@ -1032,16 +1074,29 @@ TimeZoneNamesImpl::getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode
|
|||
|
||||
UnicodeString&
|
||||
TimeZoneNamesImpl::getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) const {
|
||||
return TimeZoneNamesImpl::_getMetaZoneID(tzID, date, mzID);
|
||||
}
|
||||
|
||||
// static implementation of getMetaZoneID
|
||||
UnicodeString&
|
||||
TimeZoneNamesImpl::_getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) {
|
||||
ZoneMeta::getMetazoneID(tzID, date, mzID);
|
||||
return mzID;
|
||||
}
|
||||
|
||||
UnicodeString&
|
||||
TimeZoneNamesImpl::getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) const {
|
||||
return TimeZoneNamesImpl::_getReferenceZoneID(mzID, region, tzID);
|
||||
}
|
||||
|
||||
// static implementaion of getReferenceZoneID
|
||||
UnicodeString&
|
||||
TimeZoneNamesImpl::_getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) {
|
||||
ZoneMeta::getZoneIdByMetazone(mzID, UnicodeString(region, -1, US_INV), tzID);
|
||||
return tzID;
|
||||
}
|
||||
|
||||
|
||||
UnicodeString&
|
||||
TimeZoneNamesImpl::getMetaZoneDisplayName(const UnicodeString& mzID,
|
||||
UTimeZoneNameType type,
|
||||
|
@ -1170,6 +1225,7 @@ TimeZoneNamesImpl::loadMetaZoneNames(const UnicodeString& mzID) {
|
|||
if (U_FAILURE(status)) {
|
||||
if (znames != NULL) {
|
||||
delete znames;
|
||||
znames = NULL;
|
||||
}
|
||||
} else if (znames != NULL) {
|
||||
// put the name info into the trie
|
||||
|
@ -1247,6 +1303,7 @@ TimeZoneNamesImpl::loadTimeZoneNames(const UnicodeString& tzID) {
|
|||
if (U_FAILURE(status)) {
|
||||
if (tznames != NULL) {
|
||||
delete tznames;
|
||||
tznames = NULL;
|
||||
}
|
||||
} else if (tznames != NULL) {
|
||||
// put the name info into the trie
|
||||
|
@ -1371,6 +1428,589 @@ TimeZoneNamesImpl::getDefaultExemplarLocationName(const UnicodeString& tzID, Uni
|
|||
return name;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------
|
||||
// TZDBTimeZoneNames and its supporting classes
|
||||
//
|
||||
// TZDBTimeZoneNames is an implementation class of
|
||||
// TimeZoneNames holding the IANA tz database abbreviations.
|
||||
// ---------------------------------------------------
|
||||
|
||||
class TZDBNames : public UMemory {
|
||||
public:
|
||||
virtual ~TZDBNames();
|
||||
|
||||
static TZDBNames* createInstance(UResourceBundle* rb, const char* key);
|
||||
const UChar* getName(UTimeZoneNameType type) const;
|
||||
const char** getParseRegions(int32_t& numRegions) const;
|
||||
|
||||
protected:
|
||||
TZDBNames(const UChar** names, char** regions, int32_t numRegions);
|
||||
|
||||
private:
|
||||
const UChar** fNames;
|
||||
char** fRegions;
|
||||
int32_t fNumRegions;
|
||||
};
|
||||
|
||||
TZDBNames::TZDBNames(const UChar** names, char** regions, int32_t numRegions)
|
||||
: fNames(names),
|
||||
fRegions(regions),
|
||||
fNumRegions(numRegions) {
|
||||
}
|
||||
|
||||
TZDBNames::~TZDBNames() {
|
||||
if (fNames != NULL) {
|
||||
uprv_free(fNames);
|
||||
}
|
||||
if (fRegions != NULL) {
|
||||
char **p = fRegions;
|
||||
for (int32_t i = 0; i < fNumRegions; p++, i++) {
|
||||
uprv_free(*p);
|
||||
}
|
||||
uprv_free(fRegions);
|
||||
}
|
||||
}
|
||||
|
||||
TZDBNames*
|
||||
TZDBNames::createInstance(UResourceBundle* rb, const char* key) {
|
||||
if (rb == NULL || key == NULL || *key == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
|
||||
const UChar **names = NULL;
|
||||
char** regions = NULL;
|
||||
int32_t numRegions = 0;
|
||||
|
||||
int32_t len = 0;
|
||||
|
||||
UResourceBundle* rbTable = NULL;
|
||||
rbTable = ures_getByKey(rb, key, rbTable, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
names = (const UChar **)uprv_malloc(sizeof(const UChar*) * TZDBNAMES_KEYS_SIZE);
|
||||
UBool isEmpty = TRUE;
|
||||
if (names != NULL) {
|
||||
for (int32_t i = 0; i < TZDBNAMES_KEYS_SIZE; i++) {
|
||||
status = U_ZERO_ERROR;
|
||||
const UChar *value = ures_getStringByKey(rbTable, TZDBNAMES_KEYS[i], &len, &status);
|
||||
if (U_FAILURE(status) || len == 0) {
|
||||
names[i] = NULL;
|
||||
} else {
|
||||
names[i] = value;
|
||||
isEmpty = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isEmpty) {
|
||||
if (names != NULL) {
|
||||
uprv_free(names);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UResourceBundle *regionsRes = ures_getByKey(rbTable, "parseRegions", NULL, &status);
|
||||
UBool regionError = FALSE;
|
||||
if (U_SUCCESS(status)) {
|
||||
numRegions = ures_getSize(regionsRes);
|
||||
if (numRegions > 0) {
|
||||
regions = (char**)uprv_malloc(sizeof(char*) * numRegions);
|
||||
if (regions != NULL) {
|
||||
char **pRegion = regions;
|
||||
for (int32_t i = 0; i < numRegions; i++, pRegion++) {
|
||||
*pRegion = NULL;
|
||||
}
|
||||
// filling regions
|
||||
pRegion = regions;
|
||||
for (int32_t i = 0; i < numRegions; i++, pRegion++) {
|
||||
status = U_ZERO_ERROR;
|
||||
const UChar *uregion = ures_getStringByIndex(regionsRes, i, &len, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
regionError = TRUE;
|
||||
break;
|
||||
}
|
||||
*pRegion = (char*)uprv_malloc(sizeof(char) * (len + 1));
|
||||
if (*pRegion == NULL) {
|
||||
regionError = TRUE;
|
||||
break;
|
||||
}
|
||||
u_UCharsToChars(uregion, *pRegion, len);
|
||||
(*pRegion)[len] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
ures_close(regionsRes);
|
||||
ures_close(rbTable);
|
||||
|
||||
if (regionError) {
|
||||
if (names != NULL) {
|
||||
uprv_free(names);
|
||||
}
|
||||
if (regions != NULL) {
|
||||
char **p = regions;
|
||||
for (int32_t i = 0; i < numRegions; p++, i++) {
|
||||
uprv_free(p);
|
||||
}
|
||||
uprv_free(regions);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return new TZDBNames(names, regions, numRegions);
|
||||
}
|
||||
|
||||
const UChar*
|
||||
TZDBNames::getName(UTimeZoneNameType type) const {
|
||||
if (fNames == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
const UChar *name = NULL;
|
||||
switch(type) {
|
||||
case UTZNM_SHORT_STANDARD:
|
||||
name = fNames[0];
|
||||
break;
|
||||
case UTZNM_SHORT_DAYLIGHT:
|
||||
name = fNames[1];
|
||||
break;
|
||||
default:
|
||||
name = NULL;
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
const char**
|
||||
TZDBNames::getParseRegions(int32_t& numRegions) const {
|
||||
if (fRegions == NULL) {
|
||||
numRegions = 0;
|
||||
} else {
|
||||
numRegions = fNumRegions;
|
||||
}
|
||||
return (const char**)fRegions;
|
||||
}
|
||||
|
||||
U_CDECL_BEGIN
|
||||
/**
|
||||
* TZDBNameInfo stores metazone name information for the IANA abbreviations
|
||||
* in the trie
|
||||
*/
|
||||
typedef struct TZDBNameInfo {
|
||||
const UChar* mzID;
|
||||
UTimeZoneNameType type;
|
||||
UBool ambiguousType;
|
||||
const char** parseRegions;
|
||||
int32_t nRegions;
|
||||
} TZDBNameInfo;
|
||||
U_CDECL_END
|
||||
|
||||
|
||||
class TZDBNameSearchHandler : public TextTrieMapSearchResultHandler {
|
||||
public:
|
||||
TZDBNameSearchHandler(uint32_t types, const char* region);
|
||||
virtual ~TZDBNameSearchHandler();
|
||||
|
||||
UBool handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status);
|
||||
TimeZoneNames::MatchInfoCollection* getMatches(int32_t& maxMatchLen);
|
||||
|
||||
private:
|
||||
uint32_t fTypes;
|
||||
int32_t fMaxMatchLen;
|
||||
TimeZoneNames::MatchInfoCollection* fResults;
|
||||
const char* fRegion;
|
||||
};
|
||||
|
||||
TZDBNameSearchHandler::TZDBNameSearchHandler(uint32_t types, const char* region)
|
||||
: fTypes(types), fMaxMatchLen(0), fResults(NULL), fRegion(region) {
|
||||
}
|
||||
|
||||
TZDBNameSearchHandler::~TZDBNameSearchHandler() {
|
||||
if (fResults != NULL) {
|
||||
delete fResults;
|
||||
}
|
||||
}
|
||||
|
||||
UBool
|
||||
TZDBNameSearchHandler::handleMatch(int32_t matchLength, const CharacterNode *node, UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TZDBNameInfo *match = NULL;
|
||||
TZDBNameInfo *defaultRegionMatch = NULL;
|
||||
|
||||
if (node->hasValues()) {
|
||||
int32_t valuesCount = node->countValues();
|
||||
for (int32_t i = 0; i < valuesCount; i++) {
|
||||
TZDBNameInfo *ninfo = (TZDBNameInfo *)node->getValue(i);
|
||||
if (ninfo == NULL) {
|
||||
continue;
|
||||
}
|
||||
if ((ninfo->type & fTypes) != 0) {
|
||||
// Some tz database abbreviations are ambiguous. For example,
|
||||
// CST means either Central Standard Time or China Standard Time.
|
||||
// Unlike CLDR time zone display names, this implementation
|
||||
// does not use unique names. And TimeZoneFormat does not expect
|
||||
// multiple results returned for the same time zone type.
|
||||
// For this reason, this implementation resolve one among same
|
||||
// zone type with a same name at this level.
|
||||
if (ninfo->parseRegions == NULL) {
|
||||
// parseRegions == null means this is the default metazone
|
||||
// mapping for the abbreviation.
|
||||
if (defaultRegionMatch == NULL) {
|
||||
match = defaultRegionMatch = ninfo;
|
||||
}
|
||||
} else {
|
||||
UBool matchRegion = FALSE;
|
||||
// non-default metazone mapping for an abbreviation
|
||||
// comes with applicable regions. For example, the default
|
||||
// metazone mapping for "CST" is America_Central,
|
||||
// but if region is one of CN/MO/TW, "CST" is parsed
|
||||
// as metazone China (China Standard Time).
|
||||
for (int32_t i = 0; i < ninfo->nRegions; i++) {
|
||||
const char *region = ninfo->parseRegions[i];
|
||||
if (uprv_strcmp(fRegion, region) == 0) {
|
||||
match = ninfo;
|
||||
matchRegion = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (matchRegion) {
|
||||
break;
|
||||
}
|
||||
if (match == NULL) {
|
||||
match = ninfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (match != NULL) {
|
||||
UTimeZoneNameType ntype = match->type;
|
||||
// Note: Workaround for duplicated standard/daylight names
|
||||
// The tz database contains a few zones sharing a
|
||||
// same name for both standard time and daylight saving
|
||||
// time. For example, Australia/Sydney observes DST,
|
||||
// but "EST" is used for both standard and daylight.
|
||||
// When both SHORT_STANDARD and SHORT_DAYLIGHT are included
|
||||
// in the find operation, we cannot tell which one was
|
||||
// actually matched.
|
||||
// TimeZoneFormat#parse returns a matched name type (standard
|
||||
// or daylight) and DateFormat implementation uses the info to
|
||||
// to adjust actual time. To avoid false type information,
|
||||
// this implementation replaces the name type with SHORT_GENERIC.
|
||||
if (match->ambiguousType
|
||||
&& (ntype == UTZNM_SHORT_STANDARD || ntype == UTZNM_SHORT_DAYLIGHT)
|
||||
&& (fTypes & UTZNM_SHORT_STANDARD) != 0
|
||||
&& (fTypes & UTZNM_SHORT_DAYLIGHT) != 0) {
|
||||
ntype = UTZNM_SHORT_GENERIC;
|
||||
}
|
||||
|
||||
if (fResults == NULL) {
|
||||
fResults = new TimeZoneNames::MatchInfoCollection();
|
||||
if (fResults == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
}
|
||||
}
|
||||
if (U_SUCCESS(status)) {
|
||||
U_ASSERT(fResults != NULL);
|
||||
U_ASSERT(match->mzID != NULL);
|
||||
fResults->addMetaZone(ntype, matchLength, UnicodeString(match->mzID, -1), status);
|
||||
if (U_SUCCESS(status) && matchLength > fMaxMatchLen) {
|
||||
fMaxMatchLen = matchLength;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
TimeZoneNames::MatchInfoCollection*
|
||||
TZDBNameSearchHandler::getMatches(int32_t& maxMatchLen) {
|
||||
// give the ownership to the caller
|
||||
TimeZoneNames::MatchInfoCollection* results = fResults;
|
||||
maxMatchLen = fMaxMatchLen;
|
||||
|
||||
// reset
|
||||
fResults = NULL;
|
||||
fMaxMatchLen = 0;
|
||||
return results;
|
||||
}
|
||||
|
||||
U_CDECL_BEGIN
|
||||
/**
|
||||
* Deleter for TZDBNames
|
||||
*/
|
||||
static void U_CALLCONV
|
||||
deleteTZDBNames(void *obj) {
|
||||
if (obj != EMPTY) {
|
||||
delete (TZDBNames *)obj;
|
||||
}
|
||||
}
|
||||
|
||||
static void U_CALLCONV initTZDBNamesMap(UErrorCode &status) {
|
||||
gTZDBNamesMap = uhash_open(uhash_hashUChars, uhash_compareUChars, NULL, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
gTZDBNamesMap = NULL;
|
||||
return;
|
||||
}
|
||||
// no key deleters for tzdb name maps
|
||||
uhash_setValueDeleter(gTZDBNamesMap, deleteTZDBNames);
|
||||
ucln_i18n_registerCleanup(UCLN_I18N_TZDBTIMEZONENAMES, tzdbTimeZoneNames_cleanup);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deleter for TZDBNameInfo
|
||||
*/
|
||||
static void U_CALLCONV
|
||||
deleteTZDBNameInfo(void *obj) {
|
||||
if (obj != NULL) {
|
||||
uprv_free(obj);
|
||||
}
|
||||
}
|
||||
|
||||
static void U_CALLCONV prepareFind(UErrorCode &status) {
|
||||
if (U_FAILURE(status)) {
|
||||
return;
|
||||
}
|
||||
gTZDBNamesTrie = new TextTrieMap(TRUE, deleteTZDBNameInfo);
|
||||
if (gTZDBNamesTrie == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
const UnicodeString *mzID;
|
||||
StringEnumeration *mzIDs = TimeZoneNamesImpl::_getAvailableMetaZoneIDs(status);
|
||||
if (U_SUCCESS(status)) {
|
||||
while ((mzID = mzIDs->snext(status)) && U_SUCCESS(status)) {
|
||||
const TZDBNames *names = TZDBTimeZoneNames::getMetaZoneNames(*mzID, status);
|
||||
if (names == NULL) {
|
||||
continue;
|
||||
}
|
||||
const UChar *std = names->getName(UTZNM_SHORT_STANDARD);
|
||||
const UChar *dst = names->getName(UTZNM_SHORT_DAYLIGHT);
|
||||
if (std == NULL && dst == NULL) {
|
||||
continue;
|
||||
}
|
||||
int32_t numRegions = 0;
|
||||
const char **parseRegions = names->getParseRegions(numRegions);
|
||||
|
||||
// The tz database contains a few zones sharing a
|
||||
// same name for both standard time and daylight saving
|
||||
// time. For example, Australia/Sydney observes DST,
|
||||
// but "EST" is used for both standard and daylight.
|
||||
// we need to store the information for later processing.
|
||||
UBool ambiguousType = (std != NULL && dst != NULL && u_strcmp(std, dst) == 0);
|
||||
|
||||
const UChar *uMzID = ZoneMeta::findMetaZoneID(*mzID);
|
||||
if (std != NULL) {
|
||||
TZDBNameInfo *stdInf = (TZDBNameInfo *)uprv_malloc(sizeof(TZDBNameInfo));
|
||||
if (stdInf == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
break;
|
||||
}
|
||||
stdInf->mzID = uMzID;
|
||||
stdInf->type = UTZNM_SHORT_STANDARD;
|
||||
stdInf->ambiguousType = ambiguousType;
|
||||
stdInf->parseRegions = parseRegions;
|
||||
stdInf->nRegions = numRegions;
|
||||
gTZDBNamesTrie->put(std, stdInf, status);
|
||||
}
|
||||
if (U_SUCCESS(status) && dst != NULL) {
|
||||
TZDBNameInfo *dstInf = (TZDBNameInfo *)uprv_malloc(sizeof(TZDBNameInfo));
|
||||
if (dstInf == NULL) {
|
||||
status = U_MEMORY_ALLOCATION_ERROR;
|
||||
break;
|
||||
}
|
||||
dstInf->mzID = uMzID;
|
||||
dstInf->type = UTZNM_SHORT_DAYLIGHT;
|
||||
dstInf->ambiguousType = ambiguousType;
|
||||
dstInf->parseRegions = parseRegions;
|
||||
dstInf->nRegions = numRegions;
|
||||
gTZDBNamesTrie->put(dst, dstInf, status);
|
||||
}
|
||||
}
|
||||
}
|
||||
delete mzIDs;
|
||||
|
||||
if (U_FAILURE(status)) {
|
||||
delete gTZDBNamesTrie;
|
||||
gTZDBNamesTrie = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
ucln_i18n_registerCleanup(UCLN_I18N_TZDBTIMEZONENAMES, tzdbTimeZoneNames_cleanup);
|
||||
}
|
||||
|
||||
U_CDECL_END
|
||||
|
||||
TZDBTimeZoneNames::TZDBTimeZoneNames(const Locale& locale)
|
||||
: fLocale(locale) {
|
||||
UBool useWorld = TRUE;
|
||||
const char* region = fLocale.getCountry();
|
||||
int32_t regionLen = uprv_strlen(region);
|
||||
if (regionLen == 0) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
char loc[ULOC_FULLNAME_CAPACITY];
|
||||
uloc_addLikelySubtags(fLocale.getName(), loc, sizeof(loc), &status);
|
||||
regionLen = uloc_getCountry(loc, fRegion, sizeof(fRegion), &status);
|
||||
if (U_SUCCESS(status) && regionLen < (int32_t)sizeof(fRegion)) {
|
||||
useWorld = FALSE;
|
||||
}
|
||||
} else if (regionLen < (int32_t)sizeof(fRegion)) {
|
||||
uprv_strcpy(fRegion, region);
|
||||
useWorld = FALSE;
|
||||
}
|
||||
if (useWorld) {
|
||||
uprv_strcpy(fRegion, "001");
|
||||
}
|
||||
}
|
||||
|
||||
TZDBTimeZoneNames::~TZDBTimeZoneNames() {
|
||||
}
|
||||
|
||||
UBool
|
||||
TZDBTimeZoneNames::operator==(const TimeZoneNames& other) const {
|
||||
if (this == &other) {
|
||||
return TRUE;
|
||||
}
|
||||
// No implementation for now
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
TimeZoneNames*
|
||||
TZDBTimeZoneNames::clone() const {
|
||||
return new TZDBTimeZoneNames(fLocale);
|
||||
}
|
||||
|
||||
StringEnumeration*
|
||||
TZDBTimeZoneNames::getAvailableMetaZoneIDs(UErrorCode& status) const {
|
||||
return TimeZoneNamesImpl::_getAvailableMetaZoneIDs(status);
|
||||
}
|
||||
|
||||
StringEnumeration*
|
||||
TZDBTimeZoneNames::getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const {
|
||||
return TimeZoneNamesImpl::_getAvailableMetaZoneIDs(tzID, status);
|
||||
}
|
||||
|
||||
UnicodeString&
|
||||
TZDBTimeZoneNames::getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) const {
|
||||
return TimeZoneNamesImpl::_getMetaZoneID(tzID, date, mzID);
|
||||
}
|
||||
|
||||
UnicodeString&
|
||||
TZDBTimeZoneNames::getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) const {
|
||||
return TimeZoneNamesImpl::_getReferenceZoneID(mzID, region, tzID);
|
||||
}
|
||||
|
||||
UnicodeString&
|
||||
TZDBTimeZoneNames::getMetaZoneDisplayName(const UnicodeString& mzID,
|
||||
UTimeZoneNameType type,
|
||||
UnicodeString& name) const {
|
||||
name.setToBogus();
|
||||
if (mzID.isEmpty()) {
|
||||
return name;
|
||||
}
|
||||
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
const TZDBNames *tzdbNames = TZDBTimeZoneNames::getMetaZoneNames(mzID, status);
|
||||
if (U_SUCCESS(status)) {
|
||||
const UChar *s = tzdbNames->getName(type);
|
||||
if (s != NULL) {
|
||||
name.setTo(TRUE, s, -1);
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
UnicodeString&
|
||||
TZDBTimeZoneNames::getTimeZoneDisplayName(const UnicodeString& /* tzID */, UTimeZoneNameType /* type */, UnicodeString& name) const {
|
||||
// No abbreviations associated a zone directly for now.
|
||||
name.setToBogus();
|
||||
return name;
|
||||
}
|
||||
|
||||
TZDBTimeZoneNames::MatchInfoCollection*
|
||||
TZDBTimeZoneNames::find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const {
|
||||
umtx_initOnce(gTZDBNamesTrieInitOnce, &prepareFind, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TZDBNameSearchHandler handler(types, fRegion);
|
||||
gTZDBNamesTrie->search(text, start, (TextTrieMapSearchResultHandler *)&handler, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
int32_t maxLen = 0;
|
||||
return handler.getMatches(maxLen);
|
||||
}
|
||||
|
||||
const TZDBNames*
|
||||
TZDBTimeZoneNames::getMetaZoneNames(const UnicodeString& mzID, UErrorCode& status) {
|
||||
umtx_initOnce(gTZDBNamesMapInitOnce, &initTZDBNamesMap, status);
|
||||
if (U_FAILURE(status)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
TZDBNames* tzdbNames = NULL;
|
||||
|
||||
UChar mzIDKey[ZID_KEY_MAX + 1];
|
||||
mzID.extract(mzIDKey, ZID_KEY_MAX + 1, status);
|
||||
U_ASSERT(status == U_ZERO_ERROR); // already checked length above
|
||||
mzIDKey[mzID.length()] = 0;
|
||||
|
||||
umtx_lock(&gTZDBNamesMapLock);
|
||||
{
|
||||
void *cacheVal = uhash_get(gTZDBNamesMap, mzIDKey);
|
||||
if (cacheVal == NULL) {
|
||||
UResourceBundle *zoneStringsRes = ures_openDirect(U_ICUDATA_ZONE, "tzdbNames", &status);
|
||||
zoneStringsRes = ures_getByKey(zoneStringsRes, gZoneStrings, zoneStringsRes, &status);
|
||||
if (U_SUCCESS(status)) {
|
||||
char key[ZID_KEY_MAX + 1];
|
||||
mergeTimeZoneKey(mzID, key);
|
||||
tzdbNames = TZDBNames::createInstance(zoneStringsRes, key);
|
||||
|
||||
if (tzdbNames == NULL) {
|
||||
cacheVal = (void *)EMPTY;
|
||||
} else {
|
||||
cacheVal = tzdbNames;
|
||||
}
|
||||
// Use the persistent ID as the resource key, so we can
|
||||
// avoid duplications.
|
||||
const UChar* newKey = ZoneMeta::findMetaZoneID(mzID);
|
||||
if (newKey != NULL) {
|
||||
uhash_put(gTZDBNamesMap, (void *)newKey, cacheVal, &status);
|
||||
if (U_FAILURE(status)) {
|
||||
if (tzdbNames != NULL) {
|
||||
delete tzdbNames;
|
||||
tzdbNames = NULL;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Should never happen with a valid input
|
||||
if (tzdbNames != NULL) {
|
||||
// It's not possible that we get a valid tzdbNames with unknown ID.
|
||||
// But just in case..
|
||||
delete tzdbNames;
|
||||
tzdbNames = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
ures_close(zoneStringsRes);
|
||||
} else if (cacheVal != EMPTY) {
|
||||
tzdbNames = (TZDBNames *)cacheVal;
|
||||
}
|
||||
}
|
||||
umtx_unlock(&gTZDBNamesMapLock);
|
||||
|
||||
return tzdbNames;
|
||||
}
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2011-2013, International Business Machines Corporation and *
|
||||
* Copyright (C) 2011-2014, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
@ -186,6 +186,11 @@ public:
|
|||
|
||||
static UnicodeString& getDefaultExemplarLocationName(const UnicodeString& tzID, UnicodeString& name);
|
||||
|
||||
static StringEnumeration* _getAvailableMetaZoneIDs(UErrorCode& status);
|
||||
static StringEnumeration* _getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status);
|
||||
static UnicodeString& _getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID);
|
||||
static UnicodeString& _getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID);
|
||||
|
||||
private:
|
||||
|
||||
Locale fLocale;
|
||||
|
@ -207,6 +212,34 @@ private:
|
|||
TZNames* loadTimeZoneNames(const UnicodeString& mzId);
|
||||
};
|
||||
|
||||
class TZDBNames;
|
||||
|
||||
class TZDBTimeZoneNames : public TimeZoneNames {
|
||||
public:
|
||||
TZDBTimeZoneNames(const Locale& locale);
|
||||
virtual ~TZDBTimeZoneNames();
|
||||
|
||||
virtual UBool operator==(const TimeZoneNames& other) const;
|
||||
virtual TimeZoneNames* clone() const;
|
||||
|
||||
StringEnumeration* getAvailableMetaZoneIDs(UErrorCode& status) const;
|
||||
StringEnumeration* getAvailableMetaZoneIDs(const UnicodeString& tzID, UErrorCode& status) const;
|
||||
|
||||
UnicodeString& getMetaZoneID(const UnicodeString& tzID, UDate date, UnicodeString& mzID) const;
|
||||
UnicodeString& getReferenceZoneID(const UnicodeString& mzID, const char* region, UnicodeString& tzID) const;
|
||||
|
||||
UnicodeString& getMetaZoneDisplayName(const UnicodeString& mzID, UTimeZoneNameType type, UnicodeString& name) const;
|
||||
UnicodeString& getTimeZoneDisplayName(const UnicodeString& tzID, UTimeZoneNameType type, UnicodeString& name) const;
|
||||
|
||||
TimeZoneNames::MatchInfoCollection* find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const;
|
||||
|
||||
static const TZDBNames* getMetaZoneNames(const UnicodeString& mzId, UErrorCode& status);
|
||||
|
||||
private:
|
||||
Locale fLocale;
|
||||
char fRegion[ULOC_COUNTRY_CAPACITY];
|
||||
};
|
||||
|
||||
U_NAMESPACE_END
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
|
|
@ -35,6 +35,7 @@ typedef enum ECleanupI18NType {
|
|||
UCLN_I18N_DANGI_CALENDAR,
|
||||
UCLN_I18N_CALENDAR,
|
||||
UCLN_I18N_TIMEZONEFORMAT,
|
||||
UCLN_I18N_TZDBTIMEZONENAMES,
|
||||
UCLN_I18N_TIMEZONEGENERICNAMES,
|
||||
UCLN_I18N_TIMEZONENAMES,
|
||||
UCLN_I18N_ZONEMETA,
|
||||
|
|
|
@ -233,7 +233,15 @@ typedef enum UTimeZoneFormatParseOption {
|
|||
* by other styles.
|
||||
* @stable ICU 50
|
||||
*/
|
||||
UTZFMT_PARSE_OPTION_ALL_STYLES = 0x01
|
||||
UTZFMT_PARSE_OPTION_ALL_STYLES = 0x01,
|
||||
/**
|
||||
* When parsing a time zone display name in UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
* look for the IANA tz database compatible zone abbreviations in addition
|
||||
* to the localized names coming from the {@link TimeZoneNames} currently
|
||||
* used by the {@link TimeZoneFormat}.
|
||||
* @draft ICU 54
|
||||
*/
|
||||
UTZFMT_PARSE_OPTION_TZ_DATABASE_ABBREVIATIONS = 0x02
|
||||
} UTimeZoneFormatParseOption;
|
||||
|
||||
U_CDECL_END
|
||||
|
@ -241,6 +249,7 @@ U_CDECL_END
|
|||
U_NAMESPACE_BEGIN
|
||||
|
||||
class TimeZoneGenericNames;
|
||||
class TZDBTimeZoneNames;
|
||||
class UVector;
|
||||
|
||||
/**
|
||||
|
@ -697,6 +706,9 @@ private:
|
|||
|
||||
UBool fAbuttingOffsetHoursAndMinutes;
|
||||
|
||||
/* TZDBTimeZoneNames object used for parsing */
|
||||
TZDBTimeZoneNames* fTZDBTimeZoneNames;
|
||||
|
||||
/**
|
||||
* Returns the time zone's specific format string.
|
||||
* @param tz the time zone
|
||||
|
@ -727,6 +739,13 @@ private:
|
|||
*/
|
||||
const TimeZoneGenericNames* getTimeZoneGenericNames(UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* Lazily create a TZDBTimeZoneNames instance
|
||||
* @param status receives the status
|
||||
* @return the cached TZDBTimeZoneNames.
|
||||
*/
|
||||
const TZDBTimeZoneNames* getTZDBTimeZoneNames(UErrorCode& status) const;
|
||||
|
||||
/**
|
||||
* Private method returning the time zone's exemplar location string.
|
||||
* This method will never return empty.
|
||||
|
|
|
@ -158,15 +158,28 @@ public:
|
|||
virtual TimeZoneNames* clone() const = 0;
|
||||
|
||||
/**
|
||||
* Returns an instance of <code>TimeZoneDisplayNames</code> for the specified locale.
|
||||
* Returns an instance of <code>TimeZoneNames</code> for the specified locale.
|
||||
*
|
||||
* @param locale The locale.
|
||||
* @param status Receives the status.
|
||||
* @return An instance of <code>TimeZoneDisplayNames</code>
|
||||
* @return An instance of <code>TimeZoneNames</code>
|
||||
* @stable ICU 50
|
||||
*/
|
||||
static TimeZoneNames* U_EXPORT2 createInstance(const Locale& locale, UErrorCode& status);
|
||||
|
||||
#ifndef U_HIDE_DRAFT_API
|
||||
/**
|
||||
* Returns an instance of <code>TimeZoneNames</code> containing only short specific
|
||||
* zone names (SHORT_STANDARD and SHORT_DAYLIGHT),
|
||||
* compatible with the IANA tz database's zone abbreviations (not localized).
|
||||
* <br>
|
||||
* Note: The input locale is used for resolving ambiguous names (e.g. "IST" is parsed
|
||||
* as Israel Standard Time for Israel, while it is parsed as India Standard Time for
|
||||
* all other regions). The zone names returned by this instance are not localized.
|
||||
*/
|
||||
static TimeZoneNames* U_EXPORT2 createTZDBInstance(const Locale& locale, UErrorCode& status);
|
||||
#endif /* U_HIDE_DRAFT_API */
|
||||
|
||||
/**
|
||||
* Returns an enumeration of all available meta zone IDs.
|
||||
* @param status Receives the status.
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2007-2013, International Business Machines Corporation and *
|
||||
* Copyright (C) 2007-2014, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
@ -76,6 +76,7 @@ TimeZoneFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name
|
|||
TESTCASE(2, TestParse);
|
||||
TESTCASE(3, TestISOFormat);
|
||||
TESTCASE(4, TestFormat);
|
||||
TESTCASE(5, TestFormatTZDBNames);
|
||||
default: name = ""; break;
|
||||
}
|
||||
}
|
||||
|
@ -685,7 +686,7 @@ typedef struct {
|
|||
int32_t inPos;
|
||||
const char* locale;
|
||||
UTimeZoneFormatStyle style;
|
||||
UBool parseAll;
|
||||
uint32_t parseOptions;
|
||||
const char* expected;
|
||||
int32_t outPos;
|
||||
UTimeZoneFormatTimeType timeType;
|
||||
|
@ -694,26 +695,94 @@ typedef struct {
|
|||
void
|
||||
TimeZoneFormatTest::TestParse(void) {
|
||||
const ParseTestData DATA[] = {
|
||||
// text inPos locale style parseAll expected outPos timeType
|
||||
{"Z", 0, "en_US", UTZFMT_STYLE_ISO_EXTENDED_FULL, false, "Etc/GMT", 1, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
{"Z", 0, "en_US", UTZFMT_STYLE_SPECIFIC_LONG, false, "Etc/GMT", 1, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
{"Zambia time", 0, "en_US", UTZFMT_STYLE_ISO_EXTENDED_FULL, true, "Etc/GMT", 1, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
{"Zambia time", 0, "en_US", UTZFMT_STYLE_GENERIC_LOCATION, false, "Africa/Lusaka", 11, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
{"Zambia time", 0, "en_US", UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL, true, "Africa/Lusaka", 11, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
{"+00:00", 0, "en_US", UTZFMT_STYLE_ISO_EXTENDED_FULL, false, "Etc/GMT", 6, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
{"-01:30:45", 0, "en_US", UTZFMT_STYLE_ISO_EXTENDED_FULL, false, "GMT-01:30:45", 9, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
{"-7", 0, "en_US", UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL, false, "GMT-07:00", 2, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
{"-2222", 0, "en_US", UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL, false, "GMT-22:22", 5, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
{"-3333", 0, "en_US", UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL, false, "GMT-03:33", 4, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
{"XXX+01:30YYY", 3, "en_US", UTZFMT_STYLE_LOCALIZED_GMT, false, "GMT+01:30", 9, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
{"GMT0", 0, "en_US", UTZFMT_STYLE_SPECIFIC_SHORT, false, "Etc/GMT", 3, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
{"EST", 0, "en_US", UTZFMT_STYLE_SPECIFIC_SHORT, false, "America/New_York", 3, UTZFMT_TIME_TYPE_STANDARD},
|
||||
{"ESTx", 0, "en_US", UTZFMT_STYLE_SPECIFIC_SHORT, false, "America/New_York", 3, UTZFMT_TIME_TYPE_STANDARD},
|
||||
{"EDTx", 0, "en_US", UTZFMT_STYLE_SPECIFIC_SHORT, false, "America/New_York", 3, UTZFMT_TIME_TYPE_DAYLIGHT},
|
||||
{"EST", 0, "en_US", UTZFMT_STYLE_SPECIFIC_LONG, false, NULL, 0, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
{"EST", 0, "en_US", UTZFMT_STYLE_SPECIFIC_LONG, true, "America/New_York", 3, UTZFMT_TIME_TYPE_STANDARD},
|
||||
{"EST", 0, "en_CA", UTZFMT_STYLE_SPECIFIC_SHORT, false, "America/Toronto", 3, UTZFMT_TIME_TYPE_STANDARD},
|
||||
{NULL, 0, NULL, UTZFMT_STYLE_GENERIC_LOCATION, false, NULL, 0, UTZFMT_TIME_TYPE_UNKNOWN}
|
||||
// text inPos locale style
|
||||
// parseOptions expected outPos timeType
|
||||
{"Z", 0, "en_US", UTZFMT_STYLE_ISO_EXTENDED_FULL,
|
||||
UTZFMT_PARSE_OPTION_NONE, "Etc/GMT", 1, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"Z", 0, "en_US", UTZFMT_STYLE_SPECIFIC_LONG,
|
||||
UTZFMT_PARSE_OPTION_NONE, "Etc/GMT", 1, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"Zambia time", 0, "en_US", UTZFMT_STYLE_ISO_EXTENDED_FULL,
|
||||
UTZFMT_PARSE_OPTION_ALL_STYLES, "Etc/GMT", 1, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"Zambia time", 0, "en_US", UTZFMT_STYLE_GENERIC_LOCATION,
|
||||
UTZFMT_PARSE_OPTION_NONE, "Africa/Lusaka", 11, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"Zambia time", 0, "en_US", UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL,
|
||||
UTZFMT_PARSE_OPTION_ALL_STYLES, "Africa/Lusaka", 11, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"+00:00", 0, "en_US", UTZFMT_STYLE_ISO_EXTENDED_FULL,
|
||||
UTZFMT_PARSE_OPTION_NONE, "Etc/GMT", 6, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"-01:30:45", 0, "en_US", UTZFMT_STYLE_ISO_EXTENDED_FULL,
|
||||
UTZFMT_PARSE_OPTION_NONE, "GMT-01:30:45", 9, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"-7", 0, "en_US", UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL,
|
||||
UTZFMT_PARSE_OPTION_NONE, "GMT-07:00", 2, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"-2222", 0, "en_US", UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL,
|
||||
UTZFMT_PARSE_OPTION_NONE, "GMT-22:22", 5, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"-3333", 0, "en_US", UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL,
|
||||
UTZFMT_PARSE_OPTION_NONE, "GMT-03:33", 4, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"XXX+01:30YYY", 3, "en_US", UTZFMT_STYLE_LOCALIZED_GMT,
|
||||
UTZFMT_PARSE_OPTION_NONE, "GMT+01:30", 9, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"GMT0", 0, "en_US", UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
UTZFMT_PARSE_OPTION_NONE, "Etc/GMT", 3, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"EST", 0, "en_US", UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
UTZFMT_PARSE_OPTION_NONE, "America/New_York", 3, UTZFMT_TIME_TYPE_STANDARD},
|
||||
|
||||
{"ESTx", 0, "en_US", UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
UTZFMT_PARSE_OPTION_NONE, "America/New_York", 3, UTZFMT_TIME_TYPE_STANDARD},
|
||||
|
||||
{"EDTx", 0, "en_US", UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
UTZFMT_PARSE_OPTION_NONE, "America/New_York", 3, UTZFMT_TIME_TYPE_DAYLIGHT},
|
||||
|
||||
{"EST", 0, "en_US", UTZFMT_STYLE_SPECIFIC_LONG,
|
||||
UTZFMT_PARSE_OPTION_NONE, NULL, 0, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"EST", 0, "en_US", UTZFMT_STYLE_SPECIFIC_LONG,
|
||||
UTZFMT_PARSE_OPTION_ALL_STYLES, "America/New_York", 3, UTZFMT_TIME_TYPE_STANDARD},
|
||||
|
||||
{"EST", 0, "en_CA", UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
UTZFMT_PARSE_OPTION_NONE, "America/Toronto", 3, UTZFMT_TIME_TYPE_STANDARD},
|
||||
|
||||
{"CST", 0, "en_US", UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
UTZFMT_PARSE_OPTION_NONE, "America/Chicago", 3, UTZFMT_TIME_TYPE_STANDARD},
|
||||
|
||||
{"CST", 0, "en_GB", UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
UTZFMT_PARSE_OPTION_NONE, NULL, 0, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"CST", 0, "en_GB", UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
UTZFMT_PARSE_OPTION_TZ_DATABASE_ABBREVIATIONS, "America/Chicago", 3, UTZFMT_TIME_TYPE_STANDARD},
|
||||
|
||||
{"--CST--", 2, "en_GB", UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
UTZFMT_PARSE_OPTION_TZ_DATABASE_ABBREVIATIONS, "America/Chicago", 5, UTZFMT_TIME_TYPE_STANDARD},
|
||||
|
||||
{"CST", 0, "zh_CN", UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
UTZFMT_PARSE_OPTION_TZ_DATABASE_ABBREVIATIONS, "Asia/Shanghai", 3, UTZFMT_TIME_TYPE_STANDARD},
|
||||
|
||||
{"EST", 0, "en_AU", UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
UTZFMT_PARSE_OPTION_TZ_DATABASE_ABBREVIATIONS, "Australia/Sydney", 3, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"AST", 0, "ar_SA", UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
UTZFMT_PARSE_OPTION_TZ_DATABASE_ABBREVIATIONS, "Asia/Riyadh", 3, UTZFMT_TIME_TYPE_STANDARD},
|
||||
|
||||
{"AQTST", 0, "en", UTZFMT_STYLE_SPECIFIC_LONG,
|
||||
UTZFMT_PARSE_OPTION_NONE, NULL, 0, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"AQTST", 0, "en", UTZFMT_STYLE_SPECIFIC_LONG,
|
||||
UTZFMT_PARSE_OPTION_ALL_STYLES, NULL, 0, UTZFMT_TIME_TYPE_UNKNOWN},
|
||||
|
||||
{"AQTST", 0, "en", UTZFMT_STYLE_SPECIFIC_LONG,
|
||||
UTZFMT_PARSE_OPTION_ALL_STYLES | UTZFMT_PARSE_OPTION_TZ_DATABASE_ABBREVIATIONS, "Asia/Aqtobe", 5, UTZFMT_TIME_TYPE_DAYLIGHT},
|
||||
|
||||
{NULL, 0, NULL, UTZFMT_STYLE_GENERIC_LOCATION,
|
||||
UTZFMT_PARSE_OPTION_NONE, NULL, 0, UTZFMT_TIME_TYPE_UNKNOWN}
|
||||
};
|
||||
|
||||
for (int32_t i = 0; DATA[i].text; i++) {
|
||||
|
@ -725,8 +794,7 @@ TimeZoneFormatTest::TestParse(void) {
|
|||
}
|
||||
UTimeZoneFormatTimeType ttype = UTZFMT_TIME_TYPE_UNKNOWN;
|
||||
ParsePosition pos(DATA[i].inPos);
|
||||
int32_t parseOptions = DATA[i].parseAll ? UTZFMT_PARSE_OPTION_ALL_STYLES : UTZFMT_PARSE_OPTION_NONE;
|
||||
TimeZone* tz = tzfmt->parse(DATA[i].style, DATA[i].text, pos, parseOptions, &ttype);
|
||||
TimeZone* tz = tzfmt->parse(DATA[i].style, DATA[i].text, pos, DATA[i].parseOptions, &ttype);
|
||||
|
||||
UnicodeString errMsg;
|
||||
if (tz) {
|
||||
|
@ -1025,4 +1093,102 @@ TimeZoneFormatTest::TestFormat(void) {
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
TimeZoneFormatTest::TestFormatTZDBNames(void) {
|
||||
UDate dateJan = 1358208000000.0; // 2013-01-15T00:00:00Z
|
||||
UDate dateJul = 1373846400000.0; // 2013-07-15T00:00:00Z
|
||||
|
||||
const FormatTestData DATA[] = {
|
||||
{
|
||||
"en",
|
||||
"America/Chicago",
|
||||
dateJan,
|
||||
UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
"CST",
|
||||
UTZFMT_TIME_TYPE_STANDARD
|
||||
},
|
||||
{
|
||||
"en",
|
||||
"Asia/Shanghai",
|
||||
dateJan,
|
||||
UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
"CST",
|
||||
UTZFMT_TIME_TYPE_STANDARD
|
||||
},
|
||||
{
|
||||
"zh_Hans",
|
||||
"Asia/Shanghai",
|
||||
dateJan,
|
||||
UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
"CST",
|
||||
UTZFMT_TIME_TYPE_STANDARD
|
||||
},
|
||||
{
|
||||
"en",
|
||||
"America/Los_Angeles",
|
||||
dateJul,
|
||||
UTZFMT_STYLE_SPECIFIC_LONG,
|
||||
"GMT-07:00", // No long display names
|
||||
UTZFMT_TIME_TYPE_DAYLIGHT
|
||||
},
|
||||
{
|
||||
"ja",
|
||||
"America/Los_Angeles",
|
||||
dateJul,
|
||||
UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
"PDT",
|
||||
UTZFMT_TIME_TYPE_DAYLIGHT
|
||||
},
|
||||
{
|
||||
"en",
|
||||
"Australia/Sydney",
|
||||
dateJan,
|
||||
UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
"EST",
|
||||
UTZFMT_TIME_TYPE_DAYLIGHT
|
||||
},
|
||||
{
|
||||
"en",
|
||||
"Australia/Sydney",
|
||||
dateJul,
|
||||
UTZFMT_STYLE_SPECIFIC_SHORT,
|
||||
"EST",
|
||||
UTZFMT_TIME_TYPE_STANDARD
|
||||
},
|
||||
|
||||
{0, 0, 0.0, UTZFMT_STYLE_GENERIC_LOCATION, 0, UTZFMT_TIME_TYPE_UNKNOWN}
|
||||
};
|
||||
|
||||
for (int32_t i = 0; DATA[i].locale; i++) {
|
||||
UErrorCode status = U_ZERO_ERROR;
|
||||
Locale loc(DATA[i].locale);
|
||||
LocalPointer<TimeZoneFormat> tzfmt(TimeZoneFormat::createInstance(loc, status));
|
||||
if (U_FAILURE(status)) {
|
||||
dataerrln("Fail TimeZoneFormat::createInstance: %s", u_errorName(status));
|
||||
continue;
|
||||
}
|
||||
TimeZoneNames *tzdbNames = TimeZoneNames::createTZDBInstance(loc, status);
|
||||
if (U_FAILURE(status)) {
|
||||
dataerrln("Fail TimeZoneNames::createTZDBInstance: %s", u_errorName(status));
|
||||
continue;
|
||||
}
|
||||
tzfmt->adoptTimeZoneNames(tzdbNames);
|
||||
|
||||
LocalPointer<TimeZone> tz(TimeZone::createTimeZone(DATA[i].tzid));
|
||||
UnicodeString out;
|
||||
UTimeZoneFormatTimeType timeType;
|
||||
|
||||
tzfmt->format(DATA[i].style, *(tz.getAlias()), DATA[i].date, out, &timeType);
|
||||
UnicodeString expected(DATA[i].expected, -1, US_INV);
|
||||
expected = expected.unescape();
|
||||
|
||||
assertEquals(UnicodeString("Format result for ") + DATA[i].tzid + " (Test Case " + i + ")", expected, out);
|
||||
if (DATA[i].timeType != timeType) {
|
||||
dataerrln(UnicodeString("Formatted time zone type (Test Case ") + i + "), returned="
|
||||
+ timeType + ", expected=" + DATA[i].timeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
*******************************************************************************
|
||||
* Copyright (C) 2007-2013, International Business Machines Corporation and *
|
||||
* Copyright (C) 2007-2014, International Business Machines Corporation and *
|
||||
* others. All Rights Reserved. *
|
||||
*******************************************************************************
|
||||
*/
|
||||
|
@ -23,6 +23,7 @@ class TimeZoneFormatTest : public IntlTest {
|
|||
void TestParse(void);
|
||||
void TestISOFormat(void);
|
||||
void TestFormat(void);
|
||||
void TestFormatTZDBNames(void);
|
||||
};
|
||||
|
||||
#endif /* #if !UCONFIG_NO_FORMATTING */
|
||||
|
|
Loading…
Add table
Reference in a new issue