summaryrefslogtreecommitdiff
path: root/Build/source/libs/icu/icu-src/source/i18n/smpdtfmt.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/icu/icu-src/source/i18n/smpdtfmt.cpp')
-rw-r--r--Build/source/libs/icu/icu-src/source/i18n/smpdtfmt.cpp95
1 files changed, 76 insertions, 19 deletions
diff --git a/Build/source/libs/icu/icu-src/source/i18n/smpdtfmt.cpp b/Build/source/libs/icu/icu-src/source/i18n/smpdtfmt.cpp
index 2bc8e49625f..5fcbb5875b2 100644
--- a/Build/source/libs/icu/icu-src/source/i18n/smpdtfmt.cpp
+++ b/Build/source/libs/icu/icu-src/source/i18n/smpdtfmt.cpp
@@ -230,7 +230,7 @@ static const int32_t gFieldRangeBias[] = {
static const int32_t HEBREW_CAL_CUR_MILLENIUM_START_YEAR = 5000;
static const int32_t HEBREW_CAL_CUR_MILLENIUM_END_YEAR = 6000;
-static UMutex LOCK = U_MUTEX_INITIALIZER;
+static UMutex LOCK;
UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleDateFormat)
@@ -620,7 +620,7 @@ SimpleDateFormat& SimpleDateFormat::operator=(const SimpleDateFormat& other)
//----------------------------------------------------------------------
-Format*
+SimpleDateFormat*
SimpleDateFormat::clone() const
{
return new SimpleDateFormat(*this);
@@ -856,6 +856,17 @@ SimpleDateFormat::initialize(const Locale& locale,
{
if (U_FAILURE(status)) return;
+ parsePattern(); // Need this before initNumberFormatters(), to set fHasHanYearChar
+
+ // Simple-minded hack to force Gannen year numbering for ja@calendar=japanese
+ // if format is non-numeric (includes 年) and fDateOverride is not already specified.
+ // Now this does get updated if applyPattern subsequently changes the pattern type.
+ if (fDateOverride.isBogus() && fHasHanYearChar &&
+ fCalendar != nullptr && uprv_strcmp(fCalendar->getType(),"japanese") == 0 &&
+ uprv_strcmp(fLocale.getLanguage(),"ja") == 0) {
+ fDateOverride.setTo(u"y=jpanyear", -1);
+ }
+
// We don't need to check that the row count is >= 1, since all 2d arrays have at
// least one row
fNumberFormat = NumberFormat::createInstance(locale, status);
@@ -872,8 +883,6 @@ SimpleDateFormat::initialize(const Locale& locale,
{
status = U_MISSING_RESOURCE_ERROR;
}
-
- parsePattern();
}
/* Initialize the fields we use to disambiguate ambiguous years. Separate
@@ -1211,10 +1220,14 @@ _appendSymbolWithMonthPattern(UnicodeString& dst, int32_t value, const UnicodeSt
//----------------------------------------------------------------------
static number::LocalizedNumberFormatter*
-createFastFormatter(const DecimalFormat* df, int32_t minInt, int32_t maxInt) {
- return new number::LocalizedNumberFormatter(
- df->toNumberFormatter()
- .integerWidth(number::IntegerWidth::zeroFillTo(minInt).truncateAt(maxInt)));
+createFastFormatter(const DecimalFormat* df, int32_t minInt, int32_t maxInt, UErrorCode& status) {
+ const number::LocalizedNumberFormatter* lnfBase = df->toNumberFormatter(status);
+ if (U_FAILURE(status)) {
+ return nullptr;
+ }
+ return lnfBase->integerWidth(
+ number::IntegerWidth::zeroFillTo(minInt).truncateAt(maxInt)
+ ).clone().orphan();
}
void SimpleDateFormat::initFastNumberFormatters(UErrorCode& status) {
@@ -1225,11 +1238,11 @@ void SimpleDateFormat::initFastNumberFormatters(UErrorCode& status) {
if (df == nullptr) {
return;
}
- fFastNumberFormatters[SMPDTFMT_NF_1x10] = createFastFormatter(df, 1, 10);
- fFastNumberFormatters[SMPDTFMT_NF_2x10] = createFastFormatter(df, 2, 10);
- fFastNumberFormatters[SMPDTFMT_NF_3x10] = createFastFormatter(df, 3, 10);
- fFastNumberFormatters[SMPDTFMT_NF_4x10] = createFastFormatter(df, 4, 10);
- fFastNumberFormatters[SMPDTFMT_NF_2x2] = createFastFormatter(df, 2, 2);
+ fFastNumberFormatters[SMPDTFMT_NF_1x10] = createFastFormatter(df, 1, 10, status);
+ fFastNumberFormatters[SMPDTFMT_NF_2x10] = createFastFormatter(df, 2, 10, status);
+ fFastNumberFormatters[SMPDTFMT_NF_3x10] = createFastFormatter(df, 3, 10, status);
+ fFastNumberFormatters[SMPDTFMT_NF_4x10] = createFastFormatter(df, 4, 10, status);
+ fFastNumberFormatters[SMPDTFMT_NF_2x2] = createFastFormatter(df, 2, 2, status);
}
void SimpleDateFormat::freeFastNumberFormatters() {
@@ -1778,7 +1791,7 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
}
}
else {
- U_ASSERT(FALSE);
+ UPRV_UNREACHABLE;
}
}
appendTo += zoneString;
@@ -1950,7 +1963,8 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
}
#if !UCONFIG_NO_BREAK_ITERATION
// if first field, check to see whether we need to and are able to titlecase it
- if (fieldNum == 0 && u_islower(appendTo.char32At(beginOffset)) && fCapitalizationBrkIter != NULL) {
+ if (fieldNum == 0 && fCapitalizationBrkIter != NULL && appendTo.length() > beginOffset &&
+ u_islower(appendTo.char32At(beginOffset))) {
UBool titlecase = FALSE;
switch (capitalizationContext) {
case UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE:
@@ -1967,9 +1981,11 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
break;
}
if (titlecase) {
+ BreakIterator* const mutableCapitalizationBrkIter = fCapitalizationBrkIter->clone();
UnicodeString firstField(appendTo, beginOffset);
- firstField.toTitle(fCapitalizationBrkIter, fLocale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
+ firstField.toTitle(mutableCapitalizationBrkIter, fLocale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
appendTo.replaceBetween(beginOffset, appendTo.length(), firstField);
+ delete mutableCapitalizationBrkIter;
}
}
#endif
@@ -2079,7 +2095,7 @@ SimpleDateFormat::zeroPaddingNumber(
if (U_FAILURE(localStatus)) {
return;
}
- appendTo.append(result.string.toTempUnicodeString());
+ appendTo.append(result.getStringRef().toTempUnicodeString());
return;
}
@@ -2094,7 +2110,7 @@ SimpleDateFormat::zeroPaddingNumber(
// Fall back to slow path (clone and mutate the NumberFormat)
if (currentNumberFormat != nullptr) {
FieldPosition pos(FieldPosition::DONT_CARE);
- LocalPointer<NumberFormat> nf(dynamic_cast<NumberFormat*>(currentNumberFormat->clone()));
+ LocalPointer<NumberFormat> nf(currentNumberFormat->clone());
nf->setMinimumIntegerDigits(minDigits);
nf->setMaximumIntegerDigits(maxDigits);
nf->format(value, appendTo, pos); // 3rd arg is there to speed up processing
@@ -3757,7 +3773,7 @@ void SimpleDateFormat::parseInt(const UnicodeString& text,
auto* fmtAsDF = dynamic_cast<const DecimalFormat*>(fmt);
LocalPointer<DecimalFormat> df;
if (!allowNegative && fmtAsDF != nullptr) {
- df.adoptInstead(dynamic_cast<DecimalFormat*>(fmtAsDF->clone()));
+ df.adoptInstead(fmtAsDF->clone());
if (df.isNull()) {
// Memory allocation error
return;
@@ -3872,6 +3888,42 @@ SimpleDateFormat::applyPattern(const UnicodeString& pattern)
{
fPattern = pattern;
parsePattern();
+
+ // Hack to update use of Gannen year numbering for ja@calendar=japanese -
+ // use only if format is non-numeric (includes 年) and no other fDateOverride.
+ if (fCalendar != nullptr && uprv_strcmp(fCalendar->getType(),"japanese") == 0 &&
+ uprv_strcmp(fLocale.getLanguage(),"ja") == 0) {
+ if (fDateOverride==UnicodeString(u"y=jpanyear") && !fHasHanYearChar) {
+ // Gannen numbering is set but new pattern should not use it, unset;
+ // use procedure from adoptNumberFormat to clear overrides
+ if (fSharedNumberFormatters) {
+ freeSharedNumberFormatters(fSharedNumberFormatters);
+ fSharedNumberFormatters = NULL;
+ }
+ fDateOverride.setToBogus(); // record status
+ } else if (fDateOverride.isBogus() && fHasHanYearChar) {
+ // No current override (=> no Gannen numbering) but new pattern needs it;
+ // use procedures from initNUmberFormatters / adoptNumberFormat
+ umtx_lock(&LOCK);
+ if (fSharedNumberFormatters == NULL) {
+ fSharedNumberFormatters = allocSharedNumberFormatters();
+ }
+ umtx_unlock(&LOCK);
+ if (fSharedNumberFormatters != NULL) {
+ Locale ovrLoc(fLocale.getLanguage(),fLocale.getCountry(),fLocale.getVariant(),"numbers=jpanyear");
+ UErrorCode status = U_ZERO_ERROR;
+ const SharedNumberFormat *snf = createSharedNumberFormat(ovrLoc, status);
+ if (U_SUCCESS(status)) {
+ // Now that we have an appropriate number formatter, fill in the
+ // appropriate slot in the number formatters table.
+ UDateFormatField patternCharIndex = DateFormatSymbols::getPatternCharIndex(u'y');
+ SharedObject::copyPtr(snf, fSharedNumberFormatters[patternCharIndex]);
+ snf->deleteIfZeroRefCount();
+ fDateOverride.setTo(u"y=jpanyear", -1); // record status
+ }
+ }
+ }
+ }
}
//----------------------------------------------------------------------
@@ -3949,6 +4001,7 @@ void SimpleDateFormat::adoptCalendar(Calendar* calendarToAdopt)
DateFormatSymbols *newSymbols =
DateFormatSymbols::createForLocale(calLocale, status);
if (U_FAILURE(status)) {
+ delete calendarToAdopt;
return;
}
DateFormat::adoptCalendar(calendarToAdopt);
@@ -4207,6 +4260,7 @@ SimpleDateFormat::tzFormat(UErrorCode &status) const {
void SimpleDateFormat::parsePattern() {
fHasMinute = FALSE;
fHasSecond = FALSE;
+ fHasHanYearChar = FALSE;
int len = fPattern.length();
UBool inQuote = FALSE;
@@ -4215,6 +4269,9 @@ void SimpleDateFormat::parsePattern() {
if (ch == QUOTE) {
inQuote = !inQuote;
}
+ if (ch == 0x5E74) { // don't care whether this is inside quotes
+ fHasHanYearChar = TRUE;
+ }
if (!inQuote) {
if (ch == 0x6D) { // 0x6D == 'm'
fHasMinute = TRUE;