Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(182)

Unified Diff: source/i18n/smpdtfmt.cpp

Issue 845603002: Update ICU to 54.1 step 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/icu.git@master
Patch Set: remove unusued directories Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « source/i18n/sharedpluralrules.h ('k') | source/i18n/stsearch.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: source/i18n/smpdtfmt.cpp
diff --git a/source/i18n/smpdtfmt.cpp b/source/i18n/smpdtfmt.cpp
index 28fd78f982d5607ffcda0c1c46c0663065ac8a6f..901664115cc773d2b57651e90f2de01a8c12871c 100644
--- a/source/i18n/smpdtfmt.cpp
+++ b/source/i18n/smpdtfmt.cpp
@@ -1,6 +1,6 @@
/*
*******************************************************************************
-* Copyright (C) 1997-2013, International Business Machines Corporation and *
+* Copyright (C) 1997-2014, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*
@@ -29,7 +29,6 @@
#include "unicode/utypes.h"
#if !UCONFIG_NO_FORMATTING
-
#include "unicode/smpdtfmt.h"
#include "unicode/dtfmtsym.h"
#include "unicode/ures.h"
@@ -49,6 +48,7 @@
#include "unicode/utf16.h"
#include "unicode/vtzone.h"
#include "unicode/udisplaycontext.h"
+#include "unicode/brkiter.h"
#include "olsontz.h"
#include "patternprops.h"
#include "fphdlimp.h"
@@ -125,8 +125,9 @@ static const UDateFormatField kDateFields[] = {
UDAT_STANDALONE_MONTH_FIELD,
UDAT_QUARTER_FIELD,
UDAT_STANDALONE_QUARTER_FIELD,
- UDAT_YEAR_NAME_FIELD };
-static const int8_t kDateFieldsCount = 15;
+ UDAT_YEAR_NAME_FIELD,
+ UDAT_RELATED_YEAR_FIELD };
+static const int8_t kDateFieldsCount = 16;
static const UDateFormatField kTimeFields[] = {
UDAT_HOUR_OF_DAY1_FIELD,
@@ -202,11 +203,12 @@ static const int32_t gFieldRangeBias[] = {
1, // 'L' - UDAT_STANDALONE_MONTH_FIELD
-1, // 'Q' - UDAT_QUARTER_FIELD (1-4?)
-1, // 'q' - UDAT_STANDALONE_QUARTER_FIELD
- -1 // 'V' - UDAT_TIMEZONE_SPECIAL_FIELD
+ -1, // 'V' - UDAT_TIMEZONE_SPECIAL_FIELD
-1, // 'U' - UDAT_YEAR_NAME_FIELD
-1, // 'O' - UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD
-1, // 'X' - UDAT_TIMEZONE_ISO_FIELD
-1, // 'x' - UDAT_TIMEZONE_ISO_LOCAL_FIELD
+ -1, // 'r' - UDAT_RELATED_YEAR_FIELD
};
// When calendar uses hebr numbering (i.e. he@calendar=hebrew),
@@ -236,6 +238,10 @@ SimpleDateFormat::~SimpleDateFormat()
delete cur->nf;
uprv_free(cur);
}
+
+#if !UCONFIG_NO_BREAK_ITERATION
+ delete fCapitalizationBrkIter;
+#endif
}
//----------------------------------------------------------------------
@@ -246,9 +252,9 @@ SimpleDateFormat::SimpleDateFormat(UErrorCode& status)
fTimeZoneFormat(NULL),
fNumberFormatters(NULL),
fOverrideList(NULL),
- fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
+ fCapitalizationBrkIter(NULL)
{
- setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, true, status);
+ initializeBooleanAttributes();
construct(kShort, (EStyle) (kShort + kDateOffset), fLocale, status);
initializeDefaultCentury();
}
@@ -263,11 +269,11 @@ SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
fTimeZoneFormat(NULL),
fNumberFormatters(NULL),
fOverrideList(NULL),
- fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
+ fCapitalizationBrkIter(NULL)
{
fDateOverride.setToBogus();
fTimeOverride.setToBogus();
- setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, true, status);
+ initializeBooleanAttributes();
initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status);
initialize(fLocale, status);
initializeDefaultCentury();
@@ -284,11 +290,11 @@ SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
fTimeZoneFormat(NULL),
fNumberFormatters(NULL),
fOverrideList(NULL),
- fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
+ fCapitalizationBrkIter(NULL)
{
fDateOverride.setTo(override);
fTimeOverride.setToBogus();
- setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, true, status);
+ initializeBooleanAttributes();
initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status);
initialize(fLocale, status);
initializeDefaultCentury();
@@ -307,12 +313,12 @@ SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
fTimeZoneFormat(NULL),
fNumberFormatters(NULL),
fOverrideList(NULL),
- fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
+ fCapitalizationBrkIter(NULL)
{
fDateOverride.setToBogus();
fTimeOverride.setToBogus();
- setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, true, status);
+ initializeBooleanAttributes();
initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status);
initialize(fLocale, status);
@@ -330,12 +336,12 @@ SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
fTimeZoneFormat(NULL),
fNumberFormatters(NULL),
fOverrideList(NULL),
- fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
+ fCapitalizationBrkIter(NULL)
{
fDateOverride.setTo(override);
fTimeOverride.setToBogus();
- setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, true, status);
+ initializeBooleanAttributes();
initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status);
initialize(fLocale, status);
@@ -356,12 +362,12 @@ SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
fTimeZoneFormat(NULL),
fNumberFormatters(NULL),
fOverrideList(NULL),
- fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
+ fCapitalizationBrkIter(NULL)
{
fDateOverride.setToBogus();
fTimeOverride.setToBogus();
- setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, true, status);
+ initializeBooleanAttributes();
initializeCalendar(NULL,fLocale,status);
initialize(fLocale, status);
@@ -379,12 +385,12 @@ SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern,
fTimeZoneFormat(NULL),
fNumberFormatters(NULL),
fOverrideList(NULL),
- fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
+ fCapitalizationBrkIter(NULL)
{
fDateOverride.setToBogus();
fTimeOverride.setToBogus();
- setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, true, status);
+ initializeBooleanAttributes();
initializeCalendar(NULL, fLocale, status);
initialize(fLocale, status);
@@ -403,9 +409,9 @@ SimpleDateFormat::SimpleDateFormat(EStyle timeStyle,
fTimeZoneFormat(NULL),
fNumberFormatters(NULL),
fOverrideList(NULL),
- fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
+ fCapitalizationBrkIter(NULL)
{
- setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, true, status);
+ initializeBooleanAttributes();
construct(timeStyle, dateStyle, fLocale, status);
if(U_SUCCESS(status)) {
initializeDefaultCentury();
@@ -427,9 +433,10 @@ SimpleDateFormat::SimpleDateFormat(const Locale& locale,
fTimeZoneFormat(NULL),
fNumberFormatters(NULL),
fOverrideList(NULL),
- fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
+ fCapitalizationBrkIter(NULL)
{
if (U_FAILURE(status)) return;
+ initializeBooleanAttributes();
initializeSymbols(fLocale, initializeCalendar(NULL, fLocale, status),status);
if (U_FAILURE(status))
{
@@ -446,7 +453,6 @@ SimpleDateFormat::SimpleDateFormat(const Locale& locale,
fDateOverride.setToBogus();
fTimeOverride.setToBogus();
- setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, true, status);
initialize(fLocale, status);
if(U_SUCCESS(status)) {
@@ -463,10 +469,9 @@ SimpleDateFormat::SimpleDateFormat(const SimpleDateFormat& other)
fTimeZoneFormat(NULL),
fNumberFormatters(NULL),
fOverrideList(NULL),
- fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
+ fCapitalizationBrkIter(NULL)
{
- UErrorCode status = U_ZERO_ERROR;
- setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, true, status);
+ initializeBooleanAttributes();
*this = other;
}
@@ -498,7 +503,11 @@ SimpleDateFormat& SimpleDateFormat::operator=(const SimpleDateFormat& other)
fLocale = other.fLocale;
}
- fCapitalizationContext = other.fCapitalizationContext;
+#if !UCONFIG_NO_BREAK_ITERATION
+ if (other.fCapitalizationBrkIter != NULL) {
+ fCapitalizationBrkIter = (other.fCapitalizationBrkIter)->clone();
+ }
+#endif
return *this;
}
@@ -517,6 +526,8 @@ UBool
SimpleDateFormat::operator==(const Format& other) const
{
if (DateFormat::operator==(other)) {
+ // The DateFormat::operator== check for fCapitalizationContext equality above
+ // is sufficient to check equality of all derived context-related data.
// DateFormat::operator== guarantees following cast is safe
SimpleDateFormat* that = (SimpleDateFormat*)&other;
return (fPattern == that->fPattern &&
@@ -524,8 +535,7 @@ SimpleDateFormat::operator==(const Format& other) const
that->fSymbols != NULL && // Check for pathological object
*fSymbols == *that->fSymbols &&
fHaveDefaultCentury == that->fHaveDefaultCentury &&
- fDefaultCenturyStart == that->fDefaultCenturyStart &&
- fCapitalizationContext == that->fCapitalizationContext);
+ fDefaultCenturyStart == that->fDefaultCenturyStart);
}
return FALSE;
}
@@ -804,6 +814,19 @@ void SimpleDateFormat::initializeDefaultCentury()
}
}
+/*
+ * Initialize the boolean attributes. Separate so we can call it from all constructors.
+ */
+void SimpleDateFormat::initializeBooleanAttributes()
+{
+ UErrorCode status = U_ZERO_ERROR;
+
+ setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status);
+ setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, true, status);
+ setBooleanAttribute(UDAT_PARSE_PARTIAL_MATCH, true, status);
+ setBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, true, status);
+}
+
/* Define one-century window into which to disambiguate dates using
* two-digit years. Make public in JDK 1.2.
*/
@@ -876,6 +899,7 @@ SimpleDateFormat::_format(Calendar& cal, UnicodeString& appendTo,
UChar prevCh = 0;
int32_t count = 0;
int32_t fieldNum = 0;
+ UDisplayContext capitalizationContext = getContext(UDISPCTX_TYPE_CAPITALIZATION, status);
// loop through the pattern string character by character
for (int32_t i = 0; i < fPattern.length() && U_SUCCESS(status); ++i) {
@@ -884,7 +908,7 @@ SimpleDateFormat::_format(Calendar& cal, UnicodeString& appendTo,
// Use subFormat() to format a repeated pattern character
// when a different pattern or non-pattern character is seen
if (ch != prevCh && count > 0) {
- subFormat(appendTo, prevCh, count, fCapitalizationContext, fieldNum++, handler, *workCal, status);
+ subFormat(appendTo, prevCh, count, capitalizationContext, fieldNum++, handler, *workCal, status);
count = 0;
}
if (ch == QUOTE) {
@@ -912,7 +936,7 @@ SimpleDateFormat::_format(Calendar& cal, UnicodeString& appendTo,
// Format the last item in the pattern, if any
if (count > 0) {
- subFormat(appendTo, prevCh, count, fCapitalizationContext, fieldNum++, handler, *workCal, status);
+ subFormat(appendTo, prevCh, count, capitalizationContext, fieldNum++, handler, *workCal, status);
}
if (calClone != NULL) {
@@ -937,10 +961,10 @@ SimpleDateFormat::fgCalendarFieldToLevel[] =
/*wW*/ 20, 30,
/*dDEF*/ 30, 20, 30, 30,
/*ahHm*/ 40, 50, 50, 60,
- /*sS..*/ 70, 80,
+ /*sS*/ 70, 80,
/*z?Y*/ 0, 0, 10,
/*eug*/ 30, 10, 0,
- /*A*/ 40
+ /*A?.*/ 40, 0, 0
};
@@ -957,7 +981,7 @@ SimpleDateFormat::fgPatternCharToLevel[] = {
// a b c d e f g h i j k l m n o
-1, 40, -1, 30, 30, 30, -1, 0, 50, -1, -1, 50, -1, 60, -1, -1,
// p q r s t u v w x y z
- -1, 20, -1, 70, -1, 10, 0, 20, 0, 10, 0, -1, -1, -1, -1, -1
+ -1, 20, 10, 70, -1, 10, 0, 20, 0, 10, 0, -1, -1, -1, -1, -1
};
@@ -982,6 +1006,7 @@ SimpleDateFormat::fgPatternIndexToCalendarField[] =
/*U*/ UCAL_YEAR,
/*O*/ UCAL_ZONE_OFFSET,
/*Xx*/ UCAL_ZONE_OFFSET, UCAL_ZONE_OFFSET,
+ /*r*/ UCAL_EXTENDED_YEAR,
};
// Map index into pattern character string to DateFormat field number
@@ -1004,6 +1029,7 @@ SimpleDateFormat::fgPatternIndexToDateFormatField[] = {
/*U*/ UDAT_YEAR_NAME_FIELD,
/*O*/ UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD,
/*Xx*/ UDAT_TIMEZONE_ISO_FIELD, UDAT_TIMEZONE_ISO_LOCAL_FIELD,
+ /*r*/ UDAT_RELATED_YEAR_FIELD,
};
//----------------------------------------------------------------------
@@ -1059,16 +1085,22 @@ SimpleDateFormat::initNumberFormatters(const Locale &locale,UErrorCode &status)
}
umtx_unlock(&LOCK);
+ if (U_FAILURE(status)) {
+ return;
+ }
+
processOverrideString(locale,fDateOverride,kOvrStrDate,status);
processOverrideString(locale,fTimeOverride,kOvrStrTime,status);
-
}
void
SimpleDateFormat::processOverrideString(const Locale &locale, const UnicodeString &str, int8_t type, UErrorCode &status) {
- if (str.isBogus()) {
+ if (str.isBogus() || U_FAILURE(status)) {
return;
}
+
+ U_ASSERT(fNumberFormatters != NULL);
+
int32_t start = 0;
int32_t len;
UnicodeString nsName;
@@ -1150,7 +1182,6 @@ SimpleDateFormat::processOverrideString(const Locale &locale, const UnicodeStrin
// Now that we have an appropriate number formatter, fill in the appropriate spaces in the
// number formatters table.
-
if (ovrField.isBogus()) {
switch (type) {
case kOvrStrDate:
@@ -1223,7 +1254,7 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
}
UCalendarDateFields field = fgPatternIndexToCalendarField[patternCharIndex];
- int32_t value = cal.get(field, status);
+ int32_t value = (patternCharIndex != UDAT_RELATED_YEAR_FIELD)? cal.get(field, status): cal.getRelatedYear(status);
if (U_FAILURE(status)) {
return;
}
@@ -1592,8 +1623,8 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
break;
}
#if !UCONFIG_NO_BREAK_ITERATION
- if (fieldNum == 0) {
- // first field, check to see whether we need to titlecase it
+ // 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) {
UBool titlecase = FALSE;
switch (capitalizationContext) {
case UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE:
@@ -1611,7 +1642,7 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
}
if (titlecase) {
UnicodeString firstField(appendTo, beginOffset);
- firstField.toTitle(NULL, fLocale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
+ firstField.toTitle(fCapitalizationBrkIter, fLocale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
appendTo.replaceBetween(beginOffset, appendTo.length(), firstField);
}
}
@@ -1622,6 +1653,104 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
//----------------------------------------------------------------------
+void SimpleDateFormat::adoptNumberFormat(NumberFormat *formatToAdopt) {
+ formatToAdopt->setParseIntegerOnly(TRUE);
+ if (fNumberFormat && fNumberFormat != formatToAdopt){
+ delete fNumberFormat;
+ }
+ fNumberFormat = formatToAdopt;
+
+ if (fNumberFormatters) {
+ for (int32_t i = 0; i < UDAT_FIELD_COUNT; i++) {
+ if (fNumberFormatters[i] == formatToAdopt) {
+ fNumberFormatters[i] = NULL;
+ }
+ }
+ uprv_free(fNumberFormatters);
+ fNumberFormatters = NULL;
+ }
+
+ while (fOverrideList) {
+ NSOverride *cur = fOverrideList;
+ fOverrideList = cur->next;
+ if (cur->nf != formatToAdopt) { // only delete those not duplicate
+ delete cur->nf;
+ uprv_free(cur);
+ } else {
+ cur->nf = NULL;
+ uprv_free(cur);
+ }
+ }
+}
+
+void SimpleDateFormat::adoptNumberFormat(const UnicodeString& fields, NumberFormat *formatToAdopt, UErrorCode &status){
+ // if it has not been initialized yet, initialize
+ if (fNumberFormatters == NULL) {
+ fNumberFormatters = (NumberFormat**)uprv_malloc(UDAT_FIELD_COUNT * sizeof(NumberFormat*));
+ if (fNumberFormatters) {
+ for (int32_t i = 0; i < UDAT_FIELD_COUNT; i++) {
+ fNumberFormatters[i] = fNumberFormat;
+ }
+ } else {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ }
+
+ // See if the numbering format is in the override list, if not, then add it.
+ NSOverride *cur = fOverrideList;
+ UBool found = FALSE;
+ while (cur && !found) {
+ if ( cur->nf == formatToAdopt ) {
+ found = TRUE;
+ }
+ cur = cur->next;
+ }
+
+ if (!found) {
+ cur = (NSOverride *)uprv_malloc(sizeof(NSOverride));
+ if (cur) {
+ // no matter what the locale's default number format looked like, we want
+ // to modify it so that it doesn't use thousands separators, doesn't always
+ // show the decimal point, and recognizes integers only when parsing
+ formatToAdopt->setGroupingUsed(FALSE);
+ DecimalFormat* decfmt = dynamic_cast<DecimalFormat*>(formatToAdopt);
+ if (decfmt != NULL) {
+ decfmt->setDecimalSeparatorAlwaysShown(FALSE);
+ }
+ formatToAdopt->setParseIntegerOnly(TRUE);
+ formatToAdopt->setMinimumFractionDigits(0); // To prevent "Jan 1.00, 1997.00"
+
+ cur->nf = formatToAdopt;
+ cur->hash = -1; // set duplicate here (before we set it with NumberSystem Hash, here we cannot get nor use it)
+ cur->next = fOverrideList;
+ fOverrideList = cur;
+ } else {
+ status = U_MEMORY_ALLOCATION_ERROR;
+ return;
+ }
+ }
+
+ for (int i=0; i<fields.length(); i++) {
+ UChar field = fields.charAt(i);
+ // if the pattern character is unrecognized, signal an error and bail out
+ UDateFormatField patternCharIndex = DateFormatSymbols::getPatternCharIndex(field);
+ if (patternCharIndex == UDAT_FIELD_COUNT) {
+ status = U_INVALID_FORMAT_ERROR;
+ return;
+ }
+
+ // Set the number formatter in the table
+ fNumberFormatters[patternCharIndex] = formatToAdopt;
+ }
+}
+
+const NumberFormat *
+SimpleDateFormat::getNumberFormatForField(UChar field) const {
+ UDateFormatField index = DateFormatSymbols::getPatternCharIndex(field);
+ return getNumberFormatByIndex(index);
+}
+
NumberFormat *
SimpleDateFormat::getNumberFormatByIndex(UDateFormatField index) const {
if (fNumberFormatters != NULL) {
@@ -1694,14 +1823,17 @@ SimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition&
{
UErrorCode status = U_ZERO_ERROR;
int32_t pos = parsePos.getIndex();
+ if(parsePos.getIndex() < 0) {
+ parsePos.setErrorIndex(0);
+ return;
+ }
int32_t start = pos;
+
UBool ambiguousYear[] = { FALSE };
int32_t saveHebrewMonth = -1;
int32_t count = 0;
-
- // hack, reset tztype, cast away const
- ((SimpleDateFormat*)this)->tztype = UTZFMT_TIME_TYPE_UNKNOWN;
+ UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN;
// For parsing abutting numeric fields. 'abutPat' is the
// offset into 'pattern' of the first of 2 or more abutting
@@ -1795,7 +1927,7 @@ SimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition&
}
pos = subParse(text, pos, ch, count,
- TRUE, FALSE, ambiguousYear, saveHebrewMonth, *workCal, i, numericLeapMonthFormatter);
+ TRUE, FALSE, ambiguousYear, saveHebrewMonth, *workCal, i, numericLeapMonthFormatter, &tzTimeType);
// If the parse fails anywhere in the run, back up to the
// start of the run and retry.
@@ -1810,7 +1942,7 @@ SimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition&
// fields.
else if (ch != 0x6C) { // pattern char 'l' (SMALL LETTER L) just gets ignored
int32_t s = subParse(text, pos, ch, count,
- FALSE, TRUE, ambiguousYear, saveHebrewMonth, *workCal, i, numericLeapMonthFormatter);
+ FALSE, TRUE, ambiguousYear, saveHebrewMonth, *workCal, i, numericLeapMonthFormatter, &tzTimeType);
if (s == -pos-1) {
// era not present, in special cases allow this to continue
@@ -1847,7 +1979,7 @@ SimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition&
abutPat = -1; // End of any abutting fields
- if (! matchLiterals(fPattern, i, text, pos, getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status))) {
+ if (! matchLiterals(fPattern, i, text, pos, getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status), getBooleanAttribute(UDAT_PARSE_PARTIAL_MATCH, status), isLenient())) {
status = U_PARSE_ERROR;
goto ExitParse;
}
@@ -1890,7 +2022,7 @@ SimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition&
// when the two-digit year is equal to the start year, and thus might fall at the
// front or the back of the default century. This only works because we adjust
// the year correctly to start with in other cases -- see subParse().
- if (ambiguousYear[0] || tztype != UTZFMT_TIME_TYPE_UNKNOWN) // If this is true then the two-digit year == the default start year
+ if (ambiguousYear[0] || tzTimeType != UTZFMT_TIME_TYPE_UNKNOWN) // If this is true then the two-digit year == the default start year
{
// We need a copy of the fields, and we need to avoid triggering a call to
// complete(), which will recalculate the fields. Since we can't access
@@ -1913,7 +2045,7 @@ SimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition&
delete copy;
}
- if (tztype != UTZFMT_TIME_TYPE_UNKNOWN) {
+ if (tzTimeType != UTZFMT_TIME_TYPE_UNKNOWN) {
copy = cal.clone();
// Check for failed cloning.
if (copy == NULL) {
@@ -1939,7 +2071,7 @@ SimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition&
// matches the rule used by the parsed time zone.
int32_t raw, dst;
if (btz != NULL) {
- if (tztype == UTZFMT_TIME_TYPE_STANDARD) {
+ if (tzTimeType == UTZFMT_TIME_TYPE_STANDARD) {
btz->getOffsetFromLocal(localMillis,
BasicTimeZone::kStandard, BasicTimeZone::kStandard, raw, dst, status);
} else {
@@ -1954,7 +2086,7 @@ SimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition&
// Now, compare the results with parsed type, either standard or daylight saving time
int32_t resolvedSavings = dst;
- if (tztype == UTZFMT_TIME_TYPE_STANDARD) {
+ if (tzTimeType == UTZFMT_TIME_TYPE_STANDARD) {
if (dst != 0) {
// Override DST_OFFSET = 0 in the result calendar
resolvedSavings = 0;
@@ -2129,12 +2261,14 @@ UBool SimpleDateFormat::matchLiterals(const UnicodeString &pattern,
int32_t &patternOffset,
const UnicodeString &text,
int32_t &textOffset,
- UBool lenient)
+ UBool whitespaceLenient,
+ UBool partialMatchLenient,
+ UBool oldLeniency)
{
UBool inQuote = FALSE;
- UnicodeString literal;
+ UnicodeString literal;
int32_t i = patternOffset;
-
+
// scan pattern looking for contiguous literal characters
for ( ; i < pattern.length(); i += 1) {
UChar ch = pattern.charAt(i);
@@ -2161,7 +2295,7 @@ UBool SimpleDateFormat::matchLiterals(const UnicodeString &pattern,
int32_t p;
int32_t t = textOffset;
- if (lenient) {
+ if (whitespaceLenient) {
// trim leading, trailing whitespace from
// the literal text
literal.trim();
@@ -2196,7 +2330,7 @@ UBool SimpleDateFormat::matchLiterals(const UnicodeString &pattern,
// TODO: should we require internal spaces
// in lenient mode? (There won't be any
// leading or trailing spaces)
- if (!lenient && t == tStart) {
+ if (!whitespaceLenient && t == tStart) {
// didn't find matching whitespace:
// an error in strict mode
return FALSE;
@@ -2208,11 +2342,10 @@ UBool SimpleDateFormat::matchLiterals(const UnicodeString &pattern,
break;
}
}
-
if (t >= text.length() || literal.charAt(p) != text.charAt(t)) {
// Ran out of text, or found a non-matching character:
// OK in lenient mode, an error in strict mode.
- if (lenient) {
+ if (whitespaceLenient) {
if (t == textOffset && text.charAt(t) == 0x2e &&
isAfterNonNumericField(pattern, patternOffset)) {
// Lenient mode and the literal input text begins with a "." and
@@ -2220,6 +2353,17 @@ UBool SimpleDateFormat::matchLiterals(const UnicodeString &pattern,
++t;
continue; // Do not update p.
}
+ // if it is actual whitespace and we're whitespace lenient it's OK
+
+ UChar wsc = text.charAt(t);
+ if(PatternProps::isWhiteSpace(wsc)) {
+ // Lenient mode and it's just whitespace we skip it
+ ++t;
+ continue; // Do not update p.
+ }
+ }
+ // hack around oldleniency being a bit of a catch-all bucket and we're just adding support specifically for paritial matches
+ if(partialMatchLenient && oldLeniency) {
break;
}
@@ -2401,16 +2545,10 @@ SimpleDateFormat::set2DigitYearStart(UDate d, UErrorCode& status)
/**
* Private member function that converts the parsed date strings into
* timeFields. Returns -start (for ParsePosition) if failed.
- * @param text the time text to be parsed.
- * @param start where to start parsing.
- * @param ch the pattern character for the date field text to be parsed.
- * @param count the count of a pattern character.
- * @return the new start position if matching succeeded; a negative number
- * indicating matching failure, otherwise.
*/
int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UChar ch, int32_t count,
UBool obeyCount, UBool allowNegative, UBool ambiguousYear[], int32_t& saveHebrewMonth, Calendar& cal,
- int32_t patLoc, MessageFormat * numericLeapMonthFormatter) const
+ int32_t patLoc, MessageFormat * numericLeapMonthFormatter, UTimeZoneFormatTimeType *tzTimeType) const
{
Formattable number;
int32_t value = 0;
@@ -2606,22 +2744,22 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
&& u_isdigit(text.charAt(start))
&& u_isdigit(text.charAt(start+1)))
{
- // only adjust year for patterns less than 3.
- if(count < 3) {
- // Assume for example that the defaultCenturyStart is 6/18/1903.
- // This means that two-digit years will be forced into the range
- // 6/18/1903 to 6/17/2003. As a result, years 00, 01, and 02
- // correspond to 2000, 2001, and 2002. Years 04, 05, etc. correspond
- // to 1904, 1905, etc. If the year is 03, then it is 2003 if the
- // other fields specify a date before 6/18, or 1903 if they specify a
- // date afterwards. As a result, 03 is an ambiguous year. All other
- // two-digit years are unambiguous.
- if(fHaveDefaultCentury) { // check if this formatter even has a pivot year
- int32_t ambiguousTwoDigitYear = fDefaultCenturyStartYear % 100;
- ambiguousYear[0] = (value == ambiguousTwoDigitYear);
- value += (fDefaultCenturyStartYear/100)*100 +
- (value < ambiguousTwoDigitYear ? 100 : 0);
- }
+ // only adjust year for patterns less than 3.
+ if(count < 3) {
+ // Assume for example that the defaultCenturyStart is 6/18/1903.
+ // This means that two-digit years will be forced into the range
+ // 6/18/1903 to 6/17/2003. As a result, years 00, 01, and 02
+ // correspond to 2000, 2001, and 2002. Years 04, 05, etc. correspond
+ // to 1904, 1905, etc. If the year is 03, then it is 2003 if the
+ // other fields specify a date before 6/18, or 1903 if they specify a
+ // date afterwards. As a result, 03 is an ambiguous year. All other
+ // two-digit years are unambiguous.
+ if(fHaveDefaultCentury) { // check if this formatter even has a pivot year
+ int32_t ambiguousTwoDigitYear = fDefaultCenturyStartYear % 100;
+ ambiguousYear[0] = (value == ambiguousTwoDigitYear);
+ value += (fDefaultCenturyStartYear/100)*100 +
+ (value < ambiguousTwoDigitYear ? 100 : 0);
+ }
}
}
cal.set(UCAL_YEAR, value);
@@ -2711,17 +2849,25 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
}
int32_t newStart = 0;
if (patternCharIndex==UDAT_MONTH_FIELD) {
- newStart = matchString(text, start, UCAL_MONTH, fSymbols->fMonths, fSymbols->fMonthsCount, wideMonthPat, cal); // try MMMM
- if (newStart > 0) {
- return newStart;
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
+ newStart = matchString(text, start, UCAL_MONTH, fSymbols->fMonths, fSymbols->fMonthsCount, wideMonthPat, cal); // try MMMM
+ if (newStart > 0) {
+ return newStart;
+ }
+ }
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
+ newStart = matchString(text, start, UCAL_MONTH, fSymbols->fShortMonths, fSymbols->fShortMonthsCount, shortMonthPat, cal); // try MMM
}
- newStart = matchString(text, start, UCAL_MONTH, fSymbols->fShortMonths, fSymbols->fShortMonthsCount, shortMonthPat, cal); // try MMM
} else {
- newStart = matchString(text, start, UCAL_MONTH, fSymbols->fStandaloneMonths, fSymbols->fStandaloneMonthsCount, wideMonthPat, cal); // try LLLL
- if (newStart > 0) {
- return newStart;
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
+ newStart = matchString(text, start, UCAL_MONTH, fSymbols->fStandaloneMonths, fSymbols->fStandaloneMonthsCount, wideMonthPat, cal); // try LLLL
+ if (newStart > 0) {
+ return newStart;
+ }
+ }
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
+ newStart = matchString(text, start, UCAL_MONTH, fSymbols->fStandaloneShortMonths, fSymbols->fStandaloneShortMonthsCount, shortMonthPat, cal); // try LLL
}
- newStart = matchString(text, start, UCAL_MONTH, fSymbols->fStandaloneShortMonths, fSymbols->fStandaloneShortMonthsCount, shortMonthPat, cal); // try LLL
}
if (newStart > 0 || !getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)) // currently we do not try to parse MMMMM/LLLLL: #8860
return newStart;
@@ -2773,22 +2919,30 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
// Want to be able to parse both short and long forms.
// Try count == 4 (EEEE) wide first:
int32_t newStart = 0;
- if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
- fSymbols->fWeekdays, fSymbols->fWeekdaysCount, NULL, cal)) > 0)
- return newStart;
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
+ if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
+ fSymbols->fWeekdays, fSymbols->fWeekdaysCount, NULL, cal)) > 0)
+ return newStart;
+ }
// EEEE wide failed, now try EEE abbreviated
- else if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
- fSymbols->fShortWeekdays, fSymbols->fShortWeekdaysCount, NULL, cal)) > 0)
- return newStart;
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
+ if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
+ fSymbols->fShortWeekdays, fSymbols->fShortWeekdaysCount, NULL, cal)) > 0)
+ return newStart;
+ }
// EEE abbreviated failed, now try EEEEEE short
- else if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
- fSymbols->fShorterWeekdays, fSymbols->fShorterWeekdaysCount, NULL, cal)) > 0)
- return newStart;
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 6) {
+ if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
+ fSymbols->fShorterWeekdays, fSymbols->fShorterWeekdaysCount, NULL, cal)) > 0)
+ return newStart;
+ }
// EEEEEE short failed, now try EEEEE narrow
- else if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
- fSymbols->fNarrowWeekdays, fSymbols->fNarrowWeekdaysCount, NULL, cal)) > 0)
- return newStart;
- else if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status) || patternCharIndex == UDAT_DAY_OF_WEEK_FIELD)
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 5) {
+ if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
+ fSymbols->fNarrowWeekdays, fSymbols->fNarrowWeekdaysCount, NULL, cal)) > 0)
+ return newStart;
+ }
+ if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status) || patternCharIndex == UDAT_DAY_OF_WEEK_FIELD)
return newStart;
// else we allowing parsing as number, below
}
@@ -2805,16 +2959,22 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
// Want to be able to parse both short and long forms.
// Try count == 4 (cccc) first:
int32_t newStart = 0;
- if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
+ if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
fSymbols->fStandaloneWeekdays, fSymbols->fStandaloneWeekdaysCount, NULL, cal)) > 0)
- return newStart;
- else if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
+ return newStart;
+ }
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
+ if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
fSymbols->fStandaloneShortWeekdays, fSymbols->fStandaloneShortWeekdaysCount, NULL, cal)) > 0)
- return newStart;
- else if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
+ return newStart;
+ }
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 6) {
+ if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK,
fSymbols->fStandaloneShorterWeekdays, fSymbols->fStandaloneShorterWeekdaysCount, NULL, cal)) > 0)
- return newStart;
- else if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
+ return newStart;
+ }
+ if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
return newStart;
// else we allowing parsing as number, below
}
@@ -2848,15 +3008,21 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
// Try count == 4 first:
int32_t newStart = 0;
- if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
+ if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
fSymbols->fQuarters, fSymbols->fQuartersCount, cal)) > 0)
- return newStart;
- else if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
+ return newStart;
+ }
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
+ if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
fSymbols->fShortQuarters, fSymbols->fShortQuartersCount, cal)) > 0)
- return newStart;
- else if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
+ return newStart;
+ }
+ if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
return newStart;
// else we allowing parsing as number, below
+ if(!getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status))
+ return -start;
}
break;
@@ -2874,25 +3040,29 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
// Try count == 4 first:
int32_t newStart = 0;
- if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 4) {
+ if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
fSymbols->fStandaloneQuarters, fSymbols->fStandaloneQuartersCount, cal)) > 0)
- return newStart;
- else if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
+ return newStart;
+ }
+ if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count == 3) {
+ if ((newStart = matchQuarterString(text, start, UCAL_MONTH,
fSymbols->fStandaloneShortQuarters, fSymbols->fStandaloneShortQuartersCount, cal)) > 0)
- return newStart;
- else if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
+ return newStart;
+ }
+ if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status))
return newStart;
// else we allowing parsing as number, below
+ if(!getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status))
+ return -start;
}
break;
case UDAT_TIMEZONE_FIELD: // 'z'
{
- UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN;
UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_SPECIFIC_SHORT : UTZFMT_STYLE_SPECIFIC_LONG;
- TimeZone *tz = tzFormat()->parse(style, text, pos, &tzTimeType);
+ TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType);
if (tz != NULL) {
- ((SimpleDateFormat*)this)->tztype = tzTimeType;
cal.adoptTimeZone(tz);
return pos.getIndex();
}
@@ -2900,12 +3070,10 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
break;
case UDAT_TIMEZONE_RFC_FIELD: // 'Z'
{
- UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN;
UTimeZoneFormatStyle style = (count < 4) ?
UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL : ((count == 5) ? UTZFMT_STYLE_ISO_EXTENDED_FULL: UTZFMT_STYLE_LOCALIZED_GMT);
- TimeZone *tz = tzFormat()->parse(style, text, pos, &tzTimeType);
+ TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType);
if (tz != NULL) {
- ((SimpleDateFormat*)this)->tztype = tzTimeType;
cal.adoptTimeZone(tz);
return pos.getIndex();
}
@@ -2913,11 +3081,9 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
}
case UDAT_TIMEZONE_GENERIC_FIELD: // 'v'
{
- UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN;
UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_GENERIC_SHORT : UTZFMT_STYLE_GENERIC_LONG;
- TimeZone *tz = tzFormat()->parse(style, text, pos, &tzTimeType);
+ TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType);
if (tz != NULL) {
- ((SimpleDateFormat*)this)->tztype = tzTimeType;
cal.adoptTimeZone(tz);
return pos.getIndex();
}
@@ -2925,7 +3091,6 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
}
case UDAT_TIMEZONE_SPECIAL_FIELD: // 'V'
{
- UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN;
UTimeZoneFormatStyle style;
switch (count) {
case 1:
@@ -2941,9 +3106,8 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
style = UTZFMT_STYLE_GENERIC_LOCATION;
break;
}
- TimeZone *tz = tzFormat()->parse(style, text, pos, &tzTimeType);
+ TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType);
if (tz != NULL) {
- ((SimpleDateFormat*)this)->tztype = tzTimeType;
cal.adoptTimeZone(tz);
return pos.getIndex();
}
@@ -2951,11 +3115,9 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
}
case UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD: // 'O'
{
- UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN;
UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_LOCALIZED_GMT_SHORT : UTZFMT_STYLE_LOCALIZED_GMT;
- TimeZone *tz = tzFormat()->parse(style, text, pos, &tzTimeType);
+ TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType);
if (tz != NULL) {
- ((SimpleDateFormat*)this)->tztype = tzTimeType;
cal.adoptTimeZone(tz);
return pos.getIndex();
}
@@ -2963,7 +3125,6 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
}
case UDAT_TIMEZONE_ISO_FIELD: // 'X'
{
- UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN;
UTimeZoneFormatStyle style;
switch (count) {
case 1:
@@ -2982,9 +3143,8 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
style = UTZFMT_STYLE_ISO_EXTENDED_FULL;
break;
}
- TimeZone *tz = tzFormat()->parse(style, text, pos, &tzTimeType);
+ TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType);
if (tz != NULL) {
- ((SimpleDateFormat*)this)->tztype = tzTimeType;
cal.adoptTimeZone(tz);
return pos.getIndex();
}
@@ -2992,7 +3152,6 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
}
case UDAT_TIMEZONE_ISO_LOCAL_FIELD: // 'x'
{
- UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN;
UTimeZoneFormatStyle style;
switch (count) {
case 1:
@@ -3011,9 +3170,8 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
style = UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL;
break;
}
- TimeZone *tz = tzFormat()->parse(style, text, pos, &tzTimeType);
+ TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType);
if (tz != NULL) {
- ((SimpleDateFormat*)this)->tztype = tzTimeType;
cal.adoptTimeZone(tz);
return pos.getIndex();
}
@@ -3088,6 +3246,9 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
case UDAT_STANDALONE_QUARTER_FIELD:
cal.set(UCAL_MONTH, (value - 1) * 3);
break;
+ case UDAT_RELATED_YEAR_FIELD:
+ cal.setRelatedYear(value);
+ break;
default:
cal.set(field, value);
break;
@@ -3297,30 +3458,25 @@ void SimpleDateFormat::adoptCalendar(Calendar* calendarToAdopt)
//----------------------------------------------------------------------
-void SimpleDateFormat::setContext(UDisplayContext value, UErrorCode& status)
-{
- if (U_FAILURE(status))
- return;
- if ( (UDisplayContextType)((uint32_t)value >> 8) == UDISPCTX_TYPE_CAPITALIZATION ) {
- fCapitalizationContext = value;
- } else {
- status = U_ILLEGAL_ARGUMENT_ERROR;
- }
-}
-
-
-//----------------------------------------------------------------------
-
-
-UDisplayContext SimpleDateFormat::getContext(UDisplayContextType type, UErrorCode& status) const
+// override the DateFormat implementation in order to
+// lazily initialize fCapitalizationBrkIter
+void
+SimpleDateFormat::setContext(UDisplayContext value, UErrorCode& status)
{
- if (U_FAILURE(status))
- return (UDisplayContext)0;
- if (type != UDISPCTX_TYPE_CAPITALIZATION) {
- status = U_ILLEGAL_ARGUMENT_ERROR;
- return (UDisplayContext)0;
+ DateFormat::setContext(value, status);
+#if !UCONFIG_NO_BREAK_ITERATION
+ if (U_SUCCESS(status)) {
+ if ( fCapitalizationBrkIter == NULL && (value==UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE ||
+ value==UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU || value==UDISPCTX_CAPITALIZATION_FOR_STANDALONE) ) {
+ UErrorCode status = U_ZERO_ERROR;
+ fCapitalizationBrkIter = BreakIterator::createSentenceInstance(fLocale, status);
+ if (U_FAILURE(status)) {
+ delete fCapitalizationBrkIter;
+ fCapitalizationBrkIter = NULL;
+ }
+ }
}
- return fCapitalizationContext;
+#endif
}
« no previous file with comments | « source/i18n/sharedpluralrules.h ('k') | source/i18n/stsearch.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698