OLD | NEW |
1 /* | 1 /* |
2 ******************************************************************************* | 2 ******************************************************************************* |
3 * Copyright (C) 2011-2013, International Business Machines Corporation and | 3 * Copyright (C) 2011-2014, International Business Machines Corporation and |
4 * others. All Rights Reserved. | 4 * others. All Rights Reserved. |
5 ******************************************************************************* | 5 ******************************************************************************* |
6 */ | 6 */ |
7 | 7 |
8 #include "unicode/utypes.h" | 8 #include "unicode/utypes.h" |
9 | 9 |
10 #if !UCONFIG_NO_FORMATTING | 10 #if !UCONFIG_NO_FORMATTING |
11 | 11 |
12 #include "unicode/calendar.h" | 12 #include "unicode/calendar.h" |
13 #include "unicode/tzfmt.h" | 13 #include "unicode/tzfmt.h" |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
301 } | 301 } |
302 U_CDECL_END | 302 U_CDECL_END |
303 | 303 |
304 | 304 |
305 // ------------------------------------------------------------------ | 305 // ------------------------------------------------------------------ |
306 // TimeZoneFormat | 306 // TimeZoneFormat |
307 // ------------------------------------------------------------------ | 307 // ------------------------------------------------------------------ |
308 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeZoneFormat) | 308 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(TimeZoneFormat) |
309 | 309 |
310 TimeZoneFormat::TimeZoneFormat(const Locale& locale, UErrorCode& status) | 310 TimeZoneFormat::TimeZoneFormat(const Locale& locale, UErrorCode& status) |
311 : fLocale(locale), fTimeZoneNames(NULL), fTimeZoneGenericNames(NULL), fDefParseO
ptionFlags(0) { | 311 : fLocale(locale), fTimeZoneNames(NULL), fTimeZoneGenericNames(NULL), |
| 312 fDefParseOptionFlags(0), fTZDBTimeZoneNames(NULL) { |
312 | 313 |
313 for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) { | 314 for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) { |
314 fGMTOffsetPatternItems[i] = NULL; | 315 fGMTOffsetPatternItems[i] = NULL; |
315 } | 316 } |
316 | 317 |
317 const char* region = fLocale.getCountry(); | 318 const char* region = fLocale.getCountry(); |
318 int32_t regionLen = uprv_strlen(region); | 319 int32_t regionLen = uprv_strlen(region); |
319 if (regionLen == 0) { | 320 if (regionLen == 0) { |
320 char loc[ULOC_FULLNAME_CAPACITY]; | 321 char loc[ULOC_FULLNAME_CAPACITY]; |
321 uloc_addLikelySubtags(fLocale.getName(), loc, sizeof(loc), &status); | 322 uloc_addLikelySubtags(fLocale.getName(), loc, sizeof(loc), &status); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
411 for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) { | 412 for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) { |
412 fGMTOffsetPatternItems[i] = NULL; | 413 fGMTOffsetPatternItems[i] = NULL; |
413 } | 414 } |
414 *this = other; | 415 *this = other; |
415 } | 416 } |
416 | 417 |
417 | 418 |
418 TimeZoneFormat::~TimeZoneFormat() { | 419 TimeZoneFormat::~TimeZoneFormat() { |
419 delete fTimeZoneNames; | 420 delete fTimeZoneNames; |
420 delete fTimeZoneGenericNames; | 421 delete fTimeZoneGenericNames; |
| 422 delete fTZDBTimeZoneNames; |
421 for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) { | 423 for (int32_t i = 0; i < UTZFMT_PAT_COUNT; i++) { |
422 delete fGMTOffsetPatternItems[i]; | 424 delete fGMTOffsetPatternItems[i]; |
423 } | 425 } |
424 } | 426 } |
425 | 427 |
426 TimeZoneFormat& | 428 TimeZoneFormat& |
427 TimeZoneFormat::operator=(const TimeZoneFormat& other) { | 429 TimeZoneFormat::operator=(const TimeZoneFormat& other) { |
428 if (this == &other) { | 430 if (this == &other) { |
429 return *this; | 431 return *this; |
430 } | 432 } |
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
839 } | 841 } |
840 // Note: For now, no distinction between long/short localized GMT format
in the parser. | 842 // Note: For now, no distinction between long/short localized GMT format
in the parser. |
841 // This might be changed in future. | 843 // This might be changed in future. |
842 // evaluated |= (fallbackLocalizedGMT ? STYLE_PARSE_FLAGS[UTZFMT_STYLE_L
OCALIZED_GMT] : STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT_SHORT]); | 844 // evaluated |= (fallbackLocalizedGMT ? STYLE_PARSE_FLAGS[UTZFMT_STYLE_L
OCALIZED_GMT] : STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT_SHORT]); |
843 evaluated |= STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT] | STYLE_PARSE
_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT_SHORT]; | 845 evaluated |= STYLE_PARSE_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT] | STYLE_PARSE
_FLAGS[UTZFMT_STYLE_LOCALIZED_GMT_SHORT]; |
844 } | 846 } |
845 | 847 |
846 UErrorCode status = U_ZERO_ERROR; | 848 UErrorCode status = U_ZERO_ERROR; |
847 UnicodeString tzID; | 849 UnicodeString tzID; |
848 | 850 |
| 851 UBool parseTZDBAbbrev = ((parseOptions & UTZFMT_PARSE_OPTION_TZ_DATABASE_ABB
REVIATIONS) != 0); |
| 852 |
849 // Try the specified style | 853 // Try the specified style |
850 switch (style) { | 854 switch (style) { |
851 case UTZFMT_STYLE_LOCALIZED_GMT: | 855 case UTZFMT_STYLE_LOCALIZED_GMT: |
852 { | 856 { |
853 tmpPos.setIndex(startIdx); | 857 tmpPos.setIndex(startIdx); |
854 tmpPos.setErrorIndex(-1); | 858 tmpPos.setErrorIndex(-1); |
855 | 859 |
856 offset = parseOffsetLocalizedGMT(text, tmpPos); | 860 offset = parseOffsetLocalizedGMT(text, tmpPos); |
857 if (tmpPos.getErrorIndex() == -1) { | 861 if (tmpPos.getErrorIndex() == -1) { |
858 pos.setIndex(tmpPos.getIndex()); | 862 pos.setIndex(tmpPos.getIndex()); |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
949 if (matchIdx >= 0) { | 953 if (matchIdx >= 0) { |
950 if (timeType) { | 954 if (timeType) { |
951 *timeType = getTimeType(specificMatches->getNameTypeAt(m
atchIdx)); | 955 *timeType = getTimeType(specificMatches->getNameTypeAt(m
atchIdx)); |
952 } | 956 } |
953 pos.setIndex(matchPos); | 957 pos.setIndex(matchPos); |
954 getTimeZoneID(specificMatches.getAlias(), matchIdx, tzID); | 958 getTimeZoneID(specificMatches.getAlias(), matchIdx, tzID); |
955 U_ASSERT(!tzID.isEmpty()); | 959 U_ASSERT(!tzID.isEmpty()); |
956 return TimeZone::createTimeZone(tzID); | 960 return TimeZone::createTimeZone(tzID); |
957 } | 961 } |
958 } | 962 } |
| 963 |
| 964 if (parseTZDBAbbrev && style == UTZFMT_STYLE_SPECIFIC_SHORT) { |
| 965 U_ASSERT((nameTypes & UTZNM_SHORT_STANDARD) != 0); |
| 966 U_ASSERT((nameTypes & UTZNM_SHORT_DAYLIGHT) != 0); |
| 967 |
| 968 const TZDBTimeZoneNames *tzdbTimeZoneNames = getTZDBTimeZoneName
s(status); |
| 969 if (U_SUCCESS(status)) { |
| 970 LocalPointer<TimeZoneNames::MatchInfoCollection> tzdbNameMat
ches( |
| 971 tzdbTimeZoneNames->find(text, startIdx, nameTypes, statu
s)); |
| 972 if (U_FAILURE(status)) { |
| 973 pos.setErrorIndex(startIdx); |
| 974 return NULL; |
| 975 } |
| 976 if (!tzdbNameMatches.isNull()) { |
| 977 int32_t matchIdx = -1; |
| 978 int32_t matchPos = -1; |
| 979 for (int32_t i = 0; i < tzdbNameMatches->size(); i++) { |
| 980 matchPos = startIdx + tzdbNameMatches->getMatchLengt
hAt(i); |
| 981 if (matchPos > parsedPos) { |
| 982 matchIdx = i; |
| 983 parsedPos = matchPos; |
| 984 } |
| 985 } |
| 986 if (matchIdx >= 0) { |
| 987 if (timeType) { |
| 988 *timeType = getTimeType(tzdbNameMatches->getName
TypeAt(matchIdx)); |
| 989 } |
| 990 pos.setIndex(matchPos); |
| 991 getTimeZoneID(tzdbNameMatches.getAlias(), matchIdx,
tzID); |
| 992 U_ASSERT(!tzID.isEmpty()); |
| 993 return TimeZone::createTimeZone(tzID); |
| 994 } |
| 995 } |
| 996 } |
| 997 } |
959 break; | 998 break; |
960 } | 999 } |
961 case UTZFMT_STYLE_GENERIC_LONG: | 1000 case UTZFMT_STYLE_GENERIC_LONG: |
962 case UTZFMT_STYLE_GENERIC_SHORT: | 1001 case UTZFMT_STYLE_GENERIC_SHORT: |
963 case UTZFMT_STYLE_GENERIC_LOCATION: | 1002 case UTZFMT_STYLE_GENERIC_LOCATION: |
964 { | 1003 { |
965 int32_t genericNameTypes = 0; | 1004 int32_t genericNameTypes = 0; |
966 switch (style) { | 1005 switch (style) { |
967 case UTZFMT_STYLE_GENERIC_LOCATION: | 1006 case UTZFMT_STYLE_GENERIC_LOCATION: |
968 genericNameTypes = UTZGNM_LOCATION; | 1007 genericNameTypes = UTZGNM_LOCATION; |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1161 } | 1200 } |
1162 } | 1201 } |
1163 if (parsedPos < matchPos) { | 1202 if (parsedPos < matchPos) { |
1164 U_ASSERT(specificMatchIdx >= 0); | 1203 U_ASSERT(specificMatchIdx >= 0); |
1165 parsedPos = matchPos; | 1204 parsedPos = matchPos; |
1166 getTimeZoneID(specificMatches.getAlias(), specificMatchIdx, pars
edID); | 1205 getTimeZoneID(specificMatches.getAlias(), specificMatchIdx, pars
edID); |
1167 parsedTimeType = getTimeType(specificMatches->getNameTypeAt(spec
ificMatchIdx)); | 1206 parsedTimeType = getTimeType(specificMatches->getNameTypeAt(spec
ificMatchIdx)); |
1168 parsedOffset = UNKNOWN_OFFSET; | 1207 parsedOffset = UNKNOWN_OFFSET; |
1169 } | 1208 } |
1170 } | 1209 } |
| 1210 if (parseTZDBAbbrev && parsedPos < maxPos && (evaluated & STYLE_PARSE_FL
AGS[UTZFMT_STYLE_SPECIFIC_SHORT]) == 0) { |
| 1211 const TZDBTimeZoneNames *tzdbTimeZoneNames = getTZDBTimeZoneNames(st
atus); |
| 1212 if (U_SUCCESS(status)) { |
| 1213 LocalPointer<TimeZoneNames::MatchInfoCollection> tzdbNameMatches
( |
| 1214 tzdbTimeZoneNames->find(text, startIdx, ALL_SIMPLE_NAME_TYPE
S, status)); |
| 1215 if (U_FAILURE(status)) { |
| 1216 pos.setErrorIndex(startIdx); |
| 1217 return NULL; |
| 1218 } |
| 1219 int32_t tzdbNameMatchIdx = -1; |
| 1220 int32_t matchPos = -1; |
| 1221 if (!tzdbNameMatches.isNull()) { |
| 1222 for (int32_t i = 0; i < tzdbNameMatches->size(); i++) { |
| 1223 if (startIdx + tzdbNameMatches->getMatchLengthAt(i) > ma
tchPos) { |
| 1224 tzdbNameMatchIdx = i; |
| 1225 matchPos = startIdx + tzdbNameMatches->getMatchLengt
hAt(i); |
| 1226 } |
| 1227 } |
| 1228 } |
| 1229 if (parsedPos < matchPos) { |
| 1230 U_ASSERT(tzdbNameMatchIdx >= 0); |
| 1231 parsedPos = matchPos; |
| 1232 getTimeZoneID(tzdbNameMatches.getAlias(), tzdbNameMatchIdx,
parsedID); |
| 1233 parsedTimeType = getTimeType(tzdbNameMatches->getNameTypeAt(
tzdbNameMatchIdx)); |
| 1234 parsedOffset = UNKNOWN_OFFSET; |
| 1235 } |
| 1236 } |
| 1237 } |
1171 // Try generic names | 1238 // Try generic names |
1172 if (parsedPos < maxPos) { | 1239 if (parsedPos < maxPos) { |
1173 int32_t genMatchLen = -1; | 1240 int32_t genMatchLen = -1; |
1174 UTimeZoneFormatTimeType tt = UTZFMT_TIME_TYPE_UNKNOWN; | 1241 UTimeZoneFormatTimeType tt = UTZFMT_TIME_TYPE_UNKNOWN; |
1175 | 1242 |
1176 const TimeZoneGenericNames *gnames = getTimeZoneGenericNames(status)
; | 1243 const TimeZoneGenericNames *gnames = getTimeZoneGenericNames(status)
; |
1177 if (U_SUCCESS(status)) { | 1244 if (U_SUCCESS(status)) { |
1178 genMatchLen = gnames->findBestMatch(text, startIdx, ALL_GENERIC_
NAME_TYPES, tzID, tt, status); | 1245 genMatchLen = gnames->findBestMatch(text, startIdx, ALL_GENERIC_
NAME_TYPES, tzID, tt, status); |
1179 } | 1246 } |
1180 if (U_FAILURE(status)) { | 1247 if (U_FAILURE(status)) { |
1181 pos.setErrorIndex(startIdx); | 1248 pos.setErrorIndex(startIdx); |
1182 return NULL; | 1249 return NULL; |
1183 } | 1250 } |
1184 | 1251 |
1185 if (parsedPos < startIdx + genMatchLen) { | 1252 if (genMatchLen > 0 && parsedPos < startIdx + genMatchLen) { |
1186 parsedPos = startIdx + genMatchLen; | 1253 parsedPos = startIdx + genMatchLen; |
1187 parsedID.setTo(tzID); | 1254 parsedID.setTo(tzID); |
1188 parsedTimeType = tt; | 1255 parsedTimeType = tt; |
1189 parsedOffset = UNKNOWN_OFFSET; | 1256 parsedOffset = UNKNOWN_OFFSET; |
1190 } | 1257 } |
1191 } | 1258 } |
1192 | 1259 |
1193 // Try time zone ID | 1260 // Try time zone ID |
1194 if (parsedPos < maxPos && (evaluated & STYLE_PARSE_FLAGS[UTZFMT_STYLE_ZO
NE_ID]) == 0) { | 1261 if (parsedPos < maxPos && (evaluated & STYLE_PARSE_FLAGS[UTZFMT_STYLE_ZO
NE_ID]) == 0) { |
1195 tmpPos.setIndex(startIdx); | 1262 tmpPos.setIndex(startIdx); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1306 umtx_lock(&gLock); | 1373 umtx_lock(&gLock); |
1307 if (fTimeZoneGenericNames == NULL) { | 1374 if (fTimeZoneGenericNames == NULL) { |
1308 TimeZoneFormat *nonConstThis = const_cast<TimeZoneFormat *>(this); | 1375 TimeZoneFormat *nonConstThis = const_cast<TimeZoneFormat *>(this); |
1309 nonConstThis->fTimeZoneGenericNames = TimeZoneGenericNames::createInstan
ce(fLocale, status); | 1376 nonConstThis->fTimeZoneGenericNames = TimeZoneGenericNames::createInstan
ce(fLocale, status); |
1310 } | 1377 } |
1311 umtx_unlock(&gLock); | 1378 umtx_unlock(&gLock); |
1312 | 1379 |
1313 return fTimeZoneGenericNames; | 1380 return fTimeZoneGenericNames; |
1314 } | 1381 } |
1315 | 1382 |
| 1383 const TZDBTimeZoneNames* |
| 1384 TimeZoneFormat::getTZDBTimeZoneNames(UErrorCode& status) const { |
| 1385 if (U_FAILURE(status)) { |
| 1386 return NULL; |
| 1387 } |
| 1388 |
| 1389 umtx_lock(&gLock); |
| 1390 if (fTZDBTimeZoneNames == NULL) { |
| 1391 TZDBTimeZoneNames *tzdbNames = new TZDBTimeZoneNames(fLocale); |
| 1392 if (tzdbNames == NULL) { |
| 1393 status = U_MEMORY_ALLOCATION_ERROR; |
| 1394 } else { |
| 1395 TimeZoneFormat *nonConstThis = const_cast<TimeZoneFormat *>(this); |
| 1396 nonConstThis->fTZDBTimeZoneNames = tzdbNames; |
| 1397 } |
| 1398 } |
| 1399 umtx_unlock(&gLock); |
| 1400 |
| 1401 return fTZDBTimeZoneNames; |
| 1402 } |
| 1403 |
1316 UnicodeString& | 1404 UnicodeString& |
1317 TimeZoneFormat::formatExemplarLocation(const TimeZone& tz, UnicodeString& name)
const { | 1405 TimeZoneFormat::formatExemplarLocation(const TimeZone& tz, UnicodeString& name)
const { |
1318 UnicodeString location; | 1406 UnicodeString location; |
1319 const UChar* canonicalID = ZoneMeta::getCanonicalCLDRID(tz); | 1407 const UChar* canonicalID = ZoneMeta::getCanonicalCLDRID(tz); |
1320 | 1408 |
1321 if (canonicalID) { | 1409 if (canonicalID) { |
1322 fTimeZoneNames->getExemplarLocationName(UnicodeString(canonicalID), loca
tion); | 1410 fTimeZoneNames->getExemplarLocationName(UnicodeString(canonicalID), loca
tion); |
1323 } | 1411 } |
1324 if (location.length() > 0) { | 1412 if (location.length() > 0) { |
1325 name.setTo(location); | 1413 name.setTo(location); |
(...skipping 1243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2569 switch (nameType) { | 2657 switch (nameType) { |
2570 case UTZNM_LONG_STANDARD: | 2658 case UTZNM_LONG_STANDARD: |
2571 case UTZNM_SHORT_STANDARD: | 2659 case UTZNM_SHORT_STANDARD: |
2572 return UTZFMT_TIME_TYPE_STANDARD; | 2660 return UTZFMT_TIME_TYPE_STANDARD; |
2573 | 2661 |
2574 case UTZNM_LONG_DAYLIGHT: | 2662 case UTZNM_LONG_DAYLIGHT: |
2575 case UTZNM_SHORT_DAYLIGHT: | 2663 case UTZNM_SHORT_DAYLIGHT: |
2576 return UTZFMT_TIME_TYPE_DAYLIGHT; | 2664 return UTZFMT_TIME_TYPE_DAYLIGHT; |
2577 | 2665 |
2578 default: | 2666 default: |
2579 U_ASSERT(FALSE); | 2667 return UTZFMT_TIME_TYPE_UNKNOWN; |
2580 } | 2668 } |
2581 return UTZFMT_TIME_TYPE_UNKNOWN; | |
2582 } | 2669 } |
2583 | 2670 |
2584 UnicodeString& | 2671 UnicodeString& |
2585 TimeZoneFormat::getTimeZoneID(const TimeZoneNames::MatchInfoCollection* matches,
int32_t idx, UnicodeString& tzID) const { | 2672 TimeZoneFormat::getTimeZoneID(const TimeZoneNames::MatchInfoCollection* matches,
int32_t idx, UnicodeString& tzID) const { |
2586 if (!matches->getTimeZoneIDAt(idx, tzID)) { | 2673 if (!matches->getTimeZoneIDAt(idx, tzID)) { |
2587 UnicodeString mzID; | 2674 UnicodeString mzID; |
2588 if (matches->getMetaZoneIDAt(idx, mzID)) { | 2675 if (matches->getMetaZoneIDAt(idx, mzID)) { |
2589 fTimeZoneNames->getReferenceZoneID(mzID, fTargetRegion, tzID); | 2676 fTimeZoneNames->getReferenceZoneID(mzID, fTargetRegion, tzID); |
2590 } | 2677 } |
2591 } | 2678 } |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2768 if (tzID.length() == 0) { | 2855 if (tzID.length() == 0) { |
2769 pos.setErrorIndex(startIdx); | 2856 pos.setErrorIndex(startIdx); |
2770 } | 2857 } |
2771 | 2858 |
2772 return tzID; | 2859 return tzID; |
2773 } | 2860 } |
2774 | 2861 |
2775 U_NAMESPACE_END | 2862 U_NAMESPACE_END |
2776 | 2863 |
2777 #endif | 2864 #endif |
OLD | NEW |