summaryrefslogtreecommitdiff
path: root/deps/icu-small/source/i18n/dtptngen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'deps/icu-small/source/i18n/dtptngen.cpp')
-rw-r--r--deps/icu-small/source/i18n/dtptngen.cpp76
1 files changed, 55 insertions, 21 deletions
diff --git a/deps/icu-small/source/i18n/dtptngen.cpp b/deps/icu-small/source/i18n/dtptngen.cpp
index 9ca29a3cc7..50a377259a 100644
--- a/deps/icu-small/source/i18n/dtptngen.cpp
+++ b/deps/icu-small/source/i18n/dtptngen.cpp
@@ -28,6 +28,7 @@
#include "unicode/ures.h"
#include "unicode/ustring.h"
#include "unicode/rep.h"
+#include "unicode/region.h"
#include "cpputils.h"
#include "mutex.h"
#include "umutex.h"
@@ -613,29 +614,56 @@ U_CFUNC void U_CALLCONV DateTimePatternGenerator::loadAllowedHourFormatsData(UEr
ures_getAllItemsWithFallback(rb.getAlias(), "timeData", sink, status);
}
-void DateTimePatternGenerator::getAllowedHourFormats(const Locale &locale, UErrorCode &status) {
- if (U_FAILURE(status)) { return; }
- Locale maxLocale(locale);
- maxLocale.addLikelySubtags(status);
- if (U_FAILURE(status)) {
- return;
- }
-
- const char *country = maxLocale.getCountry();
- if (*country == '\0') { country = "001"; }
- const char *language = maxLocale.getLanguage();
-
+static int32_t* getAllowedHourFormatsLangCountry(const char* language, const char* country, UErrorCode& status) {
CharString langCountry;
- langCountry.append(language, static_cast<int32_t>(uprv_strlen(language)), status);
+ langCountry.append(language, status);
langCountry.append('_', status);
- langCountry.append(country, static_cast<int32_t>(uprv_strlen(country)), status);
+ langCountry.append(country, status);
- int32_t *allowedFormats;
+ int32_t* allowedFormats;
allowedFormats = (int32_t *)uhash_get(localeToAllowedHourFormatsMap, langCountry.data());
if (allowedFormats == nullptr) {
allowedFormats = (int32_t *)uhash_get(localeToAllowedHourFormatsMap, const_cast<char *>(country));
}
+ return allowedFormats;
+}
+
+void DateTimePatternGenerator::getAllowedHourFormats(const Locale &locale, UErrorCode &status) {
+ if (U_FAILURE(status)) { return; }
+
+ const char *language = locale.getLanguage();
+ const char *country = locale.getCountry();
+ Locale maxLocale; // must be here for correct lifetime
+ if (*language == '\0' || *country == '\0') {
+ maxLocale = locale;
+ UErrorCode localStatus = U_ZERO_ERROR;
+ maxLocale.addLikelySubtags(localStatus);
+ if (U_SUCCESS(localStatus)) {
+ language = maxLocale.getLanguage();
+ country = maxLocale.getCountry();
+ }
+ }
+ if (*language == '\0') {
+ // Unexpected, but fail gracefully
+ language = "und";
+ }
+ if (*country == '\0') {
+ country = "001";
+ }
+
+ int32_t* allowedFormats = getAllowedHourFormatsLangCountry(language, country, status);
+
+ // Check if the region has an alias
+ if (allowedFormats == nullptr) {
+ UErrorCode localStatus = U_ZERO_ERROR;
+ const Region* region = Region::getInstance(country, localStatus);
+ if (U_SUCCESS(localStatus)) {
+ country = region->getRegionCode(); // the real region code
+ allowedFormats = getAllowedHourFormatsLangCountry(language, country, status);
+ }
+ }
+
if (allowedFormats != nullptr) { // Lookup is successful
// Here allowedFormats points to a list consisting of key for preferredFormat,
// followed by one or more keys for allowedFormats, then followed by ALLOWED_HOUR_FORMAT_UNKNOWN.
@@ -787,6 +815,7 @@ void
DateTimePatternGenerator::getCalendarTypeToUse(const Locale& locale, CharString& destination, UErrorCode& err) {
destination.clear().append(DT_DateTimeGregorianTag, -1, err); // initial default
if ( U_SUCCESS(err) ) {
+ UErrorCode localStatus = U_ZERO_ERROR;
char localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY];
// obtain a locale that always has the calendar key value that should be used
ures_getFunctionalEquivalent(
@@ -798,8 +827,7 @@ DateTimePatternGenerator::getCalendarTypeToUse(const Locale& locale, CharString&
locale.getName(),
nullptr,
FALSE,
- &err);
- if (U_FAILURE(err)) { return; }
+ &localStatus);
localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY-1] = 0; // ensure null termination
// now get the calendar key value from that locale
char calendarType[ULOC_KEYWORDS_CAPACITY];
@@ -808,13 +836,17 @@ DateTimePatternGenerator::getCalendarTypeToUse(const Locale& locale, CharString&
"calendar",
calendarType,
ULOC_KEYWORDS_CAPACITY,
- &err);
- if (U_FAILURE(err)) { return; }
+ &localStatus);
+ // If the input locale was invalid, don't fail with missing resource error, instead
+ // continue with default of Gregorian.
+ if (U_FAILURE(localStatus) && localStatus != U_MISSING_RESOURCE_ERROR) {
+ err = localStatus;
+ return;
+ }
if (calendarTypeLen < ULOC_KEYWORDS_CAPACITY) {
destination.clear().append(calendarType, -1, err);
if (U_FAILURE(err)) { return; }
}
- err = U_ZERO_ERROR;
}
}
@@ -2543,7 +2575,8 @@ UChar SkeletonFields::getFirstChar() const {
}
-PtnSkeleton::PtnSkeleton() {
+PtnSkeleton::PtnSkeleton()
+ : addedDefaultDayPeriod(FALSE) {
}
PtnSkeleton::PtnSkeleton(const PtnSkeleton& other) {
@@ -2554,6 +2587,7 @@ void PtnSkeleton::copyFrom(const PtnSkeleton& other) {
uprv_memcpy(type, other.type, sizeof(type));
original.copyFrom(other.original);
baseOriginal.copyFrom(other.baseOriginal);
+ addedDefaultDayPeriod = other.addedDefaultDayPeriod;
}
void PtnSkeleton::clear() {