| OLD | NEW |
| 1 /* | 1 /* |
| 2 ******************************************************************************* | 2 ******************************************************************************* |
| 3 * Copyright (C) 1997-2013, International Business Machines Corporation and * | 3 * Copyright (C) 1997-2014, International Business Machines Corporation and * |
| 4 * others. All Rights Reserved. * | 4 * others. All Rights Reserved. * |
| 5 ******************************************************************************* | 5 ******************************************************************************* |
| 6 * | 6 * |
| 7 * File SMPDTFMT.CPP | 7 * File SMPDTFMT.CPP |
| 8 * | 8 * |
| 9 * Modification History: | 9 * Modification History: |
| 10 * | 10 * |
| 11 * Date Name Description | 11 * Date Name Description |
| 12 * 02/19/97 aliu Converted from java. | 12 * 02/19/97 aliu Converted from java. |
| 13 * 03/31/97 aliu Modified extensively to work with 50 locales. | 13 * 03/31/97 aliu Modified extensively to work with 50 locales. |
| 14 * 04/01/97 aliu Added support for centuries. | 14 * 04/01/97 aliu Added support for centuries. |
| 15 * 07/09/97 helena Made ParsePosition into a class. | 15 * 07/09/97 helena Made ParsePosition into a class. |
| 16 * 07/21/98 stephen Added initializeDefaultCentury. | 16 * 07/21/98 stephen Added initializeDefaultCentury. |
| 17 * Removed getZoneIndex (added in DateFormatSymbols) | 17 * Removed getZoneIndex (added in DateFormatSymbols) |
| 18 * Removed subParseLong | 18 * Removed subParseLong |
| 19 * Removed chk | 19 * Removed chk |
| 20 * 02/22/99 stephen Removed character literals for EBCDIC safety | 20 * 02/22/99 stephen Removed character literals for EBCDIC safety |
| 21 * 10/14/99 aliu Updated 2-digit year parsing so that only "00" thru | 21 * 10/14/99 aliu Updated 2-digit year parsing so that only "00" thru |
| 22 * "99" are recognized. {j28 4182066} | 22 * "99" are recognized. {j28 4182066} |
| 23 * 11/15/99 weiv Added support for week of year/day of week format | 23 * 11/15/99 weiv Added support for week of year/day of week format |
| 24 ******************************************************************************** | 24 ******************************************************************************** |
| 25 */ | 25 */ |
| 26 | 26 |
| 27 #define ZID_KEY_MAX 128 | 27 #define ZID_KEY_MAX 128 |
| 28 | 28 |
| 29 #include "unicode/utypes.h" | 29 #include "unicode/utypes.h" |
| 30 | 30 |
| 31 #if !UCONFIG_NO_FORMATTING | 31 #if !UCONFIG_NO_FORMATTING |
| 32 | |
| 33 #include "unicode/smpdtfmt.h" | 32 #include "unicode/smpdtfmt.h" |
| 34 #include "unicode/dtfmtsym.h" | 33 #include "unicode/dtfmtsym.h" |
| 35 #include "unicode/ures.h" | 34 #include "unicode/ures.h" |
| 36 #include "unicode/msgfmt.h" | 35 #include "unicode/msgfmt.h" |
| 37 #include "unicode/calendar.h" | 36 #include "unicode/calendar.h" |
| 38 #include "unicode/gregocal.h" | 37 #include "unicode/gregocal.h" |
| 39 #include "unicode/timezone.h" | 38 #include "unicode/timezone.h" |
| 40 #include "unicode/decimfmt.h" | 39 #include "unicode/decimfmt.h" |
| 41 #include "unicode/dcfmtsym.h" | 40 #include "unicode/dcfmtsym.h" |
| 42 #include "unicode/uchar.h" | 41 #include "unicode/uchar.h" |
| 43 #include "unicode/uniset.h" | 42 #include "unicode/uniset.h" |
| 44 #include "unicode/ustring.h" | 43 #include "unicode/ustring.h" |
| 45 #include "unicode/basictz.h" | 44 #include "unicode/basictz.h" |
| 46 #include "unicode/simpletz.h" | 45 #include "unicode/simpletz.h" |
| 47 #include "unicode/rbtz.h" | 46 #include "unicode/rbtz.h" |
| 48 #include "unicode/tzfmt.h" | 47 #include "unicode/tzfmt.h" |
| 49 #include "unicode/utf16.h" | 48 #include "unicode/utf16.h" |
| 50 #include "unicode/vtzone.h" | 49 #include "unicode/vtzone.h" |
| 51 #include "unicode/udisplaycontext.h" | 50 #include "unicode/udisplaycontext.h" |
| 51 #include "unicode/brkiter.h" |
| 52 #include "olsontz.h" | 52 #include "olsontz.h" |
| 53 #include "patternprops.h" | 53 #include "patternprops.h" |
| 54 #include "fphdlimp.h" | 54 #include "fphdlimp.h" |
| 55 #include "gregoimp.h" | 55 #include "gregoimp.h" |
| 56 #include "hebrwcal.h" | 56 #include "hebrwcal.h" |
| 57 #include "cstring.h" | 57 #include "cstring.h" |
| 58 #include "uassert.h" | 58 #include "uassert.h" |
| 59 #include "cmemory.h" | 59 #include "cmemory.h" |
| 60 #include "umutex.h" | 60 #include "umutex.h" |
| 61 #include <float.h> | 61 #include <float.h> |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 118 UDAT_DAY_OF_WEEK_IN_MONTH_FIELD, | 118 UDAT_DAY_OF_WEEK_IN_MONTH_FIELD, |
| 119 UDAT_WEEK_OF_YEAR_FIELD, | 119 UDAT_WEEK_OF_YEAR_FIELD, |
| 120 UDAT_WEEK_OF_MONTH_FIELD, | 120 UDAT_WEEK_OF_MONTH_FIELD, |
| 121 UDAT_YEAR_WOY_FIELD, | 121 UDAT_YEAR_WOY_FIELD, |
| 122 UDAT_EXTENDED_YEAR_FIELD, | 122 UDAT_EXTENDED_YEAR_FIELD, |
| 123 UDAT_JULIAN_DAY_FIELD, | 123 UDAT_JULIAN_DAY_FIELD, |
| 124 UDAT_STANDALONE_DAY_FIELD, | 124 UDAT_STANDALONE_DAY_FIELD, |
| 125 UDAT_STANDALONE_MONTH_FIELD, | 125 UDAT_STANDALONE_MONTH_FIELD, |
| 126 UDAT_QUARTER_FIELD, | 126 UDAT_QUARTER_FIELD, |
| 127 UDAT_STANDALONE_QUARTER_FIELD, | 127 UDAT_STANDALONE_QUARTER_FIELD, |
| 128 UDAT_YEAR_NAME_FIELD }; | 128 UDAT_YEAR_NAME_FIELD, |
| 129 static const int8_t kDateFieldsCount = 15; | 129 UDAT_RELATED_YEAR_FIELD }; |
| 130 static const int8_t kDateFieldsCount = 16; |
| 130 | 131 |
| 131 static const UDateFormatField kTimeFields[] = { | 132 static const UDateFormatField kTimeFields[] = { |
| 132 UDAT_HOUR_OF_DAY1_FIELD, | 133 UDAT_HOUR_OF_DAY1_FIELD, |
| 133 UDAT_HOUR_OF_DAY0_FIELD, | 134 UDAT_HOUR_OF_DAY0_FIELD, |
| 134 UDAT_MINUTE_FIELD, | 135 UDAT_MINUTE_FIELD, |
| 135 UDAT_SECOND_FIELD, | 136 UDAT_SECOND_FIELD, |
| 136 UDAT_FRACTIONAL_SECOND_FIELD, | 137 UDAT_FRACTIONAL_SECOND_FIELD, |
| 137 UDAT_HOUR1_FIELD, | 138 UDAT_HOUR1_FIELD, |
| 138 UDAT_HOUR0_FIELD, | 139 UDAT_HOUR0_FIELD, |
| 139 UDAT_MILLISECONDS_IN_DAY_FIELD, | 140 UDAT_MILLISECONDS_IN_DAY_FIELD, |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 -1, // 'e' - UDAT_DOW_LOCAL_FIELD | 196 -1, // 'e' - UDAT_DOW_LOCAL_FIELD |
| 196 -1, // 'u' - UDAT_EXTENDED_YEAR_FIELD | 197 -1, // 'u' - UDAT_EXTENDED_YEAR_FIELD |
| 197 -1, // 'g' - UDAT_JULIAN_DAY_FIELD | 198 -1, // 'g' - UDAT_JULIAN_DAY_FIELD |
| 198 -1, // 'A' - UDAT_MILLISECONDS_IN_DAY_FIELD | 199 -1, // 'A' - UDAT_MILLISECONDS_IN_DAY_FIELD |
| 199 -1, // 'Z' - UDAT_TIMEZONE_RFC_FIELD | 200 -1, // 'Z' - UDAT_TIMEZONE_RFC_FIELD |
| 200 -1, // 'v' - UDAT_TIMEZONE_GENERIC_FIELD | 201 -1, // 'v' - UDAT_TIMEZONE_GENERIC_FIELD |
| 201 0, // 'c' - UDAT_STANDALONE_DAY_FIELD | 202 0, // 'c' - UDAT_STANDALONE_DAY_FIELD |
| 202 1, // 'L' - UDAT_STANDALONE_MONTH_FIELD | 203 1, // 'L' - UDAT_STANDALONE_MONTH_FIELD |
| 203 -1, // 'Q' - UDAT_QUARTER_FIELD (1-4?) | 204 -1, // 'Q' - UDAT_QUARTER_FIELD (1-4?) |
| 204 -1, // 'q' - UDAT_STANDALONE_QUARTER_FIELD | 205 -1, // 'q' - UDAT_STANDALONE_QUARTER_FIELD |
| 205 -1 // 'V' - UDAT_TIMEZONE_SPECIAL_FIELD | 206 -1, // 'V' - UDAT_TIMEZONE_SPECIAL_FIELD |
| 206 -1, // 'U' - UDAT_YEAR_NAME_FIELD | 207 -1, // 'U' - UDAT_YEAR_NAME_FIELD |
| 207 -1, // 'O' - UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD | 208 -1, // 'O' - UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD |
| 208 -1, // 'X' - UDAT_TIMEZONE_ISO_FIELD | 209 -1, // 'X' - UDAT_TIMEZONE_ISO_FIELD |
| 209 -1, // 'x' - UDAT_TIMEZONE_ISO_LOCAL_FIELD | 210 -1, // 'x' - UDAT_TIMEZONE_ISO_LOCAL_FIELD |
| 211 -1, // 'r' - UDAT_RELATED_YEAR_FIELD |
| 210 }; | 212 }; |
| 211 | 213 |
| 212 // When calendar uses hebr numbering (i.e. he@calendar=hebrew), | 214 // When calendar uses hebr numbering (i.e. he@calendar=hebrew), |
| 213 // offset the years within the current millenium down to 1-999 | 215 // offset the years within the current millenium down to 1-999 |
| 214 static const int32_t HEBREW_CAL_CUR_MILLENIUM_START_YEAR = 5000; | 216 static const int32_t HEBREW_CAL_CUR_MILLENIUM_START_YEAR = 5000; |
| 215 static const int32_t HEBREW_CAL_CUR_MILLENIUM_END_YEAR = 6000; | 217 static const int32_t HEBREW_CAL_CUR_MILLENIUM_END_YEAR = 6000; |
| 216 | 218 |
| 217 static UMutex LOCK = U_MUTEX_INITIALIZER; | 219 static UMutex LOCK = U_MUTEX_INITIALIZER; |
| 218 | 220 |
| 219 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleDateFormat) | 221 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(SimpleDateFormat) |
| 220 | 222 |
| 221 //---------------------------------------------------------------------- | 223 //---------------------------------------------------------------------- |
| 222 | 224 |
| 223 SimpleDateFormat::~SimpleDateFormat() | 225 SimpleDateFormat::~SimpleDateFormat() |
| 224 { | 226 { |
| 225 delete fSymbols; | 227 delete fSymbols; |
| 226 if (fNumberFormatters) { | 228 if (fNumberFormatters) { |
| 227 uprv_free(fNumberFormatters); | 229 uprv_free(fNumberFormatters); |
| 228 } | 230 } |
| 229 if (fTimeZoneFormat) { | 231 if (fTimeZoneFormat) { |
| 230 delete fTimeZoneFormat; | 232 delete fTimeZoneFormat; |
| 231 } | 233 } |
| 232 | 234 |
| 233 while (fOverrideList) { | 235 while (fOverrideList) { |
| 234 NSOverride *cur = fOverrideList; | 236 NSOverride *cur = fOverrideList; |
| 235 fOverrideList = cur->next; | 237 fOverrideList = cur->next; |
| 236 delete cur->nf; | 238 delete cur->nf; |
| 237 uprv_free(cur); | 239 uprv_free(cur); |
| 238 } | 240 } |
| 241 |
| 242 #if !UCONFIG_NO_BREAK_ITERATION |
| 243 delete fCapitalizationBrkIter; |
| 244 #endif |
| 239 } | 245 } |
| 240 | 246 |
| 241 //---------------------------------------------------------------------- | 247 //---------------------------------------------------------------------- |
| 242 | 248 |
| 243 SimpleDateFormat::SimpleDateFormat(UErrorCode& status) | 249 SimpleDateFormat::SimpleDateFormat(UErrorCode& status) |
| 244 : fLocale(Locale::getDefault()), | 250 : fLocale(Locale::getDefault()), |
| 245 fSymbols(NULL), | 251 fSymbols(NULL), |
| 246 fTimeZoneFormat(NULL), | 252 fTimeZoneFormat(NULL), |
| 247 fNumberFormatters(NULL), | 253 fNumberFormatters(NULL), |
| 248 fOverrideList(NULL), | 254 fOverrideList(NULL), |
| 249 fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE) | 255 fCapitalizationBrkIter(NULL) |
| 250 { | 256 { |
| 251 setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAtt
ribute(UDAT_PARSE_ALLOW_NUMERIC, true, status); | 257 initializeBooleanAttributes(); |
| 252 construct(kShort, (EStyle) (kShort + kDateOffset), fLocale, status); | 258 construct(kShort, (EStyle) (kShort + kDateOffset), fLocale, status); |
| 253 initializeDefaultCentury(); | 259 initializeDefaultCentury(); |
| 254 } | 260 } |
| 255 | 261 |
| 256 //---------------------------------------------------------------------- | 262 //---------------------------------------------------------------------- |
| 257 | 263 |
| 258 SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern, | 264 SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern, |
| 259 UErrorCode &status) | 265 UErrorCode &status) |
| 260 : fPattern(pattern), | 266 : fPattern(pattern), |
| 261 fLocale(Locale::getDefault()), | 267 fLocale(Locale::getDefault()), |
| 262 fSymbols(NULL), | 268 fSymbols(NULL), |
| 263 fTimeZoneFormat(NULL), | 269 fTimeZoneFormat(NULL), |
| 264 fNumberFormatters(NULL), | 270 fNumberFormatters(NULL), |
| 265 fOverrideList(NULL), | 271 fOverrideList(NULL), |
| 266 fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE) | 272 fCapitalizationBrkIter(NULL) |
| 267 { | 273 { |
| 268 fDateOverride.setToBogus(); | 274 fDateOverride.setToBogus(); |
| 269 fTimeOverride.setToBogus(); | 275 fTimeOverride.setToBogus(); |
| 270 setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAtt
ribute(UDAT_PARSE_ALLOW_NUMERIC, true, status); | 276 initializeBooleanAttributes(); |
| 271 initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status); | 277 initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status); |
| 272 initialize(fLocale, status); | 278 initialize(fLocale, status); |
| 273 initializeDefaultCentury(); | 279 initializeDefaultCentury(); |
| 274 | 280 |
| 275 } | 281 } |
| 276 //---------------------------------------------------------------------- | 282 //---------------------------------------------------------------------- |
| 277 | 283 |
| 278 SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern, | 284 SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern, |
| 279 const UnicodeString& override, | 285 const UnicodeString& override, |
| 280 UErrorCode &status) | 286 UErrorCode &status) |
| 281 : fPattern(pattern), | 287 : fPattern(pattern), |
| 282 fLocale(Locale::getDefault()), | 288 fLocale(Locale::getDefault()), |
| 283 fSymbols(NULL), | 289 fSymbols(NULL), |
| 284 fTimeZoneFormat(NULL), | 290 fTimeZoneFormat(NULL), |
| 285 fNumberFormatters(NULL), | 291 fNumberFormatters(NULL), |
| 286 fOverrideList(NULL), | 292 fOverrideList(NULL), |
| 287 fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE) | 293 fCapitalizationBrkIter(NULL) |
| 288 { | 294 { |
| 289 fDateOverride.setTo(override); | 295 fDateOverride.setTo(override); |
| 290 fTimeOverride.setToBogus(); | 296 fTimeOverride.setToBogus(); |
| 291 setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAtt
ribute(UDAT_PARSE_ALLOW_NUMERIC, true, status); | 297 initializeBooleanAttributes(); |
| 292 initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status); | 298 initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status); |
| 293 initialize(fLocale, status); | 299 initialize(fLocale, status); |
| 294 initializeDefaultCentury(); | 300 initializeDefaultCentury(); |
| 295 | 301 |
| 296 processOverrideString(fLocale,override,kOvrStrBoth,status); | 302 processOverrideString(fLocale,override,kOvrStrBoth,status); |
| 297 | 303 |
| 298 } | 304 } |
| 299 | 305 |
| 300 //---------------------------------------------------------------------- | 306 //---------------------------------------------------------------------- |
| 301 | 307 |
| 302 SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern, | 308 SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern, |
| 303 const Locale& locale, | 309 const Locale& locale, |
| 304 UErrorCode& status) | 310 UErrorCode& status) |
| 305 : fPattern(pattern), | 311 : fPattern(pattern), |
| 306 fLocale(locale), | 312 fLocale(locale), |
| 307 fTimeZoneFormat(NULL), | 313 fTimeZoneFormat(NULL), |
| 308 fNumberFormatters(NULL), | 314 fNumberFormatters(NULL), |
| 309 fOverrideList(NULL), | 315 fOverrideList(NULL), |
| 310 fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE) | 316 fCapitalizationBrkIter(NULL) |
| 311 { | 317 { |
| 312 | 318 |
| 313 fDateOverride.setToBogus(); | 319 fDateOverride.setToBogus(); |
| 314 fTimeOverride.setToBogus(); | 320 fTimeOverride.setToBogus(); |
| 315 setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAtt
ribute(UDAT_PARSE_ALLOW_NUMERIC, true, status); | 321 initializeBooleanAttributes(); |
| 316 | 322 |
| 317 initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status); | 323 initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status); |
| 318 initialize(fLocale, status); | 324 initialize(fLocale, status); |
| 319 initializeDefaultCentury(); | 325 initializeDefaultCentury(); |
| 320 } | 326 } |
| 321 | 327 |
| 322 //---------------------------------------------------------------------- | 328 //---------------------------------------------------------------------- |
| 323 | 329 |
| 324 SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern, | 330 SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern, |
| 325 const UnicodeString& override, | 331 const UnicodeString& override, |
| 326 const Locale& locale, | 332 const Locale& locale, |
| 327 UErrorCode& status) | 333 UErrorCode& status) |
| 328 : fPattern(pattern), | 334 : fPattern(pattern), |
| 329 fLocale(locale), | 335 fLocale(locale), |
| 330 fTimeZoneFormat(NULL), | 336 fTimeZoneFormat(NULL), |
| 331 fNumberFormatters(NULL), | 337 fNumberFormatters(NULL), |
| 332 fOverrideList(NULL), | 338 fOverrideList(NULL), |
| 333 fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE) | 339 fCapitalizationBrkIter(NULL) |
| 334 { | 340 { |
| 335 | 341 |
| 336 fDateOverride.setTo(override); | 342 fDateOverride.setTo(override); |
| 337 fTimeOverride.setToBogus(); | 343 fTimeOverride.setToBogus(); |
| 338 setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAtt
ribute(UDAT_PARSE_ALLOW_NUMERIC, true, status); | 344 initializeBooleanAttributes(); |
| 339 | 345 |
| 340 initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status); | 346 initializeSymbols(fLocale, initializeCalendar(NULL,fLocale,status), status); |
| 341 initialize(fLocale, status); | 347 initialize(fLocale, status); |
| 342 initializeDefaultCentury(); | 348 initializeDefaultCentury(); |
| 343 | 349 |
| 344 processOverrideString(locale,override,kOvrStrBoth,status); | 350 processOverrideString(locale,override,kOvrStrBoth,status); |
| 345 | 351 |
| 346 } | 352 } |
| 347 | 353 |
| 348 //---------------------------------------------------------------------- | 354 //---------------------------------------------------------------------- |
| 349 | 355 |
| 350 SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern, | 356 SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern, |
| 351 DateFormatSymbols* symbolsToAdopt, | 357 DateFormatSymbols* symbolsToAdopt, |
| 352 UErrorCode& status) | 358 UErrorCode& status) |
| 353 : fPattern(pattern), | 359 : fPattern(pattern), |
| 354 fLocale(Locale::getDefault()), | 360 fLocale(Locale::getDefault()), |
| 355 fSymbols(symbolsToAdopt), | 361 fSymbols(symbolsToAdopt), |
| 356 fTimeZoneFormat(NULL), | 362 fTimeZoneFormat(NULL), |
| 357 fNumberFormatters(NULL), | 363 fNumberFormatters(NULL), |
| 358 fOverrideList(NULL), | 364 fOverrideList(NULL), |
| 359 fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE) | 365 fCapitalizationBrkIter(NULL) |
| 360 { | 366 { |
| 361 | 367 |
| 362 fDateOverride.setToBogus(); | 368 fDateOverride.setToBogus(); |
| 363 fTimeOverride.setToBogus(); | 369 fTimeOverride.setToBogus(); |
| 364 setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAtt
ribute(UDAT_PARSE_ALLOW_NUMERIC, true, status); | 370 initializeBooleanAttributes(); |
| 365 | 371 |
| 366 initializeCalendar(NULL,fLocale,status); | 372 initializeCalendar(NULL,fLocale,status); |
| 367 initialize(fLocale, status); | 373 initialize(fLocale, status); |
| 368 initializeDefaultCentury(); | 374 initializeDefaultCentury(); |
| 369 } | 375 } |
| 370 | 376 |
| 371 //---------------------------------------------------------------------- | 377 //---------------------------------------------------------------------- |
| 372 | 378 |
| 373 SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern, | 379 SimpleDateFormat::SimpleDateFormat(const UnicodeString& pattern, |
| 374 const DateFormatSymbols& symbols, | 380 const DateFormatSymbols& symbols, |
| 375 UErrorCode& status) | 381 UErrorCode& status) |
| 376 : fPattern(pattern), | 382 : fPattern(pattern), |
| 377 fLocale(Locale::getDefault()), | 383 fLocale(Locale::getDefault()), |
| 378 fSymbols(new DateFormatSymbols(symbols)), | 384 fSymbols(new DateFormatSymbols(symbols)), |
| 379 fTimeZoneFormat(NULL), | 385 fTimeZoneFormat(NULL), |
| 380 fNumberFormatters(NULL), | 386 fNumberFormatters(NULL), |
| 381 fOverrideList(NULL), | 387 fOverrideList(NULL), |
| 382 fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE) | 388 fCapitalizationBrkIter(NULL) |
| 383 { | 389 { |
| 384 | 390 |
| 385 fDateOverride.setToBogus(); | 391 fDateOverride.setToBogus(); |
| 386 fTimeOverride.setToBogus(); | 392 fTimeOverride.setToBogus(); |
| 387 setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAtt
ribute(UDAT_PARSE_ALLOW_NUMERIC, true, status); | 393 initializeBooleanAttributes(); |
| 388 | 394 |
| 389 initializeCalendar(NULL, fLocale, status); | 395 initializeCalendar(NULL, fLocale, status); |
| 390 initialize(fLocale, status); | 396 initialize(fLocale, status); |
| 391 initializeDefaultCentury(); | 397 initializeDefaultCentury(); |
| 392 } | 398 } |
| 393 | 399 |
| 394 //---------------------------------------------------------------------- | 400 //---------------------------------------------------------------------- |
| 395 | 401 |
| 396 // Not for public consumption; used by DateFormat | 402 // Not for public consumption; used by DateFormat |
| 397 SimpleDateFormat::SimpleDateFormat(EStyle timeStyle, | 403 SimpleDateFormat::SimpleDateFormat(EStyle timeStyle, |
| 398 EStyle dateStyle, | 404 EStyle dateStyle, |
| 399 const Locale& locale, | 405 const Locale& locale, |
| 400 UErrorCode& status) | 406 UErrorCode& status) |
| 401 : fLocale(locale), | 407 : fLocale(locale), |
| 402 fSymbols(NULL), | 408 fSymbols(NULL), |
| 403 fTimeZoneFormat(NULL), | 409 fTimeZoneFormat(NULL), |
| 404 fNumberFormatters(NULL), | 410 fNumberFormatters(NULL), |
| 405 fOverrideList(NULL), | 411 fOverrideList(NULL), |
| 406 fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE) | 412 fCapitalizationBrkIter(NULL) |
| 407 { | 413 { |
| 408 setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAtt
ribute(UDAT_PARSE_ALLOW_NUMERIC, true, status); | 414 initializeBooleanAttributes(); |
| 409 construct(timeStyle, dateStyle, fLocale, status); | 415 construct(timeStyle, dateStyle, fLocale, status); |
| 410 if(U_SUCCESS(status)) { | 416 if(U_SUCCESS(status)) { |
| 411 initializeDefaultCentury(); | 417 initializeDefaultCentury(); |
| 412 } | 418 } |
| 413 } | 419 } |
| 414 | 420 |
| 415 //---------------------------------------------------------------------- | 421 //---------------------------------------------------------------------- |
| 416 | 422 |
| 417 /** | 423 /** |
| 418 * Not for public consumption; used by DateFormat. This constructor | 424 * Not for public consumption; used by DateFormat. This constructor |
| 419 * never fails. If the resource data is not available, it uses the | 425 * never fails. If the resource data is not available, it uses the |
| 420 * the last resort symbols. | 426 * the last resort symbols. |
| 421 */ | 427 */ |
| 422 SimpleDateFormat::SimpleDateFormat(const Locale& locale, | 428 SimpleDateFormat::SimpleDateFormat(const Locale& locale, |
| 423 UErrorCode& status) | 429 UErrorCode& status) |
| 424 : fPattern(gDefaultPattern), | 430 : fPattern(gDefaultPattern), |
| 425 fLocale(locale), | 431 fLocale(locale), |
| 426 fSymbols(NULL), | 432 fSymbols(NULL), |
| 427 fTimeZoneFormat(NULL), | 433 fTimeZoneFormat(NULL), |
| 428 fNumberFormatters(NULL), | 434 fNumberFormatters(NULL), |
| 429 fOverrideList(NULL), | 435 fOverrideList(NULL), |
| 430 fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE) | 436 fCapitalizationBrkIter(NULL) |
| 431 { | 437 { |
| 432 if (U_FAILURE(status)) return; | 438 if (U_FAILURE(status)) return; |
| 439 initializeBooleanAttributes(); |
| 433 initializeSymbols(fLocale, initializeCalendar(NULL, fLocale, status),status)
; | 440 initializeSymbols(fLocale, initializeCalendar(NULL, fLocale, status),status)
; |
| 434 if (U_FAILURE(status)) | 441 if (U_FAILURE(status)) |
| 435 { | 442 { |
| 436 status = U_ZERO_ERROR; | 443 status = U_ZERO_ERROR; |
| 437 delete fSymbols; | 444 delete fSymbols; |
| 438 // This constructor doesn't fail; it uses last resort data | 445 // This constructor doesn't fail; it uses last resort data |
| 439 fSymbols = new DateFormatSymbols(status); | 446 fSymbols = new DateFormatSymbols(status); |
| 440 /* test for NULL */ | 447 /* test for NULL */ |
| 441 if (fSymbols == 0) { | 448 if (fSymbols == 0) { |
| 442 status = U_MEMORY_ALLOCATION_ERROR; | 449 status = U_MEMORY_ALLOCATION_ERROR; |
| 443 return; | 450 return; |
| 444 } | 451 } |
| 445 } | 452 } |
| 446 | 453 |
| 447 fDateOverride.setToBogus(); | 454 fDateOverride.setToBogus(); |
| 448 fTimeOverride.setToBogus(); | 455 fTimeOverride.setToBogus(); |
| 449 setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAtt
ribute(UDAT_PARSE_ALLOW_NUMERIC, true, status); | |
| 450 | 456 |
| 451 initialize(fLocale, status); | 457 initialize(fLocale, status); |
| 452 if(U_SUCCESS(status)) { | 458 if(U_SUCCESS(status)) { |
| 453 initializeDefaultCentury(); | 459 initializeDefaultCentury(); |
| 454 } | 460 } |
| 455 } | 461 } |
| 456 | 462 |
| 457 //---------------------------------------------------------------------- | 463 //---------------------------------------------------------------------- |
| 458 | 464 |
| 459 SimpleDateFormat::SimpleDateFormat(const SimpleDateFormat& other) | 465 SimpleDateFormat::SimpleDateFormat(const SimpleDateFormat& other) |
| 460 : DateFormat(other), | 466 : DateFormat(other), |
| 461 fLocale(other.fLocale), | 467 fLocale(other.fLocale), |
| 462 fSymbols(NULL), | 468 fSymbols(NULL), |
| 463 fTimeZoneFormat(NULL), | 469 fTimeZoneFormat(NULL), |
| 464 fNumberFormatters(NULL), | 470 fNumberFormatters(NULL), |
| 465 fOverrideList(NULL), | 471 fOverrideList(NULL), |
| 466 fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE) | 472 fCapitalizationBrkIter(NULL) |
| 467 { | 473 { |
| 468 UErrorCode status = U_ZERO_ERROR; | 474 initializeBooleanAttributes(); |
| 469 setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status).setBooleanAtt
ribute(UDAT_PARSE_ALLOW_NUMERIC, true, status); | |
| 470 *this = other; | 475 *this = other; |
| 471 } | 476 } |
| 472 | 477 |
| 473 //---------------------------------------------------------------------- | 478 //---------------------------------------------------------------------- |
| 474 | 479 |
| 475 SimpleDateFormat& SimpleDateFormat::operator=(const SimpleDateFormat& other) | 480 SimpleDateFormat& SimpleDateFormat::operator=(const SimpleDateFormat& other) |
| 476 { | 481 { |
| 477 if (this == &other) { | 482 if (this == &other) { |
| 478 return *this; | 483 return *this; |
| 479 } | 484 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 491 | 496 |
| 492 fPattern = other.fPattern; | 497 fPattern = other.fPattern; |
| 493 | 498 |
| 494 // TimeZoneFormat in ICU4C only depends on a locale for now | 499 // TimeZoneFormat in ICU4C only depends on a locale for now |
| 495 if (fLocale != other.fLocale) { | 500 if (fLocale != other.fLocale) { |
| 496 delete fTimeZoneFormat; | 501 delete fTimeZoneFormat; |
| 497 fTimeZoneFormat = NULL; // forces lazy instantiation with the other loca
le | 502 fTimeZoneFormat = NULL; // forces lazy instantiation with the other loca
le |
| 498 fLocale = other.fLocale; | 503 fLocale = other.fLocale; |
| 499 } | 504 } |
| 500 | 505 |
| 501 fCapitalizationContext = other.fCapitalizationContext; | 506 #if !UCONFIG_NO_BREAK_ITERATION |
| 507 if (other.fCapitalizationBrkIter != NULL) { |
| 508 fCapitalizationBrkIter = (other.fCapitalizationBrkIter)->clone(); |
| 509 } |
| 510 #endif |
| 502 | 511 |
| 503 return *this; | 512 return *this; |
| 504 } | 513 } |
| 505 | 514 |
| 506 //---------------------------------------------------------------------- | 515 //---------------------------------------------------------------------- |
| 507 | 516 |
| 508 Format* | 517 Format* |
| 509 SimpleDateFormat::clone() const | 518 SimpleDateFormat::clone() const |
| 510 { | 519 { |
| 511 return new SimpleDateFormat(*this); | 520 return new SimpleDateFormat(*this); |
| 512 } | 521 } |
| 513 | 522 |
| 514 //---------------------------------------------------------------------- | 523 //---------------------------------------------------------------------- |
| 515 | 524 |
| 516 UBool | 525 UBool |
| 517 SimpleDateFormat::operator==(const Format& other) const | 526 SimpleDateFormat::operator==(const Format& other) const |
| 518 { | 527 { |
| 519 if (DateFormat::operator==(other)) { | 528 if (DateFormat::operator==(other)) { |
| 529 // The DateFormat::operator== check for fCapitalizationContext equality
above |
| 530 // is sufficient to check equality of all derived context-related data
. |
| 520 // DateFormat::operator== guarantees following cast is safe | 531 // DateFormat::operator== guarantees following cast is safe |
| 521 SimpleDateFormat* that = (SimpleDateFormat*)&other; | 532 SimpleDateFormat* that = (SimpleDateFormat*)&other; |
| 522 return (fPattern == that->fPattern && | 533 return (fPattern == that->fPattern && |
| 523 fSymbols != NULL && // Check for pathological object | 534 fSymbols != NULL && // Check for pathological object |
| 524 that->fSymbols != NULL && // Check for pathological object | 535 that->fSymbols != NULL && // Check for pathological object |
| 525 *fSymbols == *that->fSymbols && | 536 *fSymbols == *that->fSymbols && |
| 526 fHaveDefaultCentury == that->fHaveDefaultCentury && | 537 fHaveDefaultCentury == that->fHaveDefaultCentury && |
| 527 fDefaultCenturyStart == that->fDefaultCenturyStart && | 538 fDefaultCenturyStart == that->fDefaultCenturyStart); |
| 528 fCapitalizationContext == that->fCapitalizationContext); | |
| 529 } | 539 } |
| 530 return FALSE; | 540 return FALSE; |
| 531 } | 541 } |
| 532 | 542 |
| 533 //---------------------------------------------------------------------- | 543 //---------------------------------------------------------------------- |
| 534 | 544 |
| 535 void SimpleDateFormat::construct(EStyle timeStyle, | 545 void SimpleDateFormat::construct(EStyle timeStyle, |
| 536 EStyle dateStyle, | 546 EStyle dateStyle, |
| 537 const Locale& locale, | 547 const Locale& locale, |
| 538 UErrorCode& status) | 548 UErrorCode& status) |
| (...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 797 if(fHaveDefaultCentury) { | 807 if(fHaveDefaultCentury) { |
| 798 fDefaultCenturyStart = fCalendar->defaultCenturyStart(); | 808 fDefaultCenturyStart = fCalendar->defaultCenturyStart(); |
| 799 fDefaultCenturyStartYear = fCalendar->defaultCenturyStartYear(); | 809 fDefaultCenturyStartYear = fCalendar->defaultCenturyStartYear(); |
| 800 } else { | 810 } else { |
| 801 fDefaultCenturyStart = DBL_MIN; | 811 fDefaultCenturyStart = DBL_MIN; |
| 802 fDefaultCenturyStartYear = -1; | 812 fDefaultCenturyStartYear = -1; |
| 803 } | 813 } |
| 804 } | 814 } |
| 805 } | 815 } |
| 806 | 816 |
| 817 /* |
| 818 * Initialize the boolean attributes. Separate so we can call it from all constr
uctors. |
| 819 */ |
| 820 void SimpleDateFormat::initializeBooleanAttributes() |
| 821 { |
| 822 UErrorCode status = U_ZERO_ERROR; |
| 823 |
| 824 setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, true, status); |
| 825 setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, true, status); |
| 826 setBooleanAttribute(UDAT_PARSE_PARTIAL_MATCH, true, status); |
| 827 setBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, true, status); |
| 828 } |
| 829 |
| 807 /* Define one-century window into which to disambiguate dates using | 830 /* Define one-century window into which to disambiguate dates using |
| 808 * two-digit years. Make public in JDK 1.2. | 831 * two-digit years. Make public in JDK 1.2. |
| 809 */ | 832 */ |
| 810 void SimpleDateFormat::parseAmbiguousDatesAsAfter(UDate startDate, UErrorCode& s
tatus) | 833 void SimpleDateFormat::parseAmbiguousDatesAsAfter(UDate startDate, UErrorCode& s
tatus) |
| 811 { | 834 { |
| 812 if(U_FAILURE(status)) { | 835 if(U_FAILURE(status)) { |
| 813 return; | 836 return; |
| 814 } | 837 } |
| 815 if(!fCalendar) { | 838 if(!fCalendar) { |
| 816 status = U_ILLEGAL_ARGUMENT_ERROR; | 839 status = U_ILLEGAL_ARGUMENT_ERROR; |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 869 } else { | 892 } else { |
| 870 status = U_MEMORY_ALLOCATION_ERROR; | 893 status = U_MEMORY_ALLOCATION_ERROR; |
| 871 return appendTo; | 894 return appendTo; |
| 872 } | 895 } |
| 873 } | 896 } |
| 874 | 897 |
| 875 UBool inQuote = FALSE; | 898 UBool inQuote = FALSE; |
| 876 UChar prevCh = 0; | 899 UChar prevCh = 0; |
| 877 int32_t count = 0; | 900 int32_t count = 0; |
| 878 int32_t fieldNum = 0; | 901 int32_t fieldNum = 0; |
| 902 UDisplayContext capitalizationContext = getContext(UDISPCTX_TYPE_CAPITALIZAT
ION, status); |
| 879 | 903 |
| 880 // loop through the pattern string character by character | 904 // loop through the pattern string character by character |
| 881 for (int32_t i = 0; i < fPattern.length() && U_SUCCESS(status); ++i) { | 905 for (int32_t i = 0; i < fPattern.length() && U_SUCCESS(status); ++i) { |
| 882 UChar ch = fPattern[i]; | 906 UChar ch = fPattern[i]; |
| 883 | 907 |
| 884 // Use subFormat() to format a repeated pattern character | 908 // Use subFormat() to format a repeated pattern character |
| 885 // when a different pattern or non-pattern character is seen | 909 // when a different pattern or non-pattern character is seen |
| 886 if (ch != prevCh && count > 0) { | 910 if (ch != prevCh && count > 0) { |
| 887 subFormat(appendTo, prevCh, count, fCapitalizationContext, fieldNum+
+, handler, *workCal, status); | 911 subFormat(appendTo, prevCh, count, capitalizationContext, fieldNum++
, handler, *workCal, status); |
| 888 count = 0; | 912 count = 0; |
| 889 } | 913 } |
| 890 if (ch == QUOTE) { | 914 if (ch == QUOTE) { |
| 891 // Consecutive single quotes are a single quote literal, | 915 // Consecutive single quotes are a single quote literal, |
| 892 // either outside of quotes or between quotes | 916 // either outside of quotes or between quotes |
| 893 if ((i+1) < fPattern.length() && fPattern[i+1] == QUOTE) { | 917 if ((i+1) < fPattern.length() && fPattern[i+1] == QUOTE) { |
| 894 appendTo += (UChar)QUOTE; | 918 appendTo += (UChar)QUOTE; |
| 895 ++i; | 919 ++i; |
| 896 } else { | 920 } else { |
| 897 inQuote = ! inQuote; | 921 inQuote = ! inQuote; |
| 898 } | 922 } |
| 899 } | 923 } |
| 900 else if ( ! inQuote && ((ch >= 0x0061 /*'a'*/ && ch <= 0x007A /*'z'*/) | 924 else if ( ! inQuote && ((ch >= 0x0061 /*'a'*/ && ch <= 0x007A /*'z'*/) |
| 901 || (ch >= 0x0041 /*'A'*/ && ch <= 0x005A /*'Z'*/))) { | 925 || (ch >= 0x0041 /*'A'*/ && ch <= 0x005A /*'Z'*/))) { |
| 902 // ch is a date-time pattern character to be interpreted | 926 // ch is a date-time pattern character to be interpreted |
| 903 // by subFormat(); count the number of times it is repeated | 927 // by subFormat(); count the number of times it is repeated |
| 904 prevCh = ch; | 928 prevCh = ch; |
| 905 ++count; | 929 ++count; |
| 906 } | 930 } |
| 907 else { | 931 else { |
| 908 // Append quoted characters and unquoted non-pattern characters | 932 // Append quoted characters and unquoted non-pattern characters |
| 909 appendTo += ch; | 933 appendTo += ch; |
| 910 } | 934 } |
| 911 } | 935 } |
| 912 | 936 |
| 913 // Format the last item in the pattern, if any | 937 // Format the last item in the pattern, if any |
| 914 if (count > 0) { | 938 if (count > 0) { |
| 915 subFormat(appendTo, prevCh, count, fCapitalizationContext, fieldNum++, h
andler, *workCal, status); | 939 subFormat(appendTo, prevCh, count, capitalizationContext, fieldNum++, ha
ndler, *workCal, status); |
| 916 } | 940 } |
| 917 | 941 |
| 918 if (calClone != NULL) { | 942 if (calClone != NULL) { |
| 919 delete calClone; | 943 delete calClone; |
| 920 } | 944 } |
| 921 | 945 |
| 922 return appendTo; | 946 return appendTo; |
| 923 } | 947 } |
| 924 | 948 |
| 925 //---------------------------------------------------------------------- | 949 //---------------------------------------------------------------------- |
| 926 | 950 |
| 927 /* Map calendar field into calendar field level. | 951 /* Map calendar field into calendar field level. |
| 928 * the larger the level, the smaller the field unit. | 952 * the larger the level, the smaller the field unit. |
| 929 * For example, UCAL_ERA level is 0, UCAL_YEAR level is 10, | 953 * For example, UCAL_ERA level is 0, UCAL_YEAR level is 10, |
| 930 * UCAL_MONTH level is 20. | 954 * UCAL_MONTH level is 20. |
| 931 * NOTE: if new fields adds in, the table needs to update. | 955 * NOTE: if new fields adds in, the table needs to update. |
| 932 */ | 956 */ |
| 933 const int32_t | 957 const int32_t |
| 934 SimpleDateFormat::fgCalendarFieldToLevel[] = | 958 SimpleDateFormat::fgCalendarFieldToLevel[] = |
| 935 { | 959 { |
| 936 /*GyM*/ 0, 10, 20, | 960 /*GyM*/ 0, 10, 20, |
| 937 /*wW*/ 20, 30, | 961 /*wW*/ 20, 30, |
| 938 /*dDEF*/ 30, 20, 30, 30, | 962 /*dDEF*/ 30, 20, 30, 30, |
| 939 /*ahHm*/ 40, 50, 50, 60, | 963 /*ahHm*/ 40, 50, 50, 60, |
| 940 /*sS..*/ 70, 80, | 964 /*sS*/ 70, 80, |
| 941 /*z?Y*/ 0, 0, 10, | 965 /*z?Y*/ 0, 0, 10, |
| 942 /*eug*/ 30, 10, 0, | 966 /*eug*/ 30, 10, 0, |
| 943 /*A*/ 40 | 967 /*A?.*/ 40, 0, 0 |
| 944 }; | 968 }; |
| 945 | 969 |
| 946 | 970 |
| 947 /* Map calendar field LETTER into calendar field level. | 971 /* Map calendar field LETTER into calendar field level. |
| 948 * the larger the level, the smaller the field unit. | 972 * the larger the level, the smaller the field unit. |
| 949 * NOTE: if new fields adds in, the table needs to update. | 973 * NOTE: if new fields adds in, the table needs to update. |
| 950 */ | 974 */ |
| 951 const int32_t | 975 const int32_t |
| 952 SimpleDateFormat::fgPatternCharToLevel[] = { | 976 SimpleDateFormat::fgPatternCharToLevel[] = { |
| 953 // A B C D E F G H I J K L M N O | 977 // A B C D E F G H I J K L M N O |
| 954 -1, 40, -1, -1, 20, 30, 30, 0, 50, -1, -1, 50, 20, 20, -1, 0, | 978 -1, 40, -1, -1, 20, 30, 30, 0, 50, -1, -1, 50, 20, 20, -1, 0, |
| 955 // P Q R S T U V W X Y Z | 979 // P Q R S T U V W X Y Z |
| 956 -1, 20, -1, 80, -1, 10, 0, 30, 0, 10, 0, -1, -1, -1, -1, -1, | 980 -1, 20, -1, 80, -1, 10, 0, 30, 0, 10, 0, -1, -1, -1, -1, -1, |
| 957 // a b c d e f g h i j k l m n o | 981 // a b c d e f g h i j k l m n o |
| 958 -1, 40, -1, 30, 30, 30, -1, 0, 50, -1, -1, 50, -1, 60, -1, -1, | 982 -1, 40, -1, 30, 30, 30, -1, 0, 50, -1, -1, 50, -1, 60, -1, -1, |
| 959 // p q r s t u v w x y z | 983 // p q r s t u v w x y z |
| 960 -1, 20, -1, 70, -1, 10, 0, 20, 0, 10, 0, -1, -1, -1, -1, -1 | 984 -1, 20, 10, 70, -1, 10, 0, 20, 0, 10, 0, -1, -1, -1, -1, -1 |
| 961 }; | 985 }; |
| 962 | 986 |
| 963 | 987 |
| 964 // Map index into pattern character string to Calendar field number. | 988 // Map index into pattern character string to Calendar field number. |
| 965 const UCalendarDateFields | 989 const UCalendarDateFields |
| 966 SimpleDateFormat::fgPatternIndexToCalendarField[] = | 990 SimpleDateFormat::fgPatternIndexToCalendarField[] = |
| 967 { | 991 { |
| 968 /*GyM*/ UCAL_ERA, UCAL_YEAR, UCAL_MONTH, | 992 /*GyM*/ UCAL_ERA, UCAL_YEAR, UCAL_MONTH, |
| 969 /*dkH*/ UCAL_DATE, UCAL_HOUR_OF_DAY, UCAL_HOUR_OF_DAY, | 993 /*dkH*/ UCAL_DATE, UCAL_HOUR_OF_DAY, UCAL_HOUR_OF_DAY, |
| 970 /*msS*/ UCAL_MINUTE, UCAL_SECOND, UCAL_MILLISECOND, | 994 /*msS*/ UCAL_MINUTE, UCAL_SECOND, UCAL_MILLISECOND, |
| 971 /*EDF*/ UCAL_DAY_OF_WEEK, UCAL_DAY_OF_YEAR, UCAL_DAY_OF_WEEK_IN_MONTH, | 995 /*EDF*/ UCAL_DAY_OF_WEEK, UCAL_DAY_OF_YEAR, UCAL_DAY_OF_WEEK_IN_MONTH, |
| 972 /*wWa*/ UCAL_WEEK_OF_YEAR, UCAL_WEEK_OF_MONTH, UCAL_AM_PM, | 996 /*wWa*/ UCAL_WEEK_OF_YEAR, UCAL_WEEK_OF_MONTH, UCAL_AM_PM, |
| 973 /*hKz*/ UCAL_HOUR, UCAL_HOUR, UCAL_ZONE_OFFSET, | 997 /*hKz*/ UCAL_HOUR, UCAL_HOUR, UCAL_ZONE_OFFSET, |
| 974 /*Yeu*/ UCAL_YEAR_WOY, UCAL_DOW_LOCAL, UCAL_EXTENDED_YEAR, | 998 /*Yeu*/ UCAL_YEAR_WOY, UCAL_DOW_LOCAL, UCAL_EXTENDED_YEAR, |
| 975 /*gAZ*/ UCAL_JULIAN_DAY, UCAL_MILLISECONDS_IN_DAY, UCAL_ZONE_OFFSET, | 999 /*gAZ*/ UCAL_JULIAN_DAY, UCAL_MILLISECONDS_IN_DAY, UCAL_ZONE_OFFSET, |
| 976 /*v*/ UCAL_ZONE_OFFSET, | 1000 /*v*/ UCAL_ZONE_OFFSET, |
| 977 /*c*/ UCAL_DOW_LOCAL, | 1001 /*c*/ UCAL_DOW_LOCAL, |
| 978 /*L*/ UCAL_MONTH, | 1002 /*L*/ UCAL_MONTH, |
| 979 /*Q*/ UCAL_MONTH, | 1003 /*Q*/ UCAL_MONTH, |
| 980 /*q*/ UCAL_MONTH, | 1004 /*q*/ UCAL_MONTH, |
| 981 /*V*/ UCAL_ZONE_OFFSET, | 1005 /*V*/ UCAL_ZONE_OFFSET, |
| 982 /*U*/ UCAL_YEAR, | 1006 /*U*/ UCAL_YEAR, |
| 983 /*O*/ UCAL_ZONE_OFFSET, | 1007 /*O*/ UCAL_ZONE_OFFSET, |
| 984 /*Xx*/ UCAL_ZONE_OFFSET, UCAL_ZONE_OFFSET, | 1008 /*Xx*/ UCAL_ZONE_OFFSET, UCAL_ZONE_OFFSET, |
| 1009 /*r*/ UCAL_EXTENDED_YEAR, |
| 985 }; | 1010 }; |
| 986 | 1011 |
| 987 // Map index into pattern character string to DateFormat field number | 1012 // Map index into pattern character string to DateFormat field number |
| 988 const UDateFormatField | 1013 const UDateFormatField |
| 989 SimpleDateFormat::fgPatternIndexToDateFormatField[] = { | 1014 SimpleDateFormat::fgPatternIndexToDateFormatField[] = { |
| 990 /*GyM*/ UDAT_ERA_FIELD, UDAT_YEAR_FIELD, UDAT_MONTH_FIELD, | 1015 /*GyM*/ UDAT_ERA_FIELD, UDAT_YEAR_FIELD, UDAT_MONTH_FIELD, |
| 991 /*dkH*/ UDAT_DATE_FIELD, UDAT_HOUR_OF_DAY1_FIELD, UDAT_HOUR_OF_DAY0_FIELD, | 1016 /*dkH*/ UDAT_DATE_FIELD, UDAT_HOUR_OF_DAY1_FIELD, UDAT_HOUR_OF_DAY0_FIELD, |
| 992 /*msS*/ UDAT_MINUTE_FIELD, UDAT_SECOND_FIELD, UDAT_FRACTIONAL_SECOND_FIELD, | 1017 /*msS*/ UDAT_MINUTE_FIELD, UDAT_SECOND_FIELD, UDAT_FRACTIONAL_SECOND_FIELD, |
| 993 /*EDF*/ UDAT_DAY_OF_WEEK_FIELD, UDAT_DAY_OF_YEAR_FIELD, UDAT_DAY_OF_WEEK_IN_
MONTH_FIELD, | 1018 /*EDF*/ UDAT_DAY_OF_WEEK_FIELD, UDAT_DAY_OF_YEAR_FIELD, UDAT_DAY_OF_WEEK_IN_
MONTH_FIELD, |
| 994 /*wWa*/ UDAT_WEEK_OF_YEAR_FIELD, UDAT_WEEK_OF_MONTH_FIELD, UDAT_AM_PM_FIELD, | 1019 /*wWa*/ UDAT_WEEK_OF_YEAR_FIELD, UDAT_WEEK_OF_MONTH_FIELD, UDAT_AM_PM_FIELD, |
| 995 /*hKz*/ UDAT_HOUR1_FIELD, UDAT_HOUR0_FIELD, UDAT_TIMEZONE_FIELD, | 1020 /*hKz*/ UDAT_HOUR1_FIELD, UDAT_HOUR0_FIELD, UDAT_TIMEZONE_FIELD, |
| 996 /*Yeu*/ UDAT_YEAR_WOY_FIELD, UDAT_DOW_LOCAL_FIELD, UDAT_EXTENDED_YEAR_FIELD, | 1021 /*Yeu*/ UDAT_YEAR_WOY_FIELD, UDAT_DOW_LOCAL_FIELD, UDAT_EXTENDED_YEAR_FIELD, |
| 997 /*gAZ*/ UDAT_JULIAN_DAY_FIELD, UDAT_MILLISECONDS_IN_DAY_FIELD, UDAT_TIMEZONE
_RFC_FIELD, | 1022 /*gAZ*/ UDAT_JULIAN_DAY_FIELD, UDAT_MILLISECONDS_IN_DAY_FIELD, UDAT_TIMEZONE
_RFC_FIELD, |
| 998 /*v*/ UDAT_TIMEZONE_GENERIC_FIELD, | 1023 /*v*/ UDAT_TIMEZONE_GENERIC_FIELD, |
| 999 /*c*/ UDAT_STANDALONE_DAY_FIELD, | 1024 /*c*/ UDAT_STANDALONE_DAY_FIELD, |
| 1000 /*L*/ UDAT_STANDALONE_MONTH_FIELD, | 1025 /*L*/ UDAT_STANDALONE_MONTH_FIELD, |
| 1001 /*Q*/ UDAT_QUARTER_FIELD, | 1026 /*Q*/ UDAT_QUARTER_FIELD, |
| 1002 /*q*/ UDAT_STANDALONE_QUARTER_FIELD, | 1027 /*q*/ UDAT_STANDALONE_QUARTER_FIELD, |
| 1003 /*V*/ UDAT_TIMEZONE_SPECIAL_FIELD, | 1028 /*V*/ UDAT_TIMEZONE_SPECIAL_FIELD, |
| 1004 /*U*/ UDAT_YEAR_NAME_FIELD, | 1029 /*U*/ UDAT_YEAR_NAME_FIELD, |
| 1005 /*O*/ UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD, | 1030 /*O*/ UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD, |
| 1006 /*Xx*/ UDAT_TIMEZONE_ISO_FIELD, UDAT_TIMEZONE_ISO_LOCAL_FIELD, | 1031 /*Xx*/ UDAT_TIMEZONE_ISO_FIELD, UDAT_TIMEZONE_ISO_LOCAL_FIELD, |
| 1032 /*r*/ UDAT_RELATED_YEAR_FIELD, |
| 1007 }; | 1033 }; |
| 1008 | 1034 |
| 1009 //---------------------------------------------------------------------- | 1035 //---------------------------------------------------------------------- |
| 1010 | 1036 |
| 1011 /** | 1037 /** |
| 1012 * Append symbols[value] to dst. Make sure the array index is not out | 1038 * Append symbols[value] to dst. Make sure the array index is not out |
| 1013 * of bounds. | 1039 * of bounds. |
| 1014 */ | 1040 */ |
| 1015 static inline void | 1041 static inline void |
| 1016 _appendSymbol(UnicodeString& dst, | 1042 _appendSymbol(UnicodeString& dst, |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1052 if (fNumberFormatters) { | 1078 if (fNumberFormatters) { |
| 1053 for (int32_t i = 0; i < UDAT_FIELD_COUNT; i++) { | 1079 for (int32_t i = 0; i < UDAT_FIELD_COUNT; i++) { |
| 1054 fNumberFormatters[i] = fNumberFormat; | 1080 fNumberFormatters[i] = fNumberFormat; |
| 1055 } | 1081 } |
| 1056 } else { | 1082 } else { |
| 1057 status = U_MEMORY_ALLOCATION_ERROR; | 1083 status = U_MEMORY_ALLOCATION_ERROR; |
| 1058 } | 1084 } |
| 1059 } | 1085 } |
| 1060 umtx_unlock(&LOCK); | 1086 umtx_unlock(&LOCK); |
| 1061 | 1087 |
| 1088 if (U_FAILURE(status)) { |
| 1089 return; |
| 1090 } |
| 1091 |
| 1062 processOverrideString(locale,fDateOverride,kOvrStrDate,status); | 1092 processOverrideString(locale,fDateOverride,kOvrStrDate,status); |
| 1063 processOverrideString(locale,fTimeOverride,kOvrStrTime,status); | 1093 processOverrideString(locale,fTimeOverride,kOvrStrTime,status); |
| 1064 | |
| 1065 } | 1094 } |
| 1066 | 1095 |
| 1067 void | 1096 void |
| 1068 SimpleDateFormat::processOverrideString(const Locale &locale, const UnicodeStrin
g &str, int8_t type, UErrorCode &status) { | 1097 SimpleDateFormat::processOverrideString(const Locale &locale, const UnicodeStrin
g &str, int8_t type, UErrorCode &status) { |
| 1069 if (str.isBogus()) { | 1098 if (str.isBogus() || U_FAILURE(status)) { |
| 1070 return; | 1099 return; |
| 1071 } | 1100 } |
| 1101 |
| 1102 U_ASSERT(fNumberFormatters != NULL); |
| 1103 |
| 1072 int32_t start = 0; | 1104 int32_t start = 0; |
| 1073 int32_t len; | 1105 int32_t len; |
| 1074 UnicodeString nsName; | 1106 UnicodeString nsName; |
| 1075 UnicodeString ovrField; | 1107 UnicodeString ovrField; |
| 1076 UBool moreToProcess = TRUE; | 1108 UBool moreToProcess = TRUE; |
| 1077 | 1109 |
| 1078 while (moreToProcess) { | 1110 while (moreToProcess) { |
| 1079 int32_t delimiterPosition = str.indexOf((UChar)ULOC_KEYWORD_ITEM_SEPARAT
OR_UNICODE,start); | 1111 int32_t delimiterPosition = str.indexOf((UChar)ULOC_KEYWORD_ITEM_SEPARAT
OR_UNICODE,start); |
| 1080 if (delimiterPosition == -1) { | 1112 if (delimiterPosition == -1) { |
| 1081 moreToProcess = FALSE; | 1113 moreToProcess = FALSE; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1143 } | 1175 } |
| 1144 | 1176 |
| 1145 } else { | 1177 } else { |
| 1146 status = U_MEMORY_ALLOCATION_ERROR; | 1178 status = U_MEMORY_ALLOCATION_ERROR; |
| 1147 return; | 1179 return; |
| 1148 } | 1180 } |
| 1149 } | 1181 } |
| 1150 | 1182 |
| 1151 // Now that we have an appropriate number formatter, fill in the appropr
iate spaces in the | 1183 // Now that we have an appropriate number formatter, fill in the appropr
iate spaces in the |
| 1152 // number formatters table. | 1184 // number formatters table. |
| 1153 | |
| 1154 if (ovrField.isBogus()) { | 1185 if (ovrField.isBogus()) { |
| 1155 switch (type) { | 1186 switch (type) { |
| 1156 case kOvrStrDate: | 1187 case kOvrStrDate: |
| 1157 case kOvrStrBoth: { | 1188 case kOvrStrBoth: { |
| 1158 for ( int8_t i=0 ; i<kDateFieldsCount; i++ ) { | 1189 for ( int8_t i=0 ; i<kDateFieldsCount; i++ ) { |
| 1159 fNumberFormatters[kDateFields[i]] = nf; | 1190 fNumberFormatters[kDateFields[i]] = nf; |
| 1160 } | 1191 } |
| 1161 if (type==kOvrStrDate) { | 1192 if (type==kOvrStrDate) { |
| 1162 break; | 1193 break; |
| 1163 } | 1194 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1216 // if the pattern character is unrecognized, signal an error and dump out | 1247 // if the pattern character is unrecognized, signal an error and dump out |
| 1217 if (patternCharIndex == UDAT_FIELD_COUNT) | 1248 if (patternCharIndex == UDAT_FIELD_COUNT) |
| 1218 { | 1249 { |
| 1219 if (ch != 0x6C) { // pattern char 'l' (SMALL LETTER L) just gets ignored | 1250 if (ch != 0x6C) { // pattern char 'l' (SMALL LETTER L) just gets ignored |
| 1220 status = U_INVALID_FORMAT_ERROR; | 1251 status = U_INVALID_FORMAT_ERROR; |
| 1221 } | 1252 } |
| 1222 return; | 1253 return; |
| 1223 } | 1254 } |
| 1224 | 1255 |
| 1225 UCalendarDateFields field = fgPatternIndexToCalendarField[patternCharIndex]; | 1256 UCalendarDateFields field = fgPatternIndexToCalendarField[patternCharIndex]; |
| 1226 int32_t value = cal.get(field, status); | 1257 int32_t value = (patternCharIndex != UDAT_RELATED_YEAR_FIELD)? cal.get(field
, status): cal.getRelatedYear(status); |
| 1227 if (U_FAILURE(status)) { | 1258 if (U_FAILURE(status)) { |
| 1228 return; | 1259 return; |
| 1229 } | 1260 } |
| 1230 | 1261 |
| 1231 currentNumberFormat = getNumberFormatByIndex(patternCharIndex); | 1262 currentNumberFormat = getNumberFormatByIndex(patternCharIndex); |
| 1232 UnicodeString hebr("hebr", 4, US_INV); | 1263 UnicodeString hebr("hebr", 4, US_INV); |
| 1233 | 1264 |
| 1234 switch (patternCharIndex) { | 1265 switch (patternCharIndex) { |
| 1235 | 1266 |
| 1236 // for any "G" symbol, write out the appropriate era string | 1267 // for any "G" symbol, write out the appropriate era string |
| (...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1585 break; | 1616 break; |
| 1586 | 1617 |
| 1587 | 1618 |
| 1588 // all of the other pattern symbols can be formatted as simple numbers with | 1619 // all of the other pattern symbols can be formatted as simple numbers with |
| 1589 // appropriate zero padding | 1620 // appropriate zero padding |
| 1590 default: | 1621 default: |
| 1591 zeroPaddingNumber(currentNumberFormat,appendTo, value, count, maxIntCoun
t); | 1622 zeroPaddingNumber(currentNumberFormat,appendTo, value, count, maxIntCoun
t); |
| 1592 break; | 1623 break; |
| 1593 } | 1624 } |
| 1594 #if !UCONFIG_NO_BREAK_ITERATION | 1625 #if !UCONFIG_NO_BREAK_ITERATION |
| 1595 if (fieldNum == 0) { | 1626 // if first field, check to see whether we need to and are able to titlecase
it |
| 1596 // first field, check to see whether we need to titlecase it | 1627 if (fieldNum == 0 && u_islower(appendTo.char32At(beginOffset)) && fCapitaliz
ationBrkIter != NULL) { |
| 1597 UBool titlecase = FALSE; | 1628 UBool titlecase = FALSE; |
| 1598 switch (capitalizationContext) { | 1629 switch (capitalizationContext) { |
| 1599 case UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE: | 1630 case UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE: |
| 1600 titlecase = TRUE; | 1631 titlecase = TRUE; |
| 1601 break; | 1632 break; |
| 1602 case UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU: | 1633 case UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU: |
| 1603 titlecase = fSymbols->fCapitalization[capContextUsageType][0]; | 1634 titlecase = fSymbols->fCapitalization[capContextUsageType][0]; |
| 1604 break; | 1635 break; |
| 1605 case UDISPCTX_CAPITALIZATION_FOR_STANDALONE: | 1636 case UDISPCTX_CAPITALIZATION_FOR_STANDALONE: |
| 1606 titlecase = fSymbols->fCapitalization[capContextUsageType][1]; | 1637 titlecase = fSymbols->fCapitalization[capContextUsageType][1]; |
| 1607 break; | 1638 break; |
| 1608 default: | 1639 default: |
| 1609 // titlecase = FALSE; | 1640 // titlecase = FALSE; |
| 1610 break; | 1641 break; |
| 1611 } | 1642 } |
| 1612 if (titlecase) { | 1643 if (titlecase) { |
| 1613 UnicodeString firstField(appendTo, beginOffset); | 1644 UnicodeString firstField(appendTo, beginOffset); |
| 1614 firstField.toTitle(NULL, fLocale, U_TITLECASE_NO_LOWERCASE | U_TITLE
CASE_NO_BREAK_ADJUSTMENT); | 1645 firstField.toTitle(fCapitalizationBrkIter, fLocale, U_TITLECASE_NO_L
OWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT); |
| 1615 appendTo.replaceBetween(beginOffset, appendTo.length(), firstField); | 1646 appendTo.replaceBetween(beginOffset, appendTo.length(), firstField); |
| 1616 } | 1647 } |
| 1617 } | 1648 } |
| 1618 #endif | 1649 #endif |
| 1619 | 1650 |
| 1620 handler.addAttribute(fgPatternIndexToDateFormatField[patternCharIndex], begi
nOffset, appendTo.length()); | 1651 handler.addAttribute(fgPatternIndexToDateFormatField[patternCharIndex], begi
nOffset, appendTo.length()); |
| 1621 } | 1652 } |
| 1622 | 1653 |
| 1623 //---------------------------------------------------------------------- | 1654 //---------------------------------------------------------------------- |
| 1624 | 1655 |
| 1656 void SimpleDateFormat::adoptNumberFormat(NumberFormat *formatToAdopt) { |
| 1657 formatToAdopt->setParseIntegerOnly(TRUE); |
| 1658 if (fNumberFormat && fNumberFormat != formatToAdopt){ |
| 1659 delete fNumberFormat; |
| 1660 } |
| 1661 fNumberFormat = formatToAdopt; |
| 1662 |
| 1663 if (fNumberFormatters) { |
| 1664 for (int32_t i = 0; i < UDAT_FIELD_COUNT; i++) { |
| 1665 if (fNumberFormatters[i] == formatToAdopt) { |
| 1666 fNumberFormatters[i] = NULL; |
| 1667 } |
| 1668 } |
| 1669 uprv_free(fNumberFormatters); |
| 1670 fNumberFormatters = NULL; |
| 1671 } |
| 1672 |
| 1673 while (fOverrideList) { |
| 1674 NSOverride *cur = fOverrideList; |
| 1675 fOverrideList = cur->next; |
| 1676 if (cur->nf != formatToAdopt) { // only delete those not duplicate |
| 1677 delete cur->nf; |
| 1678 uprv_free(cur); |
| 1679 } else { |
| 1680 cur->nf = NULL; |
| 1681 uprv_free(cur); |
| 1682 } |
| 1683 } |
| 1684 } |
| 1685 |
| 1686 void SimpleDateFormat::adoptNumberFormat(const UnicodeString& fields, NumberForm
at *formatToAdopt, UErrorCode &status){ |
| 1687 // if it has not been initialized yet, initialize |
| 1688 if (fNumberFormatters == NULL) { |
| 1689 fNumberFormatters = (NumberFormat**)uprv_malloc(UDAT_FIELD_COUNT * sizeo
f(NumberFormat*)); |
| 1690 if (fNumberFormatters) { |
| 1691 for (int32_t i = 0; i < UDAT_FIELD_COUNT; i++) { |
| 1692 fNumberFormatters[i] = fNumberFormat; |
| 1693 } |
| 1694 } else { |
| 1695 status = U_MEMORY_ALLOCATION_ERROR; |
| 1696 return; |
| 1697 } |
| 1698 } |
| 1699 |
| 1700 // See if the numbering format is in the override list, if not, then add it. |
| 1701 NSOverride *cur = fOverrideList; |
| 1702 UBool found = FALSE; |
| 1703 while (cur && !found) { |
| 1704 if ( cur->nf == formatToAdopt ) { |
| 1705 found = TRUE; |
| 1706 } |
| 1707 cur = cur->next; |
| 1708 } |
| 1709 |
| 1710 if (!found) { |
| 1711 cur = (NSOverride *)uprv_malloc(sizeof(NSOverride)); |
| 1712 if (cur) { |
| 1713 // no matter what the locale's default number format looked like, we
want |
| 1714 // to modify it so that it doesn't use thousands separators, doesn't
always |
| 1715 // show the decimal point, and recognizes integers only when parsing |
| 1716 formatToAdopt->setGroupingUsed(FALSE); |
| 1717 DecimalFormat* decfmt = dynamic_cast<DecimalFormat*>(formatToAdopt); |
| 1718 if (decfmt != NULL) { |
| 1719 decfmt->setDecimalSeparatorAlwaysShown(FALSE); |
| 1720 } |
| 1721 formatToAdopt->setParseIntegerOnly(TRUE); |
| 1722 formatToAdopt->setMinimumFractionDigits(0); // To prevent "Jan 1.00,
1997.00" |
| 1723 |
| 1724 cur->nf = formatToAdopt; |
| 1725 cur->hash = -1; // set duplicate here (before we set it with NumberS
ystem Hash, here we cannot get nor use it) |
| 1726 cur->next = fOverrideList; |
| 1727 fOverrideList = cur; |
| 1728 } else { |
| 1729 status = U_MEMORY_ALLOCATION_ERROR; |
| 1730 return; |
| 1731 } |
| 1732 } |
| 1733 |
| 1734 for (int i=0; i<fields.length(); i++) { |
| 1735 UChar field = fields.charAt(i); |
| 1736 // if the pattern character is unrecognized, signal an error and bail ou
t |
| 1737 UDateFormatField patternCharIndex = DateFormatSymbols::getPatternCharInd
ex(field); |
| 1738 if (patternCharIndex == UDAT_FIELD_COUNT) { |
| 1739 status = U_INVALID_FORMAT_ERROR; |
| 1740 return; |
| 1741 } |
| 1742 |
| 1743 // Set the number formatter in the table |
| 1744 fNumberFormatters[patternCharIndex] = formatToAdopt; |
| 1745 } |
| 1746 } |
| 1747 |
| 1748 const NumberFormat * |
| 1749 SimpleDateFormat::getNumberFormatForField(UChar field) const { |
| 1750 UDateFormatField index = DateFormatSymbols::getPatternCharIndex(field); |
| 1751 return getNumberFormatByIndex(index); |
| 1752 } |
| 1753 |
| 1625 NumberFormat * | 1754 NumberFormat * |
| 1626 SimpleDateFormat::getNumberFormatByIndex(UDateFormatField index) const { | 1755 SimpleDateFormat::getNumberFormatByIndex(UDateFormatField index) const { |
| 1627 if (fNumberFormatters != NULL) { | 1756 if (fNumberFormatters != NULL) { |
| 1628 return fNumberFormatters[index]; | 1757 return fNumberFormatters[index]; |
| 1629 } else { | 1758 } else { |
| 1630 return fNumberFormat; | 1759 return fNumberFormat; |
| 1631 } | 1760 } |
| 1632 } | 1761 } |
| 1633 | 1762 |
| 1634 //---------------------------------------------------------------------- | 1763 //---------------------------------------------------------------------- |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1687 int32_t i = patternOffset; | 1816 int32_t i = patternOffset; |
| 1688 while (pattern.charAt(--i) == ch) {} | 1817 while (pattern.charAt(--i) == ch) {} |
| 1689 return !DateFormatSymbols::isNumericField(f, patternOffset - i); | 1818 return !DateFormatSymbols::isNumericField(f, patternOffset - i); |
| 1690 } | 1819 } |
| 1691 | 1820 |
| 1692 void | 1821 void |
| 1693 SimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition&
parsePos) const | 1822 SimpleDateFormat::parse(const UnicodeString& text, Calendar& cal, ParsePosition&
parsePos) const |
| 1694 { | 1823 { |
| 1695 UErrorCode status = U_ZERO_ERROR; | 1824 UErrorCode status = U_ZERO_ERROR; |
| 1696 int32_t pos = parsePos.getIndex(); | 1825 int32_t pos = parsePos.getIndex(); |
| 1826 if(parsePos.getIndex() < 0) { |
| 1827 parsePos.setErrorIndex(0); |
| 1828 return; |
| 1829 } |
| 1697 int32_t start = pos; | 1830 int32_t start = pos; |
| 1698 | 1831 |
| 1832 |
| 1699 UBool ambiguousYear[] = { FALSE }; | 1833 UBool ambiguousYear[] = { FALSE }; |
| 1700 int32_t saveHebrewMonth = -1; | 1834 int32_t saveHebrewMonth = -1; |
| 1701 int32_t count = 0; | 1835 int32_t count = 0; |
| 1702 | 1836 UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN; |
| 1703 // hack, reset tztype, cast away const | |
| 1704 ((SimpleDateFormat*)this)->tztype = UTZFMT_TIME_TYPE_UNKNOWN; | |
| 1705 | 1837 |
| 1706 // For parsing abutting numeric fields. 'abutPat' is the | 1838 // For parsing abutting numeric fields. 'abutPat' is the |
| 1707 // offset into 'pattern' of the first of 2 or more abutting | 1839 // offset into 'pattern' of the first of 2 or more abutting |
| 1708 // numeric fields. 'abutStart' is the offset into 'text' | 1840 // numeric fields. 'abutStart' is the offset into 'text' |
| 1709 // where parsing the fields begins. 'abutPass' starts off as 0 | 1841 // where parsing the fields begins. 'abutPass' starts off as 0 |
| 1710 // and increments each time we try to parse the fields. | 1842 // and increments each time we try to parse the fields. |
| 1711 int32_t abutPat = -1; // If >=0, we are in a run of abutting numeric fields | 1843 int32_t abutPat = -1; // If >=0, we are in a run of abutting numeric fields |
| 1712 int32_t abutStart = 0; | 1844 int32_t abutStart = 0; |
| 1713 int32_t abutPass = 0; | 1845 int32_t abutPass = 0; |
| 1714 UBool inQuote = FALSE; | 1846 UBool inQuote = FALSE; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1788 // abutting numeric fields has failed. | 1920 // abutting numeric fields has failed. |
| 1789 if (fieldPat == abutPat) { | 1921 if (fieldPat == abutPat) { |
| 1790 count -= abutPass++; | 1922 count -= abutPass++; |
| 1791 if (count == 0) { | 1923 if (count == 0) { |
| 1792 status = U_PARSE_ERROR; | 1924 status = U_PARSE_ERROR; |
| 1793 goto ExitParse; | 1925 goto ExitParse; |
| 1794 } | 1926 } |
| 1795 } | 1927 } |
| 1796 | 1928 |
| 1797 pos = subParse(text, pos, ch, count, | 1929 pos = subParse(text, pos, ch, count, |
| 1798 TRUE, FALSE, ambiguousYear, saveHebrewMonth, *wor
kCal, i, numericLeapMonthFormatter); | 1930 TRUE, FALSE, ambiguousYear, saveHebrewMonth, *wor
kCal, i, numericLeapMonthFormatter, &tzTimeType); |
| 1799 | 1931 |
| 1800 // If the parse fails anywhere in the run, back up to the | 1932 // If the parse fails anywhere in the run, back up to the |
| 1801 // start of the run and retry. | 1933 // start of the run and retry. |
| 1802 if (pos < 0) { | 1934 if (pos < 0) { |
| 1803 i = abutPat - 1; | 1935 i = abutPat - 1; |
| 1804 pos = abutStart; | 1936 pos = abutStart; |
| 1805 continue; | 1937 continue; |
| 1806 } | 1938 } |
| 1807 } | 1939 } |
| 1808 | 1940 |
| 1809 // Handle non-numeric fields and non-abutting numeric | 1941 // Handle non-numeric fields and non-abutting numeric |
| 1810 // fields. | 1942 // fields. |
| 1811 else if (ch != 0x6C) { // pattern char 'l' (SMALL LETTER L) just get
s ignored | 1943 else if (ch != 0x6C) { // pattern char 'l' (SMALL LETTER L) just get
s ignored |
| 1812 int32_t s = subParse(text, pos, ch, count, | 1944 int32_t s = subParse(text, pos, ch, count, |
| 1813 FALSE, TRUE, ambiguousYear, saveHebrewMonth, *wor
kCal, i, numericLeapMonthFormatter); | 1945 FALSE, TRUE, ambiguousYear, saveHebrewMonth, *wor
kCal, i, numericLeapMonthFormatter, &tzTimeType); |
| 1814 | 1946 |
| 1815 if (s == -pos-1) { | 1947 if (s == -pos-1) { |
| 1816 // era not present, in special cases allow this to continue | 1948 // era not present, in special cases allow this to continue |
| 1817 // from the position where the era was expected | 1949 // from the position where the era was expected |
| 1818 s = pos; | 1950 s = pos; |
| 1819 | 1951 |
| 1820 if (i+1 < fPattern.length()) { | 1952 if (i+1 < fPattern.length()) { |
| 1821 // move to next pattern character | 1953 // move to next pattern character |
| 1822 UChar ch = fPattern.charAt(i+1); | 1954 UChar ch = fPattern.charAt(i+1); |
| 1823 | 1955 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 1840 } | 1972 } |
| 1841 } | 1973 } |
| 1842 | 1974 |
| 1843 // Handle literal pattern characters. These are any | 1975 // Handle literal pattern characters. These are any |
| 1844 // quoted characters and non-alphabetic unquoted | 1976 // quoted characters and non-alphabetic unquoted |
| 1845 // characters. | 1977 // characters. |
| 1846 else { | 1978 else { |
| 1847 | 1979 |
| 1848 abutPat = -1; // End of any abutting fields | 1980 abutPat = -1; // End of any abutting fields |
| 1849 | 1981 |
| 1850 if (! matchLiterals(fPattern, i, text, pos, getBooleanAttribute(UDAT
_PARSE_ALLOW_WHITESPACE, status))) { | 1982 if (! matchLiterals(fPattern, i, text, pos, getBooleanAttribute(UDAT
_PARSE_ALLOW_WHITESPACE, status), getBooleanAttribute(UDAT_PARSE_PARTIAL_MATCH,
status), isLenient())) { |
| 1851 status = U_PARSE_ERROR; | 1983 status = U_PARSE_ERROR; |
| 1852 goto ExitParse; | 1984 goto ExitParse; |
| 1853 } | 1985 } |
| 1854 } | 1986 } |
| 1855 } | 1987 } |
| 1856 | 1988 |
| 1857 // Special hack for trailing "." after non-numeric field. | 1989 // Special hack for trailing "." after non-numeric field. |
| 1858 if (text.charAt(pos) == 0x2e && getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESP
ACE, status)) { | 1990 if (text.charAt(pos) == 0x2e && getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESP
ACE, status)) { |
| 1859 // only do if the last field is not numeric | 1991 // only do if the last field is not numeric |
| 1860 if (isAfterNonNumericField(fPattern, fPattern.length())) { | 1992 if (isAfterNonNumericField(fPattern, fPattern.length())) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 1883 parsedDate = calendar.getTime(); | 2015 parsedDate = calendar.getTime(); |
| 1884 } | 2016 } |
| 1885 */ | 2017 */ |
| 1886 // Because of the above condition, save off the fields in case we need to re
adjust. | 2018 // Because of the above condition, save off the fields in case we need to re
adjust. |
| 1887 // The procedure we use here is not particularly efficient, but there is no
other | 2019 // The procedure we use here is not particularly efficient, but there is no
other |
| 1888 // way to do this given the API restrictions present in Calendar. We minimi
ze | 2020 // way to do this given the API restrictions present in Calendar. We minimi
ze |
| 1889 // inefficiency by only performing this computation when it might apply, tha
t is, | 2021 // inefficiency by only performing this computation when it might apply, tha
t is, |
| 1890 // when the two-digit year is equal to the start year, and thus might fall a
t the | 2022 // when the two-digit year is equal to the start year, and thus might fall a
t the |
| 1891 // front or the back of the default century. This only works because we adj
ust | 2023 // front or the back of the default century. This only works because we adj
ust |
| 1892 // the year correctly to start with in other cases -- see subParse(). | 2024 // the year correctly to start with in other cases -- see subParse(). |
| 1893 if (ambiguousYear[0] || tztype != UTZFMT_TIME_TYPE_UNKNOWN) // If this is tr
ue then the two-digit year == the default start year | 2025 if (ambiguousYear[0] || tzTimeType != UTZFMT_TIME_TYPE_UNKNOWN) // If this i
s true then the two-digit year == the default start year |
| 1894 { | 2026 { |
| 1895 // We need a copy of the fields, and we need to avoid triggering a call
to | 2027 // We need a copy of the fields, and we need to avoid triggering a call
to |
| 1896 // complete(), which will recalculate the fields. Since we can't access | 2028 // complete(), which will recalculate the fields. Since we can't access |
| 1897 // the fields[] array in Calendar, we clone the entire object. This wil
l | 2029 // the fields[] array in Calendar, we clone the entire object. This wil
l |
| 1898 // stop working if Calendar.clone() is ever rewritten to call complete()
. | 2030 // stop working if Calendar.clone() is ever rewritten to call complete()
. |
| 1899 Calendar *copy; | 2031 Calendar *copy; |
| 1900 if (ambiguousYear[0]) { | 2032 if (ambiguousYear[0]) { |
| 1901 copy = cal.clone(); | 2033 copy = cal.clone(); |
| 1902 // Check for failed cloning. | 2034 // Check for failed cloning. |
| 1903 if (copy == NULL) { | 2035 if (copy == NULL) { |
| 1904 status = U_MEMORY_ALLOCATION_ERROR; | 2036 status = U_MEMORY_ALLOCATION_ERROR; |
| 1905 goto ExitParse; | 2037 goto ExitParse; |
| 1906 } | 2038 } |
| 1907 UDate parsedDate = copy->getTime(status); | 2039 UDate parsedDate = copy->getTime(status); |
| 1908 // {sfb} check internalGetDefaultCenturyStart | 2040 // {sfb} check internalGetDefaultCenturyStart |
| 1909 if (fHaveDefaultCentury && (parsedDate < fDefaultCenturyStart)) { | 2041 if (fHaveDefaultCentury && (parsedDate < fDefaultCenturyStart)) { |
| 1910 // We can't use add here because that does a complete() first. | 2042 // We can't use add here because that does a complete() first. |
| 1911 cal.set(UCAL_YEAR, fDefaultCenturyStartYear + 100); | 2043 cal.set(UCAL_YEAR, fDefaultCenturyStartYear + 100); |
| 1912 } | 2044 } |
| 1913 delete copy; | 2045 delete copy; |
| 1914 } | 2046 } |
| 1915 | 2047 |
| 1916 if (tztype != UTZFMT_TIME_TYPE_UNKNOWN) { | 2048 if (tzTimeType != UTZFMT_TIME_TYPE_UNKNOWN) { |
| 1917 copy = cal.clone(); | 2049 copy = cal.clone(); |
| 1918 // Check for failed cloning. | 2050 // Check for failed cloning. |
| 1919 if (copy == NULL) { | 2051 if (copy == NULL) { |
| 1920 status = U_MEMORY_ALLOCATION_ERROR; | 2052 status = U_MEMORY_ALLOCATION_ERROR; |
| 1921 goto ExitParse; | 2053 goto ExitParse; |
| 1922 } | 2054 } |
| 1923 const TimeZone & tz = cal.getTimeZone(); | 2055 const TimeZone & tz = cal.getTimeZone(); |
| 1924 BasicTimeZone *btz = NULL; | 2056 BasicTimeZone *btz = NULL; |
| 1925 | 2057 |
| 1926 if (dynamic_cast<const OlsonTimeZone *>(&tz) != NULL | 2058 if (dynamic_cast<const OlsonTimeZone *>(&tz) != NULL |
| 1927 || dynamic_cast<const SimpleTimeZone *>(&tz) != NULL | 2059 || dynamic_cast<const SimpleTimeZone *>(&tz) != NULL |
| 1928 || dynamic_cast<const RuleBasedTimeZone *>(&tz) != NULL | 2060 || dynamic_cast<const RuleBasedTimeZone *>(&tz) != NULL |
| 1929 || dynamic_cast<const VTimeZone *>(&tz) != NULL) { | 2061 || dynamic_cast<const VTimeZone *>(&tz) != NULL) { |
| 1930 btz = (BasicTimeZone*)&tz; | 2062 btz = (BasicTimeZone*)&tz; |
| 1931 } | 2063 } |
| 1932 | 2064 |
| 1933 // Get local millis | 2065 // Get local millis |
| 1934 copy->set(UCAL_ZONE_OFFSET, 0); | 2066 copy->set(UCAL_ZONE_OFFSET, 0); |
| 1935 copy->set(UCAL_DST_OFFSET, 0); | 2067 copy->set(UCAL_DST_OFFSET, 0); |
| 1936 UDate localMillis = copy->getTime(status); | 2068 UDate localMillis = copy->getTime(status); |
| 1937 | 2069 |
| 1938 // Make sure parsed time zone type (Standard or Daylight) | 2070 // Make sure parsed time zone type (Standard or Daylight) |
| 1939 // matches the rule used by the parsed time zone. | 2071 // matches the rule used by the parsed time zone. |
| 1940 int32_t raw, dst; | 2072 int32_t raw, dst; |
| 1941 if (btz != NULL) { | 2073 if (btz != NULL) { |
| 1942 if (tztype == UTZFMT_TIME_TYPE_STANDARD) { | 2074 if (tzTimeType == UTZFMT_TIME_TYPE_STANDARD) { |
| 1943 btz->getOffsetFromLocal(localMillis, | 2075 btz->getOffsetFromLocal(localMillis, |
| 1944 BasicTimeZone::kStandard, BasicTimeZone::kStandard, raw,
dst, status); | 2076 BasicTimeZone::kStandard, BasicTimeZone::kStandard, raw,
dst, status); |
| 1945 } else { | 2077 } else { |
| 1946 btz->getOffsetFromLocal(localMillis, | 2078 btz->getOffsetFromLocal(localMillis, |
| 1947 BasicTimeZone::kDaylight, BasicTimeZone::kDaylight, raw,
dst, status); | 2079 BasicTimeZone::kDaylight, BasicTimeZone::kDaylight, raw,
dst, status); |
| 1948 } | 2080 } |
| 1949 } else { | 2081 } else { |
| 1950 // No good way to resolve ambiguous time at transition, | 2082 // No good way to resolve ambiguous time at transition, |
| 1951 // but following code work in most case. | 2083 // but following code work in most case. |
| 1952 tz.getOffset(localMillis, TRUE, raw, dst, status); | 2084 tz.getOffset(localMillis, TRUE, raw, dst, status); |
| 1953 } | 2085 } |
| 1954 | 2086 |
| 1955 // Now, compare the results with parsed type, either standard or day
light saving time | 2087 // Now, compare the results with parsed type, either standard or day
light saving time |
| 1956 int32_t resolvedSavings = dst; | 2088 int32_t resolvedSavings = dst; |
| 1957 if (tztype == UTZFMT_TIME_TYPE_STANDARD) { | 2089 if (tzTimeType == UTZFMT_TIME_TYPE_STANDARD) { |
| 1958 if (dst != 0) { | 2090 if (dst != 0) { |
| 1959 // Override DST_OFFSET = 0 in the result calendar | 2091 // Override DST_OFFSET = 0 in the result calendar |
| 1960 resolvedSavings = 0; | 2092 resolvedSavings = 0; |
| 1961 } | 2093 } |
| 1962 } else { // tztype == TZTYPE_DST | 2094 } else { // tztype == TZTYPE_DST |
| 1963 if (dst == 0) { | 2095 if (dst == 0) { |
| 1964 if (btz != NULL) { | 2096 if (btz != NULL) { |
| 1965 UDate time = localMillis + raw; | 2097 UDate time = localMillis + raw; |
| 1966 // We use the nearest daylight saving time rule. | 2098 // We use the nearest daylight saving time rule. |
| 1967 TimeZoneTransition beforeTrs, afterTrs; | 2099 TimeZoneTransition beforeTrs, afterTrs; |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2122 } | 2254 } |
| 2123 | 2255 |
| 2124 return -start; | 2256 return -start; |
| 2125 } | 2257 } |
| 2126 | 2258 |
| 2127 //---------------------------------------------------------------------- | 2259 //---------------------------------------------------------------------- |
| 2128 UBool SimpleDateFormat::matchLiterals(const UnicodeString &pattern, | 2260 UBool SimpleDateFormat::matchLiterals(const UnicodeString &pattern, |
| 2129 int32_t &patternOffset, | 2261 int32_t &patternOffset, |
| 2130 const UnicodeString &text, | 2262 const UnicodeString &text, |
| 2131 int32_t &textOffset, | 2263 int32_t &textOffset, |
| 2132 UBool lenient) | 2264 UBool whitespaceLenient, |
| 2265 UBool partialMatchLenient, |
| 2266 UBool oldLeniency) |
| 2133 { | 2267 { |
| 2134 UBool inQuote = FALSE; | 2268 UBool inQuote = FALSE; |
| 2135 UnicodeString literal; | 2269 UnicodeString literal; |
| 2136 int32_t i = patternOffset; | 2270 int32_t i = patternOffset; |
| 2137 | 2271 » |
| 2138 // scan pattern looking for contiguous literal characters | 2272 // scan pattern looking for contiguous literal characters |
| 2139 for ( ; i < pattern.length(); i += 1) { | 2273 for ( ; i < pattern.length(); i += 1) { |
| 2140 UChar ch = pattern.charAt(i); | 2274 UChar ch = pattern.charAt(i); |
| 2141 | 2275 |
| 2142 if (!inQuote && ((ch >= 0x41 && ch <= 0x5A) || (ch >= 0x61 && ch <= 0x7A
))) { // unquoted [A-Za-z] | 2276 if (!inQuote && ((ch >= 0x41 && ch <= 0x5A) || (ch >= 0x61 && ch <= 0x7A
))) { // unquoted [A-Za-z] |
| 2143 break; | 2277 break; |
| 2144 } | 2278 } |
| 2145 | 2279 |
| 2146 if (ch == QUOTE) { | 2280 if (ch == QUOTE) { |
| 2147 // Match a quote literal ('') inside OR outside of quotes | 2281 // Match a quote literal ('') inside OR outside of quotes |
| 2148 if ((i + 1) < pattern.length() && pattern.charAt(i + 1) == QUOTE) { | 2282 if ((i + 1) < pattern.length() && pattern.charAt(i + 1) == QUOTE) { |
| 2149 i += 1; | 2283 i += 1; |
| 2150 } else { | 2284 } else { |
| 2151 inQuote = !inQuote; | 2285 inQuote = !inQuote; |
| 2152 continue; | 2286 continue; |
| 2153 } | 2287 } |
| 2154 } | 2288 } |
| 2155 | 2289 |
| 2156 literal += ch; | 2290 literal += ch; |
| 2157 } | 2291 } |
| 2158 | 2292 |
| 2159 // at this point, literal contains the literal text | 2293 // at this point, literal contains the literal text |
| 2160 // and i is the index of the next non-literal pattern character. | 2294 // and i is the index of the next non-literal pattern character. |
| 2161 int32_t p; | 2295 int32_t p; |
| 2162 int32_t t = textOffset; | 2296 int32_t t = textOffset; |
| 2163 | 2297 |
| 2164 if (lenient) { | 2298 if (whitespaceLenient) { |
| 2165 // trim leading, trailing whitespace from | 2299 // trim leading, trailing whitespace from |
| 2166 // the literal text | 2300 // the literal text |
| 2167 literal.trim(); | 2301 literal.trim(); |
| 2168 | 2302 |
| 2169 // ignore any leading whitespace in the text | 2303 // ignore any leading whitespace in the text |
| 2170 while (t < text.length() && u_isWhitespace(text.charAt(t))) { | 2304 while (t < text.length() && u_isWhitespace(text.charAt(t))) { |
| 2171 t += 1; | 2305 t += 1; |
| 2172 } | 2306 } |
| 2173 } | 2307 } |
| 2174 | 2308 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 2189 if (!u_isUWhiteSpace(tch) && !PatternProps::isWhiteSpace(tch)) { | 2323 if (!u_isUWhiteSpace(tch) && !PatternProps::isWhiteSpace(tch)) { |
| 2190 break; | 2324 break; |
| 2191 } | 2325 } |
| 2192 | 2326 |
| 2193 t += 1; | 2327 t += 1; |
| 2194 } | 2328 } |
| 2195 | 2329 |
| 2196 // TODO: should we require internal spaces | 2330 // TODO: should we require internal spaces |
| 2197 // in lenient mode? (There won't be any | 2331 // in lenient mode? (There won't be any |
| 2198 // leading or trailing spaces) | 2332 // leading or trailing spaces) |
| 2199 if (!lenient && t == tStart) { | 2333 if (!whitespaceLenient && t == tStart) { |
| 2200 // didn't find matching whitespace: | 2334 // didn't find matching whitespace: |
| 2201 // an error in strict mode | 2335 // an error in strict mode |
| 2202 return FALSE; | 2336 return FALSE; |
| 2203 } | 2337 } |
| 2204 | 2338 |
| 2205 // In strict mode, this run of whitespace | 2339 // In strict mode, this run of whitespace |
| 2206 // may have been at the end. | 2340 // may have been at the end. |
| 2207 if (p >= literal.length()) { | 2341 if (p >= literal.length()) { |
| 2208 break; | 2342 break; |
| 2209 } | 2343 } |
| 2210 } | 2344 } |
| 2211 | |
| 2212 if (t >= text.length() || literal.charAt(p) != text.charAt(t)) { | 2345 if (t >= text.length() || literal.charAt(p) != text.charAt(t)) { |
| 2213 // Ran out of text, or found a non-matching character: | 2346 // Ran out of text, or found a non-matching character: |
| 2214 // OK in lenient mode, an error in strict mode. | 2347 // OK in lenient mode, an error in strict mode. |
| 2215 if (lenient) { | 2348 if (whitespaceLenient) { |
| 2216 if (t == textOffset && text.charAt(t) == 0x2e && | 2349 if (t == textOffset && text.charAt(t) == 0x2e && |
| 2217 isAfterNonNumericField(pattern, patternOffset)) { | 2350 isAfterNonNumericField(pattern, patternOffset)) { |
| 2218 // Lenient mode and the literal input text begins with a "."
and | 2351 // Lenient mode and the literal input text begins with a "."
and |
| 2219 // we are after a non-numeric field: We skip the "." | 2352 // we are after a non-numeric field: We skip the "." |
| 2220 ++t; | 2353 ++t; |
| 2221 continue; // Do not update p. | 2354 continue; // Do not update p. |
| 2222 } | 2355 } |
| 2356 // if it is actual whitespace and we're whitespace lenient it's
OK |
| 2357 |
| 2358 UChar wsc = text.charAt(t); |
| 2359 if(PatternProps::isWhiteSpace(wsc)) { |
| 2360 // Lenient mode and it's just whitespace we skip it |
| 2361 ++t; |
| 2362 continue; // Do not update p. |
| 2363 } |
| 2364 } |
| 2365 // hack around oldleniency being a bit of a catch-all bucket and we'
re just adding support specifically for paritial matches |
| 2366 if(partialMatchLenient && oldLeniency) {
|
| 2223 break; | 2367 break; |
| 2224 } | 2368 } |
| 2225 | 2369 |
| 2226 return FALSE; | 2370 return FALSE; |
| 2227 } | 2371 } |
| 2228 ++p; | 2372 ++p; |
| 2229 ++t; | 2373 ++t; |
| 2230 } | 2374 } |
| 2231 | 2375 |
| 2232 // At this point if we're in strict mode we have a complete match. | 2376 // At this point if we're in strict mode we have a complete match. |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2394 | 2538 |
| 2395 void | 2539 void |
| 2396 SimpleDateFormat::set2DigitYearStart(UDate d, UErrorCode& status) | 2540 SimpleDateFormat::set2DigitYearStart(UDate d, UErrorCode& status) |
| 2397 { | 2541 { |
| 2398 parseAmbiguousDatesAsAfter(d, status); | 2542 parseAmbiguousDatesAsAfter(d, status); |
| 2399 } | 2543 } |
| 2400 | 2544 |
| 2401 /** | 2545 /** |
| 2402 * Private member function that converts the parsed date strings into | 2546 * Private member function that converts the parsed date strings into |
| 2403 * timeFields. Returns -start (for ParsePosition) if failed. | 2547 * timeFields. Returns -start (for ParsePosition) if failed. |
| 2404 * @param text the time text to be parsed. | |
| 2405 * @param start where to start parsing. | |
| 2406 * @param ch the pattern character for the date field text to be parsed. | |
| 2407 * @param count the count of a pattern character. | |
| 2408 * @return the new start position if matching succeeded; a negative number | |
| 2409 * indicating matching failure, otherwise. | |
| 2410 */ | 2548 */ |
| 2411 int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
har ch, int32_t count, | 2549 int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
har ch, int32_t count, |
| 2412 UBool obeyCount, UBool allowNegative, UBool ambiguous
Year[], int32_t& saveHebrewMonth, Calendar& cal, | 2550 UBool obeyCount, UBool allowNegative, UBool ambiguous
Year[], int32_t& saveHebrewMonth, Calendar& cal, |
| 2413 int32_t patLoc, MessageFormat * numericLeapMonthForma
tter) const | 2551 int32_t patLoc, MessageFormat * numericLeapMonthForma
tter, UTimeZoneFormatTimeType *tzTimeType) const |
| 2414 { | 2552 { |
| 2415 Formattable number; | 2553 Formattable number; |
| 2416 int32_t value = 0; | 2554 int32_t value = 0; |
| 2417 int32_t i; | 2555 int32_t i; |
| 2418 int32_t ps = 0; | 2556 int32_t ps = 0; |
| 2419 UErrorCode status = U_ZERO_ERROR; | 2557 UErrorCode status = U_ZERO_ERROR; |
| 2420 ParsePosition pos(0); | 2558 ParsePosition pos(0); |
| 2421 UDateFormatField patternCharIndex = DateFormatSymbols::getPatternCharIndex(c
h); | 2559 UDateFormatField patternCharIndex = DateFormatSymbols::getPatternCharIndex(c
h); |
| 2422 NumberFormat *currentNumberFormat; | 2560 NumberFormat *currentNumberFormat; |
| 2423 UnicodeString temp; | 2561 UnicodeString temp; |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2599 // two-digit year adjustments (e.g., from "01" to 2001). Otherwise | 2737 // two-digit year adjustments (e.g., from "01" to 2001). Otherwise |
| 2600 // we made adjustments to place the 2-digit year in the proper | 2738 // we made adjustments to place the 2-digit year in the proper |
| 2601 // century, for parsed strings from "00" to "99". Any other string | 2739 // century, for parsed strings from "00" to "99". Any other string |
| 2602 // is treated literally: "2250", "-1", "1", "002". | 2740 // is treated literally: "2250", "-1", "1", "002". |
| 2603 if (fDateOverride.compare(hebr)==0 && value < 1000) { | 2741 if (fDateOverride.compare(hebr)==0 && value < 1000) { |
| 2604 value += HEBREW_CAL_CUR_MILLENIUM_START_YEAR; | 2742 value += HEBREW_CAL_CUR_MILLENIUM_START_YEAR; |
| 2605 } else if ((pos.getIndex() - start) == 2 && !isChineseCalendar | 2743 } else if ((pos.getIndex() - start) == 2 && !isChineseCalendar |
| 2606 && u_isdigit(text.charAt(start)) | 2744 && u_isdigit(text.charAt(start)) |
| 2607 && u_isdigit(text.charAt(start+1))) | 2745 && u_isdigit(text.charAt(start+1))) |
| 2608 { | 2746 { |
| 2609 » // only adjust year for patterns less than 3. | 2747 // only adjust year for patterns less than 3. |
| 2610 » if(count < 3) { | 2748 if(count < 3) { |
| 2611 » » // Assume for example that the defaultCenturyStart is 6/
18/1903. | 2749 // Assume for example that the defaultCenturyStart is 6/18/1903. |
| 2612 » » // This means that two-digit years will be forced into t
he range | 2750 // This means that two-digit years will be forced into the range |
| 2613 » » // 6/18/1903 to 6/17/2003. As a result, years 00, 01, a
nd 02 | 2751 // 6/18/1903 to 6/17/2003. As a result, years 00, 01, and 02 |
| 2614 » » // correspond to 2000, 2001, and 2002. Years 04, 05, et
c. correspond | 2752 // correspond to 2000, 2001, and 2002. Years 04, 05, etc. corre
spond |
| 2615 » » // to 1904, 1905, etc. If the year is 03, then it is 20
03 if the | 2753 // to 1904, 1905, etc. If the year is 03, then it is 2003 if th
e |
| 2616 » » // other fields specify a date before 6/18, or 1903 if t
hey specify a | 2754 // other fields specify a date before 6/18, or 1903 if they spec
ify a |
| 2617 » » // date afterwards. As a result, 03 is an ambiguous yea
r. All other | 2755 // date afterwards. As a result, 03 is an ambiguous year. All
other |
| 2618 » » // two-digit years are unambiguous. | 2756 // two-digit years are unambiguous. |
| 2619 » » if(fHaveDefaultCentury) { // check if this formatter eve
n has a pivot year | 2757 if(fHaveDefaultCentury) { // check if this formatter even has a
pivot year |
| 2620 » » » int32_t ambiguousTwoDigitYear = fDefaultCenturyS
tartYear % 100; | 2758 int32_t ambiguousTwoDigitYear = fDefaultCenturyStartYear % 1
00; |
| 2621 » » » ambiguousYear[0] = (value == ambiguousTwoDigitYe
ar); | 2759 ambiguousYear[0] = (value == ambiguousTwoDigitYear); |
| 2622 » » » value += (fDefaultCenturyStartYear/100)*100 + | 2760 value += (fDefaultCenturyStartYear/100)*100 + |
| 2623 » » » » » (value < ambiguousTwoDigitYear ?
100 : 0); | 2761 (value < ambiguousTwoDigitYear ? 100 : 0); |
| 2624 » » } | 2762 } |
| 2625 } | 2763 } |
| 2626 } | 2764 } |
| 2627 cal.set(UCAL_YEAR, value); | 2765 cal.set(UCAL_YEAR, value); |
| 2628 | 2766 |
| 2629 // Delayed checking for adjustment of Hebrew month numbers in non-leap y
ears. | 2767 // Delayed checking for adjustment of Hebrew month numbers in non-leap y
ears. |
| 2630 if (saveHebrewMonth >= 0) { | 2768 if (saveHebrewMonth >= 0) { |
| 2631 HebrewCalendar *hc = (HebrewCalendar*)&cal; | 2769 HebrewCalendar *hc = (HebrewCalendar*)&cal; |
| 2632 if (!hc->isLeapYear(value) && saveHebrewMonth >= 6) { | 2770 if (!hc->isLeapYear(value) && saveHebrewMonth >= 6) { |
| 2633 cal.set(UCAL_MONTH,saveHebrewMonth); | 2771 cal.set(UCAL_MONTH,saveHebrewMonth); |
| 2634 } else { | 2772 } else { |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2704 if (patternCharIndex==UDAT_MONTH_FIELD) { | 2842 if (patternCharIndex==UDAT_MONTH_FIELD) { |
| 2705 wideMonthPat = &fSymbols->fLeapMonthPatterns[DateFormatSymbo
ls::kLeapMonthPatternFormatWide]; | 2843 wideMonthPat = &fSymbols->fLeapMonthPatterns[DateFormatSymbo
ls::kLeapMonthPatternFormatWide]; |
| 2706 shortMonthPat = &fSymbols->fLeapMonthPatterns[DateFormatSymb
ols::kLeapMonthPatternFormatAbbrev]; | 2844 shortMonthPat = &fSymbols->fLeapMonthPatterns[DateFormatSymb
ols::kLeapMonthPatternFormatAbbrev]; |
| 2707 } else { | 2845 } else { |
| 2708 wideMonthPat = &fSymbols->fLeapMonthPatterns[DateFormatSymbo
ls::kLeapMonthPatternStandaloneWide]; | 2846 wideMonthPat = &fSymbols->fLeapMonthPatterns[DateFormatSymbo
ls::kLeapMonthPatternStandaloneWide]; |
| 2709 shortMonthPat = &fSymbols->fLeapMonthPatterns[DateFormatSymb
ols::kLeapMonthPatternStandaloneAbbrev]; | 2847 shortMonthPat = &fSymbols->fLeapMonthPatterns[DateFormatSymb
ols::kLeapMonthPatternStandaloneAbbrev]; |
| 2710 } | 2848 } |
| 2711 } | 2849 } |
| 2712 int32_t newStart = 0; | 2850 int32_t newStart = 0; |
| 2713 if (patternCharIndex==UDAT_MONTH_FIELD) { | 2851 if (patternCharIndex==UDAT_MONTH_FIELD) { |
| 2714 newStart = matchString(text, start, UCAL_MONTH, fSymbols->fMonth
s, fSymbols->fMonthsCount, wideMonthPat, cal); // try MMMM | 2852 if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, s
tatus) || count == 4) { |
| 2715 if (newStart > 0) { | 2853 newStart = matchString(text, start, UCAL_MONTH, fSymbols->fM
onths, fSymbols->fMonthsCount, wideMonthPat, cal); // try MMMM |
| 2716 return newStart; | 2854 if (newStart > 0) { |
| 2855 return newStart; |
| 2856 } |
| 2717 } | 2857 } |
| 2718 newStart = matchString(text, start, UCAL_MONTH, fSymbols->fShort
Months, fSymbols->fShortMonthsCount, shortMonthPat, cal); // try MMM | 2858 if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, s
tatus) || count == 3) { |
| 2859 newStart = matchString(text, start, UCAL_MONTH, fSymbols->fS
hortMonths, fSymbols->fShortMonthsCount, shortMonthPat, cal); // try MMM |
| 2860 } |
| 2719 } else { | 2861 } else { |
| 2720 newStart = matchString(text, start, UCAL_MONTH, fSymbols->fStand
aloneMonths, fSymbols->fStandaloneMonthsCount, wideMonthPat, cal); // try LLLL | 2862 if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, s
tatus) || count == 4) { |
| 2721 if (newStart > 0) { | 2863 newStart = matchString(text, start, UCAL_MONTH, fSymbols->fS
tandaloneMonths, fSymbols->fStandaloneMonthsCount, wideMonthPat, cal); // try LL
LL |
| 2722 return newStart; | 2864 if (newStart > 0) { |
| 2865 return newStart; |
| 2866 } |
| 2723 } | 2867 } |
| 2724 newStart = matchString(text, start, UCAL_MONTH, fSymbols->fStand
aloneShortMonths, fSymbols->fStandaloneShortMonthsCount, shortMonthPat, cal); //
try LLL | 2868 if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, s
tatus) || count == 3) { |
| 2869 newStart = matchString(text, start, UCAL_MONTH, fSymbols->fS
tandaloneShortMonths, fSymbols->fStandaloneShortMonthsCount, shortMonthPat, cal)
; // try LLL |
| 2870 } |
| 2725 } | 2871 } |
| 2726 if (newStart > 0 || !getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, s
tatus)) // currently we do not try to parse MMMMM/LLLLL: #8860 | 2872 if (newStart > 0 || !getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, s
tatus)) // currently we do not try to parse MMMMM/LLLLL: #8860 |
| 2727 return newStart; | 2873 return newStart; |
| 2728 // else we allowing parsing as number, below | 2874 // else we allowing parsing as number, below |
| 2729 } | 2875 } |
| 2730 break; | 2876 break; |
| 2731 | 2877 |
| 2732 case UDAT_HOUR_OF_DAY1_FIELD: | 2878 case UDAT_HOUR_OF_DAY1_FIELD: |
| 2733 // [We computed 'value' above.] | 2879 // [We computed 'value' above.] |
| 2734 if (value == cal.getMaximum(UCAL_HOUR_OF_DAY) + 1) | 2880 if (value == cal.getMaximum(UCAL_HOUR_OF_DAY) + 1) |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2766 cal.set(UCAL_DOW_LOCAL, value); | 2912 cal.set(UCAL_DOW_LOCAL, value); |
| 2767 return pos.getIndex(); | 2913 return pos.getIndex(); |
| 2768 } | 2914 } |
| 2769 // else for eee-eeeee fall through to handling of EEE-EEEEE | 2915 // else for eee-eeeee fall through to handling of EEE-EEEEE |
| 2770 // fall through, do not break here | 2916 // fall through, do not break here |
| 2771 case UDAT_DAY_OF_WEEK_FIELD: | 2917 case UDAT_DAY_OF_WEEK_FIELD: |
| 2772 { | 2918 { |
| 2773 // Want to be able to parse both short and long forms. | 2919 // Want to be able to parse both short and long forms. |
| 2774 // Try count == 4 (EEEE) wide first: | 2920 // Try count == 4 (EEEE) wide first: |
| 2775 int32_t newStart = 0; | 2921 int32_t newStart = 0; |
| 2776 if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK, | 2922 if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, statu
s) || count == 4) { |
| 2777 fSymbols->fWeekdays, fSymbols->fWeekdaysCo
unt, NULL, cal)) > 0) | 2923 if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK, |
| 2778 return newStart; | 2924 fSymbols->fWeekdays, fSymbols->fWeekda
ysCount, NULL, cal)) > 0) |
| 2925 return newStart; |
| 2926 } |
| 2779 // EEEE wide failed, now try EEE abbreviated | 2927 // EEEE wide failed, now try EEE abbreviated |
| 2780 else if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK, | 2928 if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, statu
s) || count == 3) { |
| 2781 fSymbols->fShortWeekdays, fSymbols->fShortWee
kdaysCount, NULL, cal)) > 0) | 2929 if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK, |
| 2782 return newStart; | 2930 fSymbols->fShortWeekdays, fSymbols->fShor
tWeekdaysCount, NULL, cal)) > 0) |
| 2931 return newStart; |
| 2932 } |
| 2783 // EEE abbreviated failed, now try EEEEEE short | 2933 // EEE abbreviated failed, now try EEEEEE short |
| 2784 else if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK, | 2934 if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, statu
s) || count == 6) { |
| 2785 fSymbols->fShorterWeekdays, fSymbols->fShorte
rWeekdaysCount, NULL, cal)) > 0) | 2935 if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK, |
| 2786 return newStart; | 2936 fSymbols->fShorterWeekdays, fSymbols->fSh
orterWeekdaysCount, NULL, cal)) > 0) |
| 2937 return newStart; |
| 2938 } |
| 2787 // EEEEEE short failed, now try EEEEE narrow | 2939 // EEEEEE short failed, now try EEEEE narrow |
| 2788 else if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK, | 2940 if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, statu
s) || count == 5) { |
| 2789 fSymbols->fNarrowWeekdays, fSymbols->fNarrowW
eekdaysCount, NULL, cal)) > 0) | 2941 if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK, |
| 2790 return newStart; | 2942 fSymbols->fNarrowWeekdays, fSymbols->fNar
rowWeekdaysCount, NULL, cal)) > 0) |
| 2791 else if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status) || p
atternCharIndex == UDAT_DAY_OF_WEEK_FIELD) | 2943 return newStart; |
| 2944 } |
| 2945 if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status) || patter
nCharIndex == UDAT_DAY_OF_WEEK_FIELD) |
| 2792 return newStart; | 2946 return newStart; |
| 2793 // else we allowing parsing as number, below | 2947 // else we allowing parsing as number, below |
| 2794 } | 2948 } |
| 2795 break; | 2949 break; |
| 2796 | 2950 |
| 2797 case UDAT_STANDALONE_DAY_FIELD: | 2951 case UDAT_STANDALONE_DAY_FIELD: |
| 2798 { | 2952 { |
| 2799 if (gotNumber) // c or cc | 2953 if (gotNumber) // c or cc |
| 2800 { | 2954 { |
| 2801 // [We computed 'value' above.] | 2955 // [We computed 'value' above.] |
| 2802 cal.set(UCAL_DOW_LOCAL, value); | 2956 cal.set(UCAL_DOW_LOCAL, value); |
| 2803 return pos.getIndex(); | 2957 return pos.getIndex(); |
| 2804 } | 2958 } |
| 2805 // Want to be able to parse both short and long forms. | 2959 // Want to be able to parse both short and long forms. |
| 2806 // Try count == 4 (cccc) first: | 2960 // Try count == 4 (cccc) first: |
| 2807 int32_t newStart = 0; | 2961 int32_t newStart = 0; |
| 2808 if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK, | 2962 if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, statu
s) || count == 4) { |
| 2963 if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK, |
| 2809 fSymbols->fStandaloneWeekdays, fSymbols->f
StandaloneWeekdaysCount, NULL, cal)) > 0) | 2964 fSymbols->fStandaloneWeekdays, fSymbols->f
StandaloneWeekdaysCount, NULL, cal)) > 0) |
| 2810 return newStart; | 2965 return newStart; |
| 2811 else if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK, | 2966 } |
| 2967 if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, statu
s) || count == 3) { |
| 2968 if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK, |
| 2812 fSymbols->fStandaloneShortWeekdays, fS
ymbols->fStandaloneShortWeekdaysCount, NULL, cal)) > 0) | 2969 fSymbols->fStandaloneShortWeekdays, fS
ymbols->fStandaloneShortWeekdaysCount, NULL, cal)) > 0) |
| 2813 return newStart; | 2970 return newStart; |
| 2814 else if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK, | 2971 } |
| 2972 if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, statu
s) || count == 6) { |
| 2973 if ((newStart = matchString(text, start, UCAL_DAY_OF_WEEK, |
| 2815 fSymbols->fStandaloneShorterWeekdays,
fSymbols->fStandaloneShorterWeekdaysCount, NULL, cal)) > 0) | 2974 fSymbols->fStandaloneShorterWeekdays,
fSymbols->fStandaloneShorterWeekdaysCount, NULL, cal)) > 0) |
| 2816 return newStart; | 2975 return newStart; |
| 2817 else if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)) | 2976 } |
| 2977 if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)) |
| 2818 return newStart; | 2978 return newStart; |
| 2819 // else we allowing parsing as number, below | 2979 // else we allowing parsing as number, below |
| 2820 } | 2980 } |
| 2821 break; | 2981 break; |
| 2822 | 2982 |
| 2823 case UDAT_AM_PM_FIELD: | 2983 case UDAT_AM_PM_FIELD: |
| 2824 return matchString(text, start, UCAL_AM_PM, fSymbols->fAmPms, fSymbols->
fAmPmsCount, NULL, cal); | 2984 return matchString(text, start, UCAL_AM_PM, fSymbols->fAmPms, fSymbols->
fAmPmsCount, NULL, cal); |
| 2825 | 2985 |
| 2826 case UDAT_HOUR1_FIELD: | 2986 case UDAT_HOUR1_FIELD: |
| 2827 // [We computed 'value' above.] | 2987 // [We computed 'value' above.] |
| (...skipping 13 matching lines...) Expand all Loading... |
| 2841 // while pattern uses numeric style: Q or QQ. | 3001 // while pattern uses numeric style: Q or QQ. |
| 2842 // [We computed 'value' above.] | 3002 // [We computed 'value' above.] |
| 2843 cal.set(UCAL_MONTH, (value - 1) * 3); | 3003 cal.set(UCAL_MONTH, (value - 1) * 3); |
| 2844 return pos.getIndex(); | 3004 return pos.getIndex(); |
| 2845 } else { | 3005 } else { |
| 2846 // count >= 3 // i.e., QQQ or QQQQ | 3006 // count >= 3 // i.e., QQQ or QQQQ |
| 2847 // Want to be able to parse both short and long forms. | 3007 // Want to be able to parse both short and long forms. |
| 2848 // Try count == 4 first: | 3008 // Try count == 4 first: |
| 2849 int32_t newStart = 0; | 3009 int32_t newStart = 0; |
| 2850 | 3010 |
| 2851 if ((newStart = matchQuarterString(text, start, UCAL_MONTH, | 3011 if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, statu
s) || count == 4) { |
| 3012 if ((newStart = matchQuarterString(text, start, UCAL_MONTH, |
| 2852 fSymbols->fQuarters, fSymbols->fQuartersCo
unt, cal)) > 0) | 3013 fSymbols->fQuarters, fSymbols->fQuartersCo
unt, cal)) > 0) |
| 2853 return newStart; | 3014 return newStart; |
| 2854 else if ((newStart = matchQuarterString(text, start, UCAL_MONTH, | 3015 } |
| 3016 if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, statu
s) || count == 3) { |
| 3017 if ((newStart = matchQuarterString(text, start, UCAL_MONTH, |
| 2855 fSymbols->fShortQuarters, fSymbols->fS
hortQuartersCount, cal)) > 0) | 3018 fSymbols->fShortQuarters, fSymbols->fS
hortQuartersCount, cal)) > 0) |
| 2856 return newStart; | 3019 return newStart; |
| 2857 else if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)) | 3020 } |
| 3021 if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)) |
| 2858 return newStart; | 3022 return newStart; |
| 2859 // else we allowing parsing as number, below | 3023 // else we allowing parsing as number, below |
| 3024 if(!getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, stat
us)) |
| 3025 return -start; |
| 2860 } | 3026 } |
| 2861 break; | 3027 break; |
| 2862 | 3028 |
| 2863 case UDAT_STANDALONE_QUARTER_FIELD: | 3029 case UDAT_STANDALONE_QUARTER_FIELD: |
| 2864 if (gotNumber) // i.e., q or qq. | 3030 if (gotNumber) // i.e., q or qq. |
| 2865 { | 3031 { |
| 2866 // Don't want to parse the month if it is a string | 3032 // Don't want to parse the month if it is a string |
| 2867 // while pattern uses numeric style: q or q. | 3033 // while pattern uses numeric style: q or q. |
| 2868 // [We computed 'value' above.] | 3034 // [We computed 'value' above.] |
| 2869 cal.set(UCAL_MONTH, (value - 1) * 3); | 3035 cal.set(UCAL_MONTH, (value - 1) * 3); |
| 2870 return pos.getIndex(); | 3036 return pos.getIndex(); |
| 2871 } else { | 3037 } else { |
| 2872 // count >= 3 // i.e., qqq or qqqq | 3038 // count >= 3 // i.e., qqq or qqqq |
| 2873 // Want to be able to parse both short and long forms. | 3039 // Want to be able to parse both short and long forms. |
| 2874 // Try count == 4 first: | 3040 // Try count == 4 first: |
| 2875 int32_t newStart = 0; | 3041 int32_t newStart = 0; |
| 2876 | 3042 |
| 2877 if ((newStart = matchQuarterString(text, start, UCAL_MONTH, | 3043 if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, statu
s) || count == 4) { |
| 3044 if ((newStart = matchQuarterString(text, start, UCAL_MONTH, |
| 2878 fSymbols->fStandaloneQuarters, fSymbols->f
StandaloneQuartersCount, cal)) > 0) | 3045 fSymbols->fStandaloneQuarters, fSymbols->f
StandaloneQuartersCount, cal)) > 0) |
| 2879 return newStart; | 3046 return newStart; |
| 2880 else if ((newStart = matchQuarterString(text, start, UCAL_MONTH, | 3047 } |
| 3048 if(getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, statu
s) || count == 3) { |
| 3049 if ((newStart = matchQuarterString(text, start, UCAL_MONTH, |
| 2881 fSymbols->fStandaloneShortQuarters, fS
ymbols->fStandaloneShortQuartersCount, cal)) > 0) | 3050 fSymbols->fStandaloneShortQuarters, fS
ymbols->fStandaloneShortQuartersCount, cal)) > 0) |
| 2882 return newStart; | 3051 return newStart; |
| 2883 else if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)) | 3052 } |
| 3053 if (!getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status)) |
| 2884 return newStart; | 3054 return newStart; |
| 2885 // else we allowing parsing as number, below | 3055 // else we allowing parsing as number, below |
| 3056 if(!getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, stat
us)) |
| 3057 return -start; |
| 2886 } | 3058 } |
| 2887 break; | 3059 break; |
| 2888 | 3060 |
| 2889 case UDAT_TIMEZONE_FIELD: // 'z' | 3061 case UDAT_TIMEZONE_FIELD: // 'z' |
| 2890 { | 3062 { |
| 2891 UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN; | |
| 2892 UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_SPECIFIC_SHO
RT : UTZFMT_STYLE_SPECIFIC_LONG; | 3063 UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_SPECIFIC_SHO
RT : UTZFMT_STYLE_SPECIFIC_LONG; |
| 2893 TimeZone *tz = tzFormat()->parse(style, text, pos, &tzTimeType); | 3064 TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType); |
| 2894 if (tz != NULL) { | 3065 if (tz != NULL) { |
| 2895 ((SimpleDateFormat*)this)->tztype = tzTimeType; | |
| 2896 cal.adoptTimeZone(tz); | 3066 cal.adoptTimeZone(tz); |
| 2897 return pos.getIndex(); | 3067 return pos.getIndex(); |
| 2898 } | 3068 } |
| 2899 } | 3069 } |
| 2900 break; | 3070 break; |
| 2901 case UDAT_TIMEZONE_RFC_FIELD: // 'Z' | 3071 case UDAT_TIMEZONE_RFC_FIELD: // 'Z' |
| 2902 { | 3072 { |
| 2903 UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN; | |
| 2904 UTimeZoneFormatStyle style = (count < 4) ? | 3073 UTimeZoneFormatStyle style = (count < 4) ? |
| 2905 UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL : ((count == 5) ? UTZFMT_STYLE
_ISO_EXTENDED_FULL: UTZFMT_STYLE_LOCALIZED_GMT); | 3074 UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL : ((count == 5) ? UTZFMT_STYLE
_ISO_EXTENDED_FULL: UTZFMT_STYLE_LOCALIZED_GMT); |
| 2906 TimeZone *tz = tzFormat()->parse(style, text, pos, &tzTimeType); | 3075 TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType); |
| 2907 if (tz != NULL) { | 3076 if (tz != NULL) { |
| 2908 ((SimpleDateFormat*)this)->tztype = tzTimeType; | |
| 2909 cal.adoptTimeZone(tz); | 3077 cal.adoptTimeZone(tz); |
| 2910 return pos.getIndex(); | 3078 return pos.getIndex(); |
| 2911 } | 3079 } |
| 2912 return -start; | 3080 return -start; |
| 2913 } | 3081 } |
| 2914 case UDAT_TIMEZONE_GENERIC_FIELD: // 'v' | 3082 case UDAT_TIMEZONE_GENERIC_FIELD: // 'v' |
| 2915 { | 3083 { |
| 2916 UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN; | |
| 2917 UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_GENERIC_SHOR
T : UTZFMT_STYLE_GENERIC_LONG; | 3084 UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_GENERIC_SHOR
T : UTZFMT_STYLE_GENERIC_LONG; |
| 2918 TimeZone *tz = tzFormat()->parse(style, text, pos, &tzTimeType); | 3085 TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType); |
| 2919 if (tz != NULL) { | 3086 if (tz != NULL) { |
| 2920 ((SimpleDateFormat*)this)->tztype = tzTimeType; | |
| 2921 cal.adoptTimeZone(tz); | 3087 cal.adoptTimeZone(tz); |
| 2922 return pos.getIndex(); | 3088 return pos.getIndex(); |
| 2923 } | 3089 } |
| 2924 return -start; | 3090 return -start; |
| 2925 } | 3091 } |
| 2926 case UDAT_TIMEZONE_SPECIAL_FIELD: // 'V' | 3092 case UDAT_TIMEZONE_SPECIAL_FIELD: // 'V' |
| 2927 { | 3093 { |
| 2928 UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN; | |
| 2929 UTimeZoneFormatStyle style; | 3094 UTimeZoneFormatStyle style; |
| 2930 switch (count) { | 3095 switch (count) { |
| 2931 case 1: | 3096 case 1: |
| 2932 style = UTZFMT_STYLE_ZONE_ID_SHORT; | 3097 style = UTZFMT_STYLE_ZONE_ID_SHORT; |
| 2933 break; | 3098 break; |
| 2934 case 2: | 3099 case 2: |
| 2935 style = UTZFMT_STYLE_ZONE_ID; | 3100 style = UTZFMT_STYLE_ZONE_ID; |
| 2936 break; | 3101 break; |
| 2937 case 3: | 3102 case 3: |
| 2938 style = UTZFMT_STYLE_EXEMPLAR_LOCATION; | 3103 style = UTZFMT_STYLE_EXEMPLAR_LOCATION; |
| 2939 break; | 3104 break; |
| 2940 default: | 3105 default: |
| 2941 style = UTZFMT_STYLE_GENERIC_LOCATION; | 3106 style = UTZFMT_STYLE_GENERIC_LOCATION; |
| 2942 break; | 3107 break; |
| 2943 } | 3108 } |
| 2944 TimeZone *tz = tzFormat()->parse(style, text, pos, &tzTimeType); | 3109 TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType); |
| 2945 if (tz != NULL) { | 3110 if (tz != NULL) { |
| 2946 ((SimpleDateFormat*)this)->tztype = tzTimeType; | |
| 2947 cal.adoptTimeZone(tz); | 3111 cal.adoptTimeZone(tz); |
| 2948 return pos.getIndex(); | 3112 return pos.getIndex(); |
| 2949 } | 3113 } |
| 2950 return -start; | 3114 return -start; |
| 2951 } | 3115 } |
| 2952 case UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD: // 'O' | 3116 case UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD: // 'O' |
| 2953 { | 3117 { |
| 2954 UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN; | |
| 2955 UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_LOCALIZED_GM
T_SHORT : UTZFMT_STYLE_LOCALIZED_GMT; | 3118 UTimeZoneFormatStyle style = (count < 4) ? UTZFMT_STYLE_LOCALIZED_GM
T_SHORT : UTZFMT_STYLE_LOCALIZED_GMT; |
| 2956 TimeZone *tz = tzFormat()->parse(style, text, pos, &tzTimeType); | 3119 TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType); |
| 2957 if (tz != NULL) { | 3120 if (tz != NULL) { |
| 2958 ((SimpleDateFormat*)this)->tztype = tzTimeType; | |
| 2959 cal.adoptTimeZone(tz); | 3121 cal.adoptTimeZone(tz); |
| 2960 return pos.getIndex(); | 3122 return pos.getIndex(); |
| 2961 } | 3123 } |
| 2962 return -start; | 3124 return -start; |
| 2963 } | 3125 } |
| 2964 case UDAT_TIMEZONE_ISO_FIELD: // 'X' | 3126 case UDAT_TIMEZONE_ISO_FIELD: // 'X' |
| 2965 { | 3127 { |
| 2966 UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN; | |
| 2967 UTimeZoneFormatStyle style; | 3128 UTimeZoneFormatStyle style; |
| 2968 switch (count) { | 3129 switch (count) { |
| 2969 case 1: | 3130 case 1: |
| 2970 style = UTZFMT_STYLE_ISO_BASIC_SHORT; | 3131 style = UTZFMT_STYLE_ISO_BASIC_SHORT; |
| 2971 break; | 3132 break; |
| 2972 case 2: | 3133 case 2: |
| 2973 style = UTZFMT_STYLE_ISO_BASIC_FIXED; | 3134 style = UTZFMT_STYLE_ISO_BASIC_FIXED; |
| 2974 break; | 3135 break; |
| 2975 case 3: | 3136 case 3: |
| 2976 style = UTZFMT_STYLE_ISO_EXTENDED_FIXED; | 3137 style = UTZFMT_STYLE_ISO_EXTENDED_FIXED; |
| 2977 break; | 3138 break; |
| 2978 case 4: | 3139 case 4: |
| 2979 style = UTZFMT_STYLE_ISO_BASIC_FULL; | 3140 style = UTZFMT_STYLE_ISO_BASIC_FULL; |
| 2980 break; | 3141 break; |
| 2981 default: | 3142 default: |
| 2982 style = UTZFMT_STYLE_ISO_EXTENDED_FULL; | 3143 style = UTZFMT_STYLE_ISO_EXTENDED_FULL; |
| 2983 break; | 3144 break; |
| 2984 } | 3145 } |
| 2985 TimeZone *tz = tzFormat()->parse(style, text, pos, &tzTimeType); | 3146 TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType); |
| 2986 if (tz != NULL) { | 3147 if (tz != NULL) { |
| 2987 ((SimpleDateFormat*)this)->tztype = tzTimeType; | |
| 2988 cal.adoptTimeZone(tz); | 3148 cal.adoptTimeZone(tz); |
| 2989 return pos.getIndex(); | 3149 return pos.getIndex(); |
| 2990 } | 3150 } |
| 2991 return -start; | 3151 return -start; |
| 2992 } | 3152 } |
| 2993 case UDAT_TIMEZONE_ISO_LOCAL_FIELD: // 'x' | 3153 case UDAT_TIMEZONE_ISO_LOCAL_FIELD: // 'x' |
| 2994 { | 3154 { |
| 2995 UTimeZoneFormatTimeType tzTimeType = UTZFMT_TIME_TYPE_UNKNOWN; | |
| 2996 UTimeZoneFormatStyle style; | 3155 UTimeZoneFormatStyle style; |
| 2997 switch (count) { | 3156 switch (count) { |
| 2998 case 1: | 3157 case 1: |
| 2999 style = UTZFMT_STYLE_ISO_BASIC_LOCAL_SHORT; | 3158 style = UTZFMT_STYLE_ISO_BASIC_LOCAL_SHORT; |
| 3000 break; | 3159 break; |
| 3001 case 2: | 3160 case 2: |
| 3002 style = UTZFMT_STYLE_ISO_BASIC_LOCAL_FIXED; | 3161 style = UTZFMT_STYLE_ISO_BASIC_LOCAL_FIXED; |
| 3003 break; | 3162 break; |
| 3004 case 3: | 3163 case 3: |
| 3005 style = UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FIXED; | 3164 style = UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FIXED; |
| 3006 break; | 3165 break; |
| 3007 case 4: | 3166 case 4: |
| 3008 style = UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL; | 3167 style = UTZFMT_STYLE_ISO_BASIC_LOCAL_FULL; |
| 3009 break; | 3168 break; |
| 3010 default: | 3169 default: |
| 3011 style = UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL; | 3170 style = UTZFMT_STYLE_ISO_EXTENDED_LOCAL_FULL; |
| 3012 break; | 3171 break; |
| 3013 } | 3172 } |
| 3014 TimeZone *tz = tzFormat()->parse(style, text, pos, &tzTimeType); | 3173 TimeZone *tz = tzFormat()->parse(style, text, pos, tzTimeType); |
| 3015 if (tz != NULL) { | 3174 if (tz != NULL) { |
| 3016 ((SimpleDateFormat*)this)->tztype = tzTimeType; | |
| 3017 cal.adoptTimeZone(tz); | 3175 cal.adoptTimeZone(tz); |
| 3018 return pos.getIndex(); | 3176 return pos.getIndex(); |
| 3019 } | 3177 } |
| 3020 return -start; | 3178 return -start; |
| 3021 } | 3179 } |
| 3022 | 3180 |
| 3023 default: | 3181 default: |
| 3024 // Handle "generic" fields | 3182 // Handle "generic" fields |
| 3025 // this is now handled below, outside the switch block | 3183 // this is now handled below, outside the switch block |
| 3026 break; | 3184 break; |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3081 cal.set(UCAL_MONTH, value - 1); | 3239 cal.set(UCAL_MONTH, value - 1); |
| 3082 break; | 3240 break; |
| 3083 case UDAT_DOW_LOCAL_FIELD: | 3241 case UDAT_DOW_LOCAL_FIELD: |
| 3084 case UDAT_STANDALONE_DAY_FIELD: | 3242 case UDAT_STANDALONE_DAY_FIELD: |
| 3085 cal.set(UCAL_DOW_LOCAL, value); | 3243 cal.set(UCAL_DOW_LOCAL, value); |
| 3086 break; | 3244 break; |
| 3087 case UDAT_QUARTER_FIELD: | 3245 case UDAT_QUARTER_FIELD: |
| 3088 case UDAT_STANDALONE_QUARTER_FIELD: | 3246 case UDAT_STANDALONE_QUARTER_FIELD: |
| 3089 cal.set(UCAL_MONTH, (value - 1) * 3); | 3247 cal.set(UCAL_MONTH, (value - 1) * 3); |
| 3090 break; | 3248 break; |
| 3249 case UDAT_RELATED_YEAR_FIELD: |
| 3250 cal.setRelatedYear(value); |
| 3251 break; |
| 3091 default: | 3252 default: |
| 3092 cal.set(field, value); | 3253 cal.set(field, value); |
| 3093 break; | 3254 break; |
| 3094 } | 3255 } |
| 3095 return pos.getIndex(); | 3256 return pos.getIndex(); |
| 3096 } | 3257 } |
| 3097 return -start; | 3258 return -start; |
| 3098 } | 3259 } |
| 3099 | 3260 |
| 3100 /** | 3261 /** |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3290 delete fSymbols; | 3451 delete fSymbols; |
| 3291 fSymbols=NULL; | 3452 fSymbols=NULL; |
| 3292 initializeSymbols(fLocale, fCalendar, status); // we need new symbols | 3453 initializeSymbols(fLocale, fCalendar, status); // we need new symbols |
| 3293 initializeDefaultCentury(); // we need a new century (possibly) | 3454 initializeDefaultCentury(); // we need a new century (possibly) |
| 3294 } | 3455 } |
| 3295 | 3456 |
| 3296 | 3457 |
| 3297 //---------------------------------------------------------------------- | 3458 //---------------------------------------------------------------------- |
| 3298 | 3459 |
| 3299 | 3460 |
| 3300 void SimpleDateFormat::setContext(UDisplayContext value, UErrorCode& status) | 3461 // override the DateFormat implementation in order to |
| 3462 // lazily initialize fCapitalizationBrkIter |
| 3463 void |
| 3464 SimpleDateFormat::setContext(UDisplayContext value, UErrorCode& status) |
| 3301 { | 3465 { |
| 3302 if (U_FAILURE(status)) | 3466 DateFormat::setContext(value, status); |
| 3303 return; | 3467 #if !UCONFIG_NO_BREAK_ITERATION |
| 3304 if ( (UDisplayContextType)((uint32_t)value >> 8) == UDISPCTX_TYPE_CAPITALIZA
TION ) { | 3468 if (U_SUCCESS(status)) { |
| 3305 fCapitalizationContext = value; | 3469 if ( fCapitalizationBrkIter == NULL && (value==UDISPCTX_CAPITALIZATION_F
OR_BEGINNING_OF_SENTENCE || |
| 3306 } else { | 3470 value==UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU || value==UDI
SPCTX_CAPITALIZATION_FOR_STANDALONE) ) { |
| 3307 status = U_ILLEGAL_ARGUMENT_ERROR; | 3471 UErrorCode status = U_ZERO_ERROR; |
| 3308 } | 3472 fCapitalizationBrkIter = BreakIterator::createSentenceInstance(fLoca
le, status); |
| 3473 if (U_FAILURE(status)) { |
| 3474 delete fCapitalizationBrkIter; |
| 3475 fCapitalizationBrkIter = NULL; |
| 3476 } |
| 3477 } |
| 3478 } |
| 3479 #endif |
| 3309 } | 3480 } |
| 3310 | 3481 |
| 3311 | 3482 |
| 3312 //---------------------------------------------------------------------- | |
| 3313 | |
| 3314 | |
| 3315 UDisplayContext SimpleDateFormat::getContext(UDisplayContextType type, UErrorCod
e& status) const | |
| 3316 { | |
| 3317 if (U_FAILURE(status)) | |
| 3318 return (UDisplayContext)0; | |
| 3319 if (type != UDISPCTX_TYPE_CAPITALIZATION) { | |
| 3320 status = U_ILLEGAL_ARGUMENT_ERROR; | |
| 3321 return (UDisplayContext)0; | |
| 3322 } | |
| 3323 return fCapitalizationContext; | |
| 3324 } | |
| 3325 | |
| 3326 | |
| 3327 //---------------------------------------------------------------------- | 3483 //---------------------------------------------------------------------- |
| 3328 | 3484 |
| 3329 | 3485 |
| 3330 UBool | 3486 UBool |
| 3331 SimpleDateFormat::isFieldUnitIgnored(UCalendarDateFields field) const { | 3487 SimpleDateFormat::isFieldUnitIgnored(UCalendarDateFields field) const { |
| 3332 return isFieldUnitIgnored(fPattern, field); | 3488 return isFieldUnitIgnored(fPattern, field); |
| 3333 } | 3489 } |
| 3334 | 3490 |
| 3335 | 3491 |
| 3336 UBool | 3492 UBool |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3545 umtx_unlock(&LOCK); | 3701 umtx_unlock(&LOCK); |
| 3546 } | 3702 } |
| 3547 return fTimeZoneFormat; | 3703 return fTimeZoneFormat; |
| 3548 } | 3704 } |
| 3549 | 3705 |
| 3550 U_NAMESPACE_END | 3706 U_NAMESPACE_END |
| 3551 | 3707 |
| 3552 #endif /* #if !UCONFIG_NO_FORMATTING */ | 3708 #endif /* #if !UCONFIG_NO_FORMATTING */ |
| 3553 | 3709 |
| 3554 //eof | 3710 //eof |
| OLD | NEW |