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 |