OLD | NEW |
1 /******************************************************************************* | 1 /******************************************************************************* |
2 * Copyright (C) 2008-2014, International Business Machines Corporation and | 2 * Copyright (C) 2008-2015, International Business Machines Corporation and |
3 * others. All Rights Reserved. | 3 * others. All Rights Reserved. |
4 ******************************************************************************* | 4 ******************************************************************************* |
5 * | 5 * |
6 * File DTITVFMT.CPP | 6 * File DTITVFMT.CPP |
7 * | 7 * |
8 ******************************************************************************* | 8 ******************************************************************************* |
9 */ | 9 */ |
10 | 10 |
11 #include "utypeinfo.h" // for 'typeid' to work | 11 #include "utypeinfo.h" // for 'typeid' to work |
12 | 12 |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 DateIntervalInfo* ptn = dtitvinf.clone(); | 110 DateIntervalInfo* ptn = dtitvinf.clone(); |
111 return create(locale, ptn, &skeleton, status); | 111 return create(locale, ptn, &skeleton, status); |
112 } | 112 } |
113 | 113 |
114 | 114 |
115 DateIntervalFormat::DateIntervalFormat() | 115 DateIntervalFormat::DateIntervalFormat() |
116 : fInfo(NULL), | 116 : fInfo(NULL), |
117 fDateFormat(NULL), | 117 fDateFormat(NULL), |
118 fFromCalendar(NULL), | 118 fFromCalendar(NULL), |
119 fToCalendar(NULL), | 119 fToCalendar(NULL), |
120 fDtpng(NULL) | 120 fLocale(Locale::getRoot()), |
| 121 fDatePattern(NULL), |
| 122 fTimePattern(NULL), |
| 123 fDateTimeFormat(NULL) |
121 {} | 124 {} |
122 | 125 |
123 | 126 |
124 DateIntervalFormat::DateIntervalFormat(const DateIntervalFormat& itvfmt) | 127 DateIntervalFormat::DateIntervalFormat(const DateIntervalFormat& itvfmt) |
125 : Format(itvfmt), | 128 : Format(itvfmt), |
126 fInfo(NULL), | 129 fInfo(NULL), |
127 fDateFormat(NULL), | 130 fDateFormat(NULL), |
128 fFromCalendar(NULL), | 131 fFromCalendar(NULL), |
129 fToCalendar(NULL), | 132 fToCalendar(NULL), |
130 fDtpng(NULL) { | 133 fLocale(itvfmt.fLocale), |
| 134 fDatePattern(NULL), |
| 135 fTimePattern(NULL), |
| 136 fDateTimeFormat(NULL) { |
131 *this = itvfmt; | 137 *this = itvfmt; |
132 } | 138 } |
133 | 139 |
134 | 140 |
135 DateIntervalFormat& | 141 DateIntervalFormat& |
136 DateIntervalFormat::operator=(const DateIntervalFormat& itvfmt) { | 142 DateIntervalFormat::operator=(const DateIntervalFormat& itvfmt) { |
137 if ( this != &itvfmt ) { | 143 if ( this != &itvfmt ) { |
138 delete fDateFormat; | 144 delete fDateFormat; |
139 delete fInfo; | 145 delete fInfo; |
140 delete fFromCalendar; | 146 delete fFromCalendar; |
141 delete fToCalendar; | 147 delete fToCalendar; |
142 delete fDtpng; | 148 delete fDatePattern; |
| 149 delete fTimePattern; |
| 150 delete fDateTimeFormat; |
143 if ( itvfmt.fDateFormat ) { | 151 if ( itvfmt.fDateFormat ) { |
144 fDateFormat = (SimpleDateFormat*)itvfmt.fDateFormat->clone(); | 152 fDateFormat = (SimpleDateFormat*)itvfmt.fDateFormat->clone(); |
145 } else { | 153 } else { |
146 fDateFormat = NULL; | 154 fDateFormat = NULL; |
147 } | 155 } |
148 if ( itvfmt.fInfo ) { | 156 if ( itvfmt.fInfo ) { |
149 fInfo = itvfmt.fInfo->clone(); | 157 fInfo = itvfmt.fInfo->clone(); |
150 } else { | 158 } else { |
151 fInfo = NULL; | 159 fInfo = NULL; |
152 } | 160 } |
153 if ( itvfmt.fFromCalendar ) { | 161 if ( itvfmt.fFromCalendar ) { |
154 fFromCalendar = itvfmt.fFromCalendar->clone(); | 162 fFromCalendar = itvfmt.fFromCalendar->clone(); |
155 } else { | 163 } else { |
156 fFromCalendar = NULL; | 164 fFromCalendar = NULL; |
157 } | 165 } |
158 if ( itvfmt.fToCalendar ) { | 166 if ( itvfmt.fToCalendar ) { |
159 fToCalendar = itvfmt.fToCalendar->clone(); | 167 fToCalendar = itvfmt.fToCalendar->clone(); |
160 } else { | 168 } else { |
161 fToCalendar = NULL; | 169 fToCalendar = NULL; |
162 } | 170 } |
163 fSkeleton = itvfmt.fSkeleton; | 171 fSkeleton = itvfmt.fSkeleton; |
164 int8_t i; | 172 int8_t i; |
165 for ( i = 0; i< DateIntervalInfo::kIPI_MAX_INDEX; ++i ) { | 173 for ( i = 0; i< DateIntervalInfo::kIPI_MAX_INDEX; ++i ) { |
166 fIntervalPatterns[i] = itvfmt.fIntervalPatterns[i]; | 174 fIntervalPatterns[i] = itvfmt.fIntervalPatterns[i]; |
167 } | 175 } |
168 if (itvfmt.fDtpng) { | 176 fLocale = itvfmt.fLocale; |
169 fDtpng = itvfmt.fDtpng->clone(); | 177 fDatePattern = (itvfmt.fDatePattern)? (UnicodeString*)itvfmt.fDate
Pattern->clone(): NULL; |
170 } | 178 fTimePattern = (itvfmt.fTimePattern)? (UnicodeString*)itvfmt.fTime
Pattern->clone(): NULL; |
| 179 fDateTimeFormat = (itvfmt.fDateTimeFormat)? (UnicodeString*)itvfmt.fDate
TimeFormat->clone(): NULL; |
171 } | 180 } |
172 return *this; | 181 return *this; |
173 } | 182 } |
174 | 183 |
175 | 184 |
176 DateIntervalFormat::~DateIntervalFormat() { | 185 DateIntervalFormat::~DateIntervalFormat() { |
177 delete fInfo; | 186 delete fInfo; |
178 delete fDateFormat; | 187 delete fDateFormat; |
179 delete fFromCalendar; | 188 delete fFromCalendar; |
180 delete fToCalendar; | 189 delete fToCalendar; |
181 delete fDtpng; | 190 delete fDatePattern; |
| 191 delete fTimePattern; |
| 192 delete fDateTimeFormat; |
182 } | 193 } |
183 | 194 |
184 | 195 |
185 Format* | 196 Format* |
186 DateIntervalFormat::clone(void) const { | 197 DateIntervalFormat::clone(void) const { |
187 return new DateIntervalFormat(*this); | 198 return new DateIntervalFormat(*this); |
188 } | 199 } |
189 | 200 |
190 | 201 |
191 UBool | 202 UBool |
192 DateIntervalFormat::operator==(const Format& other) const { | 203 DateIntervalFormat::operator==(const Format& other) const { |
193 if (typeid(*this) == typeid(other)) { | 204 if (typeid(*this) == typeid(other)) { |
194 const DateIntervalFormat* fmt = (DateIntervalFormat*)&other; | 205 const DateIntervalFormat* fmt = (DateIntervalFormat*)&other; |
195 #ifdef DTITVFMT_DEBUG | 206 #ifdef DTITVFMT_DEBUG |
196 UBool equal; | 207 UBool equal; |
197 equal = (this == fmt); | 208 equal = (this == fmt); |
198 | 209 |
199 equal = (*fInfo == *fmt->fInfo); | 210 equal = (*fInfo == *fmt->fInfo); |
200 equal = (*fDateFormat == *fmt->fDateFormat); | 211 equal = (*fDateFormat == *fmt->fDateFormat); |
201 equal = fFromCalendar->isEquivalentTo(*fmt->fFromCalendar) ; | 212 equal = fFromCalendar->isEquivalentTo(*fmt->fFromCalendar) ; |
202 equal = fToCalendar->isEquivalentTo(*fmt->fToCalendar) ; | 213 equal = fToCalendar->isEquivalentTo(*fmt->fToCalendar) ; |
203 equal = (fSkeleton == fmt->fSkeleton); | 214 equal = (fSkeleton == fmt->fSkeleton); |
| 215 equal = ((fDatePattern == NULL && fmt->fDatePattern == NULL) || (fDatePatter
n && fmt->fDatePattern && *fDatePattern == *fmt->fDatePattern)); |
| 216 equal = ((fTimePattern == NULL && fmt->fTimePattern == NULL) || (fTimePatter
n && fmt->fTimePattern && *fTimePattern == *fmt->fTimePattern)); |
| 217 equal = ((fDateTimeFormat == NULL && fmt->fDateTimeFormat == NULL) || (fDate
TimeFormat && fmt->fDateTimeFormat && *fDateTimeFormat == *fmt->fDateTimeFormat)
); |
204 #endif | 218 #endif |
205 UBool res; | 219 UBool res; |
206 res = ( this == fmt ) || | 220 res = ( this == fmt ) || |
207 ( Format::operator==(other) && | 221 ( Format::operator==(other) && |
208 fInfo && | 222 fInfo && |
209 ( *fInfo == *fmt->fInfo ) && | 223 ( *fInfo == *fmt->fInfo ) && |
210 fDateFormat && | 224 fDateFormat && |
211 ( *fDateFormat == *fmt->fDateFormat ) && | 225 ( *fDateFormat == *fmt->fDateFormat ) && |
212 fFromCalendar && | 226 fFromCalendar && |
213 fFromCalendar->isEquivalentTo(*fmt->fFromCalendar) && | 227 fFromCalendar->isEquivalentTo(*fmt->fFromCalendar) && |
214 fToCalendar && | 228 fToCalendar && |
215 fToCalendar->isEquivalentTo(*fmt->fToCalendar) && | 229 fToCalendar->isEquivalentTo(*fmt->fToCalendar) && |
216 fSkeleton == fmt->fSkeleton && | 230 fSkeleton == fmt->fSkeleton && |
217 fDtpng && | 231 ((fDatePattern == NULL && fmt->fDatePattern == NULL) || (
fDatePattern && fmt->fDatePattern && *fDatePattern == *fmt->fDatePattern)) && |
218 (*fDtpng == *fmt->fDtpng) ); | 232 ((fTimePattern == NULL && fmt->fTimePattern == NULL) || (
fTimePattern && fmt->fTimePattern && *fTimePattern == *fmt->fTimePattern)) && |
| 233 ((fDateTimeFormat == NULL && fmt->fDateTimeFormat == NULL) || (
fDateTimeFormat && fmt->fDateTimeFormat && *fDateTimeFormat == *fmt->fDateTimeFo
rmat)) && fLocale == fmt->fLocale); |
219 int8_t i; | 234 int8_t i; |
220 for (i = 0; i< DateIntervalInfo::kIPI_MAX_INDEX && res == TRUE; ++i ) { | 235 for (i = 0; i< DateIntervalInfo::kIPI_MAX_INDEX && res == TRUE; ++i ) { |
221 res = ( fIntervalPatterns[i].firstPart == | 236 res = ( fIntervalPatterns[i].firstPart == |
222 fmt->fIntervalPatterns[i].firstPart) && | 237 fmt->fIntervalPatterns[i].firstPart) && |
223 ( fIntervalPatterns[i].secondPart == | 238 ( fIntervalPatterns[i].secondPart == |
224 fmt->fIntervalPatterns[i].secondPart ) && | 239 fmt->fIntervalPatterns[i].secondPart ) && |
225 ( fIntervalPatterns[i].laterDateFirst == | 240 ( fIntervalPatterns[i].laterDateFirst == |
226 fmt->fIntervalPatterns[i].laterDateFirst) ; | 241 fmt->fIntervalPatterns[i].laterDateFirst) ; |
227 } | 242 } |
228 return res; | 243 return res; |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 field = UCAL_DATE; | 322 field = UCAL_DATE; |
308 } else if ( fromCalendar.get(UCAL_AM_PM, status) != | 323 } else if ( fromCalendar.get(UCAL_AM_PM, status) != |
309 toCalendar.get(UCAL_AM_PM, status) ) { | 324 toCalendar.get(UCAL_AM_PM, status) ) { |
310 field = UCAL_AM_PM; | 325 field = UCAL_AM_PM; |
311 } else if ( fromCalendar.get(UCAL_HOUR, status) != | 326 } else if ( fromCalendar.get(UCAL_HOUR, status) != |
312 toCalendar.get(UCAL_HOUR, status) ) { | 327 toCalendar.get(UCAL_HOUR, status) ) { |
313 field = UCAL_HOUR; | 328 field = UCAL_HOUR; |
314 } else if ( fromCalendar.get(UCAL_MINUTE, status) != | 329 } else if ( fromCalendar.get(UCAL_MINUTE, status) != |
315 toCalendar.get(UCAL_MINUTE, status) ) { | 330 toCalendar.get(UCAL_MINUTE, status) ) { |
316 field = UCAL_MINUTE; | 331 field = UCAL_MINUTE; |
| 332 } else if ( fromCalendar.get(UCAL_SECOND, status) != |
| 333 toCalendar.get(UCAL_SECOND, status) ) { |
| 334 field = UCAL_SECOND; |
317 } | 335 } |
318 | 336 |
319 if ( U_FAILURE(status) ) { | 337 if ( U_FAILURE(status) ) { |
320 return appendTo; | 338 return appendTo; |
321 } | 339 } |
322 if ( field == UCAL_FIELD_COUNT ) { | 340 if ( field == UCAL_FIELD_COUNT ) { |
323 /* ignore the second/millisecond etc. small fields' difference. | 341 /* ignore the millisecond etc. small fields' difference. |
324 * use single date when all the above are the same. | 342 * use single date when all the above are the same. |
325 */ | 343 */ |
326 return fDateFormat->format(fromCalendar, appendTo, pos); | 344 return fDateFormat->format(fromCalendar, appendTo, pos); |
327 } | 345 } |
| 346 UBool fromToOnSameDay = (field==UCAL_AM_PM || field==UCAL_HOUR || field==UCA
L_MINUTE || field==UCAL_SECOND); |
328 | 347 |
329 // following call should not set wrong status, | 348 // following call should not set wrong status, |
330 // all the pass-in fields are valid till here | 349 // all the pass-in fields are valid till here |
331 int32_t itvPtnIndex = DateIntervalInfo::calendarFieldToIntervalIndex(field, | 350 int32_t itvPtnIndex = DateIntervalInfo::calendarFieldToIntervalIndex(field, |
332 status); | 351 status); |
333 const PatternInfo& intervalPattern = fIntervalPatterns[itvPtnIndex]; | 352 const PatternInfo& intervalPattern = fIntervalPatterns[itvPtnIndex]; |
334 | 353 |
335 if ( intervalPattern.firstPart.isEmpty() && | 354 if ( intervalPattern.firstPart.isEmpty() && |
336 intervalPattern.secondPart.isEmpty() ) { | 355 intervalPattern.secondPart.isEmpty() ) { |
337 if ( fDateFormat->isFieldUnitIgnored(field) ) { | 356 if ( fDateFormat->isFieldUnitIgnored(field) ) { |
338 /* the largest different calendar field is small than | 357 /* the largest different calendar field is small than |
339 * the smallest calendar field in pattern, | 358 * the smallest calendar field in pattern, |
340 * return single date format. | 359 * return single date format. |
341 */ | 360 */ |
342 return fDateFormat->format(fromCalendar, appendTo, pos); | 361 return fDateFormat->format(fromCalendar, appendTo, pos); |
343 } | 362 } |
344 return fallbackFormat(fromCalendar, toCalendar, appendTo, pos, status); | 363 return fallbackFormat(fromCalendar, toCalendar, fromToOnSameDay, appendT
o, pos, status); |
345 } | 364 } |
346 // If the first part in interval pattern is empty, | 365 // If the first part in interval pattern is empty, |
347 // the 2nd part of it saves the full-pattern used in fall-back. | 366 // the 2nd part of it saves the full-pattern used in fall-back. |
348 // For a 'real' interval pattern, the first part will never be empty. | 367 // For a 'real' interval pattern, the first part will never be empty. |
349 if ( intervalPattern.firstPart.isEmpty() ) { | 368 if ( intervalPattern.firstPart.isEmpty() ) { |
350 // fall back | 369 // fall back |
351 UnicodeString originalPattern; | 370 UnicodeString originalPattern; |
352 fDateFormat->toPattern(originalPattern); | 371 fDateFormat->toPattern(originalPattern); |
353 fDateFormat->applyPattern(intervalPattern.secondPart); | 372 fDateFormat->applyPattern(intervalPattern.secondPart); |
354 appendTo = fallbackFormat(fromCalendar, toCalendar, appendTo, pos, statu
s); | 373 appendTo = fallbackFormat(fromCalendar, toCalendar, fromToOnSameDay, app
endTo, pos, status); |
355 fDateFormat->applyPattern(originalPattern); | 374 fDateFormat->applyPattern(originalPattern); |
356 return appendTo; | 375 return appendTo; |
357 } | 376 } |
358 Calendar* firstCal; | 377 Calendar* firstCal; |
359 Calendar* secondCal; | 378 Calendar* secondCal; |
360 if ( intervalPattern.laterDateFirst ) { | 379 if ( intervalPattern.laterDateFirst ) { |
361 firstCal = &toCalendar; | 380 firstCal = &toCalendar; |
362 secondCal = &fromCalendar; | 381 secondCal = &fromCalendar; |
363 } else { | 382 } else { |
364 firstCal = &fromCalendar; | 383 firstCal = &fromCalendar; |
365 secondCal = &toCalendar; | 384 secondCal = &toCalendar; |
366 } | 385 } |
367 // break the interval pattern into 2 parts, | 386 // break the interval pattern into 2 parts, |
368 // first part should not be empty, | 387 // first part should not be empty, |
369 UnicodeString originalPattern; | 388 UnicodeString originalPattern; |
370 fDateFormat->toPattern(originalPattern); | 389 fDateFormat->toPattern(originalPattern); |
371 fDateFormat->applyPattern(intervalPattern.firstPart); | 390 fDateFormat->applyPattern(intervalPattern.firstPart); |
372 fDateFormat->format(*firstCal, appendTo, pos); | 391 fDateFormat->format(*firstCal, appendTo, pos); |
373 if ( !intervalPattern.secondPart.isEmpty() ) { | 392 if ( !intervalPattern.secondPart.isEmpty() ) { |
374 fDateFormat->applyPattern(intervalPattern.secondPart); | 393 fDateFormat->applyPattern(intervalPattern.secondPart); |
375 fDateFormat->format(*secondCal, appendTo, pos); | 394 FieldPosition otherPos; |
| 395 otherPos.setField(pos.getField()); |
| 396 fDateFormat->format(*secondCal, appendTo, otherPos); |
| 397 if (pos.getEndIndex() == 0 && otherPos.getEndIndex() > 0) { |
| 398 pos = otherPos; |
| 399 } |
376 } | 400 } |
377 fDateFormat->applyPattern(originalPattern); | 401 fDateFormat->applyPattern(originalPattern); |
378 return appendTo; | 402 return appendTo; |
379 } | 403 } |
380 | 404 |
381 | 405 |
382 | 406 |
383 void | 407 void |
384 DateIntervalFormat::parseObject(const UnicodeString& /* source */, | 408 DateIntervalFormat::parseObject(const UnicodeString& /* source */, |
385 Formattable& /* result */, | 409 Formattable& /* result */, |
(...skipping 10 matching lines...) Expand all Loading... |
396 DateIntervalFormat::getDateIntervalInfo() const { | 420 DateIntervalFormat::getDateIntervalInfo() const { |
397 return fInfo; | 421 return fInfo; |
398 } | 422 } |
399 | 423 |
400 | 424 |
401 void | 425 void |
402 DateIntervalFormat::setDateIntervalInfo(const DateIntervalInfo& newItvPattern, | 426 DateIntervalFormat::setDateIntervalInfo(const DateIntervalInfo& newItvPattern, |
403 UErrorCode& status) { | 427 UErrorCode& status) { |
404 delete fInfo; | 428 delete fInfo; |
405 fInfo = new DateIntervalInfo(newItvPattern); | 429 fInfo = new DateIntervalInfo(newItvPattern); |
| 430 |
| 431 // Delete patterns that get reset by initializePattern |
| 432 delete fDatePattern; |
| 433 fDatePattern = NULL; |
| 434 delete fTimePattern; |
| 435 fTimePattern = NULL; |
| 436 delete fDateTimeFormat; |
| 437 fDateTimeFormat = NULL; |
| 438 |
406 if ( fDateFormat ) { | 439 if ( fDateFormat ) { |
407 initializePattern(status); | 440 initializePattern(status); |
408 } | 441 } |
409 } | 442 } |
410 | 443 |
411 | 444 |
412 | 445 |
413 const DateFormat* | 446 const DateFormat* |
414 DateIntervalFormat::getDateFormat() const { | 447 DateIntervalFormat::getDateFormat() const { |
415 return fDateFormat; | 448 return fDateFormat; |
416 } | 449 } |
417 | 450 |
418 | 451 |
419 void | 452 void |
420 DateIntervalFormat::adoptTimeZone(TimeZone* zone) | 453 DateIntervalFormat::adoptTimeZone(TimeZone* zone) |
421 { | 454 { |
422 if (fDateFormat != NULL) { | 455 if (fDateFormat != NULL) { |
423 fDateFormat->adoptTimeZone(zone); | 456 fDateFormat->adoptTimeZone(zone); |
424 } | 457 } |
425 // The fDateFormat has the master calendar for the DateIntervalFormat and ha
s | 458 // The fDateFormat has the master calendar for the DateIntervalFormat and ha
s |
426 // ownership of any adopted TimeZone; fFromCalendar and fToCalendar are inte
rnal | 459 // ownership of any adopted TimeZone; fFromCalendar and fToCalendar are inte
rnal |
427 // work clones of that calendar (and should not also be given ownership of t
he | 460 // work clones of that calendar (and should not also be given ownership of t
he |
428 // adopted TimeZone). | 461 // adopted TimeZone). |
429 if (fFromCalendar) { | 462 if (fFromCalendar) { |
430 » fFromCalendar->setTimeZone(*zone); | 463 fFromCalendar->setTimeZone(*zone); |
431 } | 464 } |
432 if (fToCalendar) { | 465 if (fToCalendar) { |
433 » fToCalendar->setTimeZone(*zone); | 466 fToCalendar->setTimeZone(*zone); |
434 } | 467 } |
435 } | 468 } |
436 | 469 |
437 void | 470 void |
438 DateIntervalFormat::setTimeZone(const TimeZone& zone) | 471 DateIntervalFormat::setTimeZone(const TimeZone& zone) |
439 { | 472 { |
440 if (fDateFormat != NULL) { | 473 if (fDateFormat != NULL) { |
441 fDateFormat->setTimeZone(zone); | 474 fDateFormat->setTimeZone(zone); |
442 } | 475 } |
443 // The fDateFormat has the master calendar for the DateIntervalFormat; | 476 // The fDateFormat has the master calendar for the DateIntervalFormat; |
444 // fFromCalendar and fToCalendar are internal work clones of that calendar. | 477 // fFromCalendar and fToCalendar are internal work clones of that calendar. |
445 if (fFromCalendar) { | 478 if (fFromCalendar) { |
446 » fFromCalendar->setTimeZone(zone); | 479 fFromCalendar->setTimeZone(zone); |
447 } | 480 } |
448 if (fToCalendar) { | 481 if (fToCalendar) { |
449 » fToCalendar->setTimeZone(zone); | 482 fToCalendar->setTimeZone(zone); |
450 } | 483 } |
451 } | 484 } |
452 | 485 |
453 const TimeZone& | 486 const TimeZone& |
454 DateIntervalFormat::getTimeZone() const | 487 DateIntervalFormat::getTimeZone() const |
455 { | 488 { |
456 if (fDateFormat != NULL) { | 489 if (fDateFormat != NULL) { |
457 return fDateFormat->getTimeZone(); | 490 return fDateFormat->getTimeZone(); |
458 } | 491 } |
459 // If fDateFormat is NULL (unexpected), create default timezone. | 492 // If fDateFormat is NULL (unexpected), create default timezone. |
460 return *(TimeZone::createDefault()); | 493 return *(TimeZone::createDefault()); |
461 } | 494 } |
462 | 495 |
463 DateIntervalFormat::DateIntervalFormat(const Locale& locale, | 496 DateIntervalFormat::DateIntervalFormat(const Locale& locale, |
464 DateIntervalInfo* dtItvInfo, | 497 DateIntervalInfo* dtItvInfo, |
465 const UnicodeString* skeleton, | 498 const UnicodeString* skeleton, |
466 UErrorCode& status) | 499 UErrorCode& status) |
467 : fInfo(NULL), | 500 : fInfo(NULL), |
468 fDateFormat(NULL), | 501 fDateFormat(NULL), |
469 fFromCalendar(NULL), | 502 fFromCalendar(NULL), |
470 fToCalendar(NULL), | 503 fToCalendar(NULL), |
471 fDtpng(NULL) | 504 fLocale(locale), |
| 505 fDatePattern(NULL), |
| 506 fTimePattern(NULL), |
| 507 fDateTimeFormat(NULL) |
472 { | 508 { |
473 if ( U_FAILURE(status) ) { | 509 if ( U_FAILURE(status) ) { |
474 delete dtItvInfo; | 510 delete dtItvInfo; |
475 return; | 511 return; |
476 } | 512 } |
477 fDtpng = DateTimePatternGenerator::createInstance(locale, status); | 513 SimpleDateFormat* dtfmt = |
478 SimpleDateFormat* dtfmt = createSDFPatternInstance(*skeleton, locale, | 514 static_cast<SimpleDateFormat *>( |
479 fDtpng, status); | 515 DateFormat::createInstanceForSkeleton( |
| 516 *skeleton, locale, status)); |
480 if ( U_FAILURE(status) ) { | 517 if ( U_FAILURE(status) ) { |
481 delete dtItvInfo; | 518 delete dtItvInfo; |
482 delete fDtpng; | |
483 delete dtfmt; | 519 delete dtfmt; |
484 return; | 520 return; |
485 } | 521 } |
486 if ( dtfmt == NULL || dtItvInfo == NULL || fDtpng == NULL ) { | 522 if ( dtfmt == NULL || dtItvInfo == NULL) { |
487 status = U_MEMORY_ALLOCATION_ERROR; | 523 status = U_MEMORY_ALLOCATION_ERROR; |
488 // safe to delete NULL | 524 // safe to delete NULL |
489 delete dtfmt; | 525 delete dtfmt; |
490 delete dtItvInfo; | 526 delete dtItvInfo; |
491 delete fDtpng; | |
492 return; | 527 return; |
493 } | 528 } |
494 if ( skeleton ) { | 529 if ( skeleton ) { |
495 fSkeleton = *skeleton; | 530 fSkeleton = *skeleton; |
496 } | 531 } |
497 fInfo = dtItvInfo; | 532 fInfo = dtItvInfo; |
498 fDateFormat = dtfmt; | 533 fDateFormat = dtfmt; |
499 if ( dtfmt->getCalendar() ) { | 534 if ( dtfmt->getCalendar() ) { |
500 fFromCalendar = dtfmt->getCalendar()->clone(); | 535 fFromCalendar = dtfmt->getCalendar()->clone(); |
501 fToCalendar = dtfmt->getCalendar()->clone(); | 536 fToCalendar = dtfmt->getCalendar()->clone(); |
502 } else { | 537 } else { |
503 fFromCalendar = NULL; | 538 fFromCalendar = NULL; |
504 fToCalendar = NULL; | 539 fToCalendar = NULL; |
505 } | 540 } |
506 initializePattern(status); | 541 initializePattern(status); |
507 } | 542 } |
508 | 543 |
509 | |
510 SimpleDateFormat* U_EXPORT2 | |
511 DateIntervalFormat::createSDFPatternInstance(const UnicodeString& skeleton, | |
512 const Locale& locale, | |
513 DateTimePatternGenerator* dtpng, | |
514 UErrorCode& status) | |
515 { | |
516 if ( U_FAILURE(status) ) { | |
517 return NULL; | |
518 } | |
519 | |
520 const UnicodeString pattern = dtpng->getBestPattern(skeleton, status); | |
521 if ( U_FAILURE(status) ) { | |
522 return NULL; | |
523 } | |
524 SimpleDateFormat* dtfmt = new SimpleDateFormat(pattern, locale, status); | |
525 if ( U_FAILURE(status) ) { | |
526 delete dtfmt; | |
527 return NULL; | |
528 } | |
529 return dtfmt; | |
530 } | |
531 | |
532 | |
533 DateIntervalFormat* U_EXPORT2 | 544 DateIntervalFormat* U_EXPORT2 |
534 DateIntervalFormat::create(const Locale& locale, | 545 DateIntervalFormat::create(const Locale& locale, |
535 DateIntervalInfo* dtitvinf, | 546 DateIntervalInfo* dtitvinf, |
536 const UnicodeString* skeleton, | 547 const UnicodeString* skeleton, |
537 UErrorCode& status) { | 548 UErrorCode& status) { |
538 DateIntervalFormat* f = new DateIntervalFormat(locale, dtitvinf, | 549 DateIntervalFormat* f = new DateIntervalFormat(locale, dtitvinf, |
539 skeleton, status); | 550 skeleton, status); |
540 if ( f == NULL ) { | 551 if ( f == NULL ) { |
541 status = U_MEMORY_ALLOCATION_ERROR; | 552 status = U_MEMORY_ALLOCATION_ERROR; |
542 delete dtitvinf; | 553 delete dtitvinf; |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 #ifdef DTITVFMT_DEBUG | 607 #ifdef DTITVFMT_DEBUG |
597 char result[1000]; | 608 char result[1000]; |
598 char result_1[1000]; | 609 char result_1[1000]; |
599 char mesg[2000]; | 610 char mesg[2000]; |
600 fSkeleton.extract(0, fSkeleton.length(), result, "UTF-8"); | 611 fSkeleton.extract(0, fSkeleton.length(), result, "UTF-8"); |
601 sprintf(mesg, "in getBestSkeleton: fSkeleton: %s; \n", result); | 612 sprintf(mesg, "in getBestSkeleton: fSkeleton: %s; \n", result); |
602 PRINTMESG(mesg) | 613 PRINTMESG(mesg) |
603 #endif | 614 #endif |
604 // fSkeleton is already set by createDateIntervalInstance() | 615 // fSkeleton is already set by createDateIntervalInstance() |
605 // or by createInstance(UnicodeString skeleton, .... ) | 616 // or by createInstance(UnicodeString skeleton, .... ) |
606 fSkeleton = fDtpng->getSkeleton(fullPattern, status); | 617 fSkeleton = DateTimePatternGenerator::staticGetSkeleton( |
| 618 fullPattern, status); |
607 if ( U_FAILURE(status) ) { | 619 if ( U_FAILURE(status) ) { |
608 return; | 620 return; |
609 } | 621 } |
610 } | 622 } |
611 | 623 |
612 // initialize the fIntervalPattern ordering | 624 // initialize the fIntervalPattern ordering |
613 int8_t i; | 625 int8_t i; |
614 for ( i = 0; i < DateIntervalInfo::kIPI_MAX_INDEX; ++i ) { | 626 for ( i = 0; i < DateIntervalInfo::kIPI_MAX_INDEX; ++i ) { |
615 fIntervalPatterns[i].laterDateFirst = fInfo->getDefaultOrder(); | 627 fIntervalPatterns[i].laterDateFirst = fInfo->getDefaultOrder(); |
616 } | 628 } |
(...skipping 23 matching lines...) Expand all Loading... |
640 | 652 |
641 #ifdef DTITVFMT_DEBUG | 653 #ifdef DTITVFMT_DEBUG |
642 char result[1000]; | 654 char result[1000]; |
643 char result_1[1000]; | 655 char result_1[1000]; |
644 char mesg[2000]; | 656 char mesg[2000]; |
645 fSkeleton.extract(0, fSkeleton.length(), result, "UTF-8"); | 657 fSkeleton.extract(0, fSkeleton.length(), result, "UTF-8"); |
646 sprintf(mesg, "in getBestSkeleton: fSkeleton: %s; \n", result); | 658 sprintf(mesg, "in getBestSkeleton: fSkeleton: %s; \n", result); |
647 PRINTMESG(mesg) | 659 PRINTMESG(mesg) |
648 #endif | 660 #endif |
649 | 661 |
| 662 // move this up here since we need it for fallbacks |
| 663 if ( timeSkeleton.length() > 0 && dateSkeleton.length() > 0 ) { |
| 664 // Need the Date/Time pattern for concatenation of the date |
| 665 // with the time interval. |
| 666 // The date/time pattern ( such as {0} {1} ) is saved in |
| 667 // calendar, that is why need to get the CalendarData here. |
| 668 CalendarData* calData = new CalendarData(locale, NULL, status); |
| 669 if ( U_FAILURE(status) ) { |
| 670 delete calData; |
| 671 return; |
| 672 } |
| 673 if ( calData == NULL ) { |
| 674 status = U_MEMORY_ALLOCATION_ERROR; |
| 675 return; |
| 676 } |
| 677 |
| 678 const UResourceBundle* dateTimePatternsRes = calData->getByKey( |
| 679 gDateTimePatternsTag, status); |
| 680 int32_t dateTimeFormatLength; |
| 681 const UChar* dateTimeFormat = ures_getStringByIndex( |
| 682 dateTimePatternsRes, |
| 683 (int32_t)DateFormat::kDateTime, |
| 684 &dateTimeFormatLength, &status); |
| 685 if ( U_SUCCESS(status) && dateTimeFormatLength >= 3 ) { |
| 686 fDateTimeFormat = new UnicodeString(dateTimeFormat, dateTimeFormatLe
ngth); |
| 687 } |
| 688 delete calData; |
| 689 } |
650 | 690 |
651 UBool found = setSeparateDateTimePtn(normalizedDateSkeleton, | 691 UBool found = setSeparateDateTimePtn(normalizedDateSkeleton, |
652 normalizedTimeSkeleton); | 692 normalizedTimeSkeleton); |
653 | 693 |
| 694 // for skeletons with seconds, found is false and we enter this block |
654 if ( found == false ) { | 695 if ( found == false ) { |
655 // use fallback | 696 // use fallback |
656 // TODO: if user asks "m"(minute), but "d"(day) differ | 697 // TODO: if user asks "m"(minute), but "d"(day) differ |
657 if ( timeSkeleton.length() != 0 ) { | 698 if ( timeSkeleton.length() != 0 ) { |
658 if ( dateSkeleton.length() == 0 ) { | 699 if ( dateSkeleton.length() == 0 ) { |
659 // prefix with yMd | 700 // prefix with yMd |
660 timeSkeleton.insert(0, gDateFormatSkeleton[DateFormat::kShort],
-1); | 701 timeSkeleton.insert(0, gDateFormatSkeleton[DateFormat::kShort],
-1); |
661 UnicodeString pattern = fDtpng->getBestPattern(timeSkeleton, sta
tus); | 702 UnicodeString pattern = DateFormat::getBestPattern( |
| 703 locale, timeSkeleton, status); |
662 if ( U_FAILURE(status) ) { | 704 if ( U_FAILURE(status) ) { |
663 return; | 705 return; |
664 } | 706 } |
665 // for fall back interval patterns, | 707 // for fall back interval patterns, |
666 // the first part of the pattern is empty, | 708 // the first part of the pattern is empty, |
667 // the second part of the pattern is the full-pattern | 709 // the second part of the pattern is the full-pattern |
668 // should be used in fall-back. | 710 // should be used in fall-back. |
669 setPatternInfo(UCAL_DATE, NULL, &pattern, fInfo->getDefaultOrder
()); | 711 setPatternInfo(UCAL_DATE, NULL, &pattern, fInfo->getDefaultOrder
()); |
670 setPatternInfo(UCAL_MONTH, NULL, &pattern, fInfo->getDefaultOrde
r()); | 712 setPatternInfo(UCAL_MONTH, NULL, &pattern, fInfo->getDefaultOrde
r()); |
671 setPatternInfo(UCAL_YEAR, NULL, &pattern, fInfo->getDefaultOrder
()); | 713 setPatternInfo(UCAL_YEAR, NULL, &pattern, fInfo->getDefaultOrder
()); |
672 } else { | 714 } else { |
673 // TODO: fall back | 715 // TODO: fall back |
674 } | 716 } |
675 } else { | 717 } else { |
676 // TODO: fall back | 718 // TODO: fall back |
677 } | 719 } |
678 return; | 720 return; |
679 } // end of skeleton not found | 721 } // end of skeleton not found |
680 // interval patterns for skeleton are found in resource | 722 // interval patterns for skeleton are found in resource |
681 if ( timeSkeleton.length() == 0 ) { | 723 if ( timeSkeleton.length() == 0 ) { |
682 // done | 724 // done |
683 } else if ( dateSkeleton.length() == 0 ) { | 725 } else if ( dateSkeleton.length() == 0 ) { |
684 // prefix with yMd | 726 // prefix with yMd |
685 timeSkeleton.insert(0, gDateFormatSkeleton[DateFormat::kShort], -1); | 727 timeSkeleton.insert(0, gDateFormatSkeleton[DateFormat::kShort], -1); |
686 UnicodeString pattern = fDtpng->getBestPattern(timeSkeleton, status); | 728 UnicodeString pattern = DateFormat::getBestPattern( |
| 729 locale, timeSkeleton, status); |
687 if ( U_FAILURE(status) ) { | 730 if ( U_FAILURE(status) ) { |
688 return; | 731 return; |
689 } | 732 } |
690 // for fall back interval patterns, | 733 // for fall back interval patterns, |
691 // the first part of the pattern is empty, | 734 // the first part of the pattern is empty, |
692 // the second part of the pattern is the full-pattern | 735 // the second part of the pattern is the full-pattern |
693 // should be used in fall-back. | 736 // should be used in fall-back. |
694 setPatternInfo(UCAL_DATE, NULL, &pattern, fInfo->getDefaultOrder()); | 737 setPatternInfo(UCAL_DATE, NULL, &pattern, fInfo->getDefaultOrder()); |
695 setPatternInfo(UCAL_MONTH, NULL, &pattern, fInfo->getDefaultOrder()); | 738 setPatternInfo(UCAL_MONTH, NULL, &pattern, fInfo->getDefaultOrder()); |
696 setPatternInfo(UCAL_YEAR, NULL, &pattern, fInfo->getDefaultOrder()); | 739 setPatternInfo(UCAL_YEAR, NULL, &pattern, fInfo->getDefaultOrder()); |
(...skipping 23 matching lines...) Expand all Loading... |
720 if ( !fieldExistsInSkeleton(UCAL_YEAR, dateSkeleton) ) { | 763 if ( !fieldExistsInSkeleton(UCAL_YEAR, dateSkeleton) ) { |
721 // then prefix skeleton with 'y' | 764 // then prefix skeleton with 'y' |
722 skeleton.insert(0, LOW_Y); | 765 skeleton.insert(0, LOW_Y); |
723 setFallbackPattern(UCAL_YEAR, skeleton, status); | 766 setFallbackPattern(UCAL_YEAR, skeleton, status); |
724 } | 767 } |
725 | 768 |
726 /* | 769 /* |
727 * 2) otherwise, present the date followed by the | 770 * 2) otherwise, present the date followed by the |
728 * range expression for the time. | 771 * range expression for the time. |
729 */ | 772 */ |
730 // Need the Date/Time pattern for concatnation the date with | |
731 // the time interval. | |
732 // The date/time pattern ( such as {0} {1} ) is saved in | |
733 // calendar, that is why need to get the CalendarData here. | |
734 CalendarData* calData = new CalendarData(locale, NULL, status); | |
735 | 773 |
736 if ( U_FAILURE(status) ) { | 774 if ( fDateTimeFormat == 0 ) { |
737 delete calData; | 775 // earlier failure getting dateTimeFormat |
738 return; | 776 return; |
739 } | 777 } |
740 | 778 |
741 if ( calData == NULL ) { | 779 UnicodeString datePattern = DateFormat::getBestPattern( |
742 status = U_MEMORY_ALLOCATION_ERROR; | 780 locale, dateSkeleton, status); |
743 return; | |
744 } | |
745 | |
746 const UResourceBundle* dateTimePatternsRes = calData->getByKey( | |
747 gDateTimePatternsTag, status); | |
748 int32_t dateTimeFormatLength; | |
749 const UChar* dateTimeFormat = ures_getStringByIndex( | |
750 dateTimePatternsRes, | |
751 (int32_t)DateFormat::kDateTime, | |
752 &dateTimeFormatLength, &status); | |
753 if ( U_FAILURE(status) ) { | |
754 return; | |
755 } | |
756 | 781 |
757 UnicodeString datePattern = fDtpng->getBestPattern(dateSkeleton, status)
; | 782 concatSingleDate2TimeInterval(*fDateTimeFormat, datePattern, UCAL_AM_PM,
status); |
758 | 783 concatSingleDate2TimeInterval(*fDateTimeFormat, datePattern, UCAL_HOUR,
status); |
759 concatSingleDate2TimeInterval(dateTimeFormat, dateTimeFormatLength, | 784 concatSingleDate2TimeInterval(*fDateTimeFormat, datePattern, UCAL_MINUTE
, status); |
760 datePattern, UCAL_AM_PM, status); | |
761 concatSingleDate2TimeInterval(dateTimeFormat, dateTimeFormatLength, | |
762 datePattern, UCAL_HOUR, status); | |
763 concatSingleDate2TimeInterval(dateTimeFormat, dateTimeFormatLength, | |
764 datePattern, UCAL_MINUTE, status); | |
765 delete calData; | |
766 } | 785 } |
767 } | 786 } |
768 | 787 |
769 | 788 |
770 | 789 |
771 void U_EXPORT2 | 790 void U_EXPORT2 |
772 DateIntervalFormat::getDateTimeSkeleton(const UnicodeString& skeleton, | 791 DateIntervalFormat::getDateTimeSkeleton(const UnicodeString& skeleton, |
773 UnicodeString& dateSkeleton, | 792 UnicodeString& dateSkeleton, |
774 UnicodeString& normalizedDateSkeleton, | 793 UnicodeString& normalizedDateSkeleton, |
775 UnicodeString& timeSkeleton, | 794 UnicodeString& timeSkeleton, |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
970 intervalFormats{ | 989 intervalFormats{ |
971 fallback{"{0} - {1}"} | 990 fallback{"{0} - {1}"} |
972 } | 991 } |
973 there is no skeletons/interval patterns defined, | 992 there is no skeletons/interval patterns defined, |
974 and the best skeleton match could be NULL | 993 and the best skeleton match could be NULL |
975 */ | 994 */ |
976 if ( bestSkeleton == NULL ) { | 995 if ( bestSkeleton == NULL ) { |
977 return false; | 996 return false; |
978 } | 997 } |
979 | 998 |
| 999 // Set patterns for fallback use, need to do this |
| 1000 // before returning if differenceInfo == -1 |
| 1001 UErrorCode status; |
| 1002 if ( dateSkeleton.length() != 0) { |
| 1003 status = U_ZERO_ERROR; |
| 1004 fDatePattern = new UnicodeString(DateFormat::getBestPattern( |
| 1005 fLocale, dateSkeleton, status)); |
| 1006 } |
| 1007 if ( timeSkeleton.length() != 0) { |
| 1008 status = U_ZERO_ERROR; |
| 1009 fTimePattern = new UnicodeString(DateFormat::getBestPattern( |
| 1010 fLocale, timeSkeleton, status)); |
| 1011 } |
| 1012 |
980 // difference: | 1013 // difference: |
981 // 0 means the best matched skeleton is the same as input skeleton | 1014 // 0 means the best matched skeleton is the same as input skeleton |
982 // 1 means the fields are the same, but field width are different | 1015 // 1 means the fields are the same, but field width are different |
983 // 2 means the only difference between fields are v/z, | 1016 // 2 means the only difference between fields are v/z, |
984 // -1 means there are other fields difference | 1017 // -1 means there are other fields difference |
| 1018 // (this will happen, for instance, if the supplied skeleton has seconds, |
| 1019 // but no skeletons in the intervalFormats data do) |
985 if ( differenceInfo == -1 ) { | 1020 if ( differenceInfo == -1 ) { |
986 // skeleton has different fields, not only v/z difference | 1021 // skeleton has different fields, not only v/z difference |
987 return false; | 1022 return false; |
988 } | 1023 } |
989 | 1024 |
990 if ( timeSkeleton.length() == 0 ) { | 1025 if ( timeSkeleton.length() == 0 ) { |
991 UnicodeString extendedSkeleton; | 1026 UnicodeString extendedSkeleton; |
992 UnicodeString extendedBestSkeleton; | 1027 UnicodeString extendedBestSkeleton; |
993 // only has date skeleton | 1028 // only has date skeleton |
994 setIntervalPattern(UCAL_DATE, skeleton, bestSkeleton, differenceInfo, | 1029 setIntervalPattern(UCAL_DATE, skeleton, bestSkeleton, differenceInfo, |
(...skipping 19 matching lines...) Expand all Loading... |
1014 | 1049 |
1015 | 1050 |
1016 | 1051 |
1017 void | 1052 void |
1018 DateIntervalFormat::setFallbackPattern(UCalendarDateFields field, | 1053 DateIntervalFormat::setFallbackPattern(UCalendarDateFields field, |
1019 const UnicodeString& skeleton, | 1054 const UnicodeString& skeleton, |
1020 UErrorCode& status) { | 1055 UErrorCode& status) { |
1021 if ( U_FAILURE(status) ) { | 1056 if ( U_FAILURE(status) ) { |
1022 return; | 1057 return; |
1023 } | 1058 } |
1024 UnicodeString pattern = fDtpng->getBestPattern(skeleton, status); | 1059 UnicodeString pattern = DateFormat::getBestPattern( |
| 1060 fLocale, skeleton, status); |
1025 if ( U_FAILURE(status) ) { | 1061 if ( U_FAILURE(status) ) { |
1026 return; | 1062 return; |
1027 } | 1063 } |
1028 setPatternInfo(field, NULL, &pattern, fInfo->getDefaultOrder()); | 1064 setPatternInfo(field, NULL, &pattern, fInfo->getDefaultOrder()); |
1029 } | 1065 } |
1030 | 1066 |
1031 | 1067 |
1032 | 1068 |
1033 | 1069 |
1034 void | 1070 void |
(...skipping 233 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1268 // "d-d"(last char repeated ), and | 1304 // "d-d"(last char repeated ), and |
1269 // "d-d MM" ( repetition found ) | 1305 // "d-d MM" ( repetition found ) |
1270 if ( count > 0 && foundRepetition == FALSE ) { | 1306 if ( count > 0 && foundRepetition == FALSE ) { |
1271 if ( patternRepeated[(int)(prevCh - PATTERN_CHAR_BASE)] == FALSE ) { | 1307 if ( patternRepeated[(int)(prevCh - PATTERN_CHAR_BASE)] == FALSE ) { |
1272 count = 0; | 1308 count = 0; |
1273 } | 1309 } |
1274 } | 1310 } |
1275 return (i - count); | 1311 return (i - count); |
1276 } | 1312 } |
1277 | 1313 |
| 1314 static const UChar bracketedZero[] = {0x7B,0x30,0x7D}; |
| 1315 static const UChar bracketedOne[] = {0x7B,0x31,0x7D}; |
1278 | 1316 |
| 1317 void |
| 1318 DateIntervalFormat::adjustPosition(UnicodeString& combiningPattern, // has {0} a
nd {1} in it |
| 1319 UnicodeString& pat0, FieldPosition& pos0, //
pattern and pos corresponding to {0} |
| 1320 UnicodeString& pat1, FieldPosition& pos1, //
pattern and pos corresponding to {1} |
| 1321 FieldPosition& posResult) { |
| 1322 int32_t index0 = combiningPattern.indexOf(bracketedZero, 3, 0); |
| 1323 int32_t index1 = combiningPattern.indexOf(bracketedOne, 3, 0); |
| 1324 if (index0 < 0 || index1 < 0) { |
| 1325 return; |
| 1326 } |
| 1327 int32_t placeholderLen = 3; // length of "{0}" or "{1}" |
| 1328 if (index0 < index1) { |
| 1329 if (pos0.getEndIndex() > 0) { |
| 1330 posResult.setBeginIndex(pos0.getBeginIndex() + index0); |
| 1331 posResult.setEndIndex(pos0.getEndIndex() + index0); |
| 1332 } else if (pos1.getEndIndex() > 0) { |
| 1333 // here index1 >= 3 |
| 1334 index1 += pat0.length() - placeholderLen; // adjust for pat0 replaci
ng {0} |
| 1335 posResult.setBeginIndex(pos1.getBeginIndex() + index1); |
| 1336 posResult.setEndIndex(pos1.getEndIndex() + index1); |
| 1337 } |
| 1338 } else { |
| 1339 if (pos1.getEndIndex() > 0) { |
| 1340 posResult.setBeginIndex(pos1.getBeginIndex() + index1); |
| 1341 posResult.setEndIndex(pos1.getEndIndex() + index1); |
| 1342 } else if (pos0.getEndIndex() > 0) { |
| 1343 // here index0 >= 3 |
| 1344 index0 += pat1.length() - placeholderLen; // adjust for pat1 replaci
ng {1} |
| 1345 posResult.setBeginIndex(pos0.getBeginIndex() + index0); |
| 1346 posResult.setEndIndex(pos0.getEndIndex() + index0); |
| 1347 } |
| 1348 } |
| 1349 } |
1279 | 1350 |
1280 UnicodeString& | 1351 UnicodeString& |
1281 DateIntervalFormat::fallbackFormat(Calendar& fromCalendar, | 1352 DateIntervalFormat::fallbackFormat(Calendar& fromCalendar, |
1282 Calendar& toCalendar, | 1353 Calendar& toCalendar, |
| 1354 UBool fromToOnSameDay, // new |
1283 UnicodeString& appendTo, | 1355 UnicodeString& appendTo, |
1284 FieldPosition& pos, | 1356 FieldPosition& pos, |
1285 UErrorCode& status) const { | 1357 UErrorCode& status) const { |
1286 if ( U_FAILURE(status) ) { | 1358 if ( U_FAILURE(status) ) { |
1287 return appendTo; | 1359 return appendTo; |
1288 } | 1360 } |
| 1361 UnicodeString fullPattern; // for saving the pattern in fDateFormat |
| 1362 UBool formatDatePlusTimeRange = (fromToOnSameDay && fDatePattern && fTimePat
tern); |
1289 // the fall back | 1363 // the fall back |
1290 // no need delete earlierDate and laterDate since they are adopted | 1364 // no need delete earlierDate and laterDate since they are adopted |
| 1365 if (formatDatePlusTimeRange) { |
| 1366 fDateFormat->toPattern(fullPattern); // save current pattern, restore la
ter |
| 1367 fDateFormat->applyPattern(*fTimePattern); |
| 1368 } |
| 1369 FieldPosition otherPos; |
| 1370 otherPos.setField(pos.getField()); |
1291 UnicodeString* earlierDate = new UnicodeString(); | 1371 UnicodeString* earlierDate = new UnicodeString(); |
1292 *earlierDate = fDateFormat->format(fromCalendar, *earlierDate, pos); | 1372 fDateFormat->format(fromCalendar, *earlierDate, pos); |
1293 UnicodeString* laterDate = new UnicodeString(); | 1373 UnicodeString* laterDate = new UnicodeString(); |
1294 *laterDate = fDateFormat->format(toCalendar, *laterDate, pos); | 1374 fDateFormat->format(toCalendar, *laterDate, otherPos); |
1295 UnicodeString fallbackPattern; | 1375 UnicodeString fallbackPattern; |
1296 fInfo->getFallbackIntervalPattern(fallbackPattern); | 1376 fInfo->getFallbackIntervalPattern(fallbackPattern); |
| 1377 adjustPosition(fallbackPattern, *earlierDate, pos, *laterDate, otherPos, pos
); |
1297 Formattable fmtArray[2]; | 1378 Formattable fmtArray[2]; |
1298 fmtArray[0].adoptString(earlierDate); | 1379 fmtArray[0].adoptString(earlierDate); |
1299 fmtArray[1].adoptString(laterDate); | 1380 fmtArray[1].adoptString(laterDate); |
1300 | 1381 |
1301 UnicodeString fallback; | 1382 UnicodeString fallbackRange; |
1302 MessageFormat::format(fallbackPattern, fmtArray, 2, fallback, status); | 1383 MessageFormat::format(fallbackPattern, fmtArray, 2, fallbackRange, status); |
| 1384 if ( U_SUCCESS(status) && formatDatePlusTimeRange ) { |
| 1385 // fallbackRange has just the time range, need to format the date part a
nd combine that |
| 1386 fDateFormat->applyPattern(*fDatePattern); |
| 1387 UnicodeString* datePortion = new UnicodeString(); |
| 1388 otherPos.setBeginIndex(0); |
| 1389 otherPos.setEndIndex(0); |
| 1390 fDateFormat->format(fromCalendar, *datePortion, otherPos); |
| 1391 adjustPosition(*fDateTimeFormat, fallbackRange, pos, *datePortion, other
Pos, pos); |
| 1392 fmtArray[0].setString(fallbackRange); // {0} is time range |
| 1393 fmtArray[1].adoptString(datePortion); // {1} is single date portion |
| 1394 fallbackRange.remove(); |
| 1395 MessageFormat::format(*fDateTimeFormat, fmtArray, 2, fallbackRange, stat
us); |
| 1396 } |
1303 if ( U_SUCCESS(status) ) { | 1397 if ( U_SUCCESS(status) ) { |
1304 appendTo.append(fallback); | 1398 appendTo.append(fallbackRange); |
| 1399 } |
| 1400 if (formatDatePlusTimeRange) { |
| 1401 // restore full pattern |
| 1402 fDateFormat->applyPattern(fullPattern); |
1305 } | 1403 } |
1306 return appendTo; | 1404 return appendTo; |
1307 } | 1405 } |
1308 | 1406 |
1309 | 1407 |
1310 | 1408 |
1311 | 1409 |
1312 UBool U_EXPORT2 | 1410 UBool U_EXPORT2 |
1313 DateIntervalFormat::fieldExistsInSkeleton(UCalendarDateFields field, | 1411 DateIntervalFormat::fieldExistsInSkeleton(UCalendarDateFields field, |
1314 const UnicodeString& skeleton) | 1412 const UnicodeString& skeleton) |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1424 for ( j = 0; j < count; ++j ) { | 1522 for ( j = 0; j < count; ++j ) { |
1425 adjustedPtn.append(prevCh); | 1523 adjustedPtn.append(prevCh); |
1426 } | 1524 } |
1427 } | 1525 } |
1428 } | 1526 } |
1429 } | 1527 } |
1430 | 1528 |
1431 | 1529 |
1432 | 1530 |
1433 void | 1531 void |
1434 DateIntervalFormat::concatSingleDate2TimeInterval(const UChar* format, | 1532 DateIntervalFormat::concatSingleDate2TimeInterval(UnicodeString& format, |
1435 int32_t formatLen, | |
1436 const UnicodeString& datePattern, | 1533 const UnicodeString& datePattern, |
1437 UCalendarDateFields field, | 1534 UCalendarDateFields field, |
1438 UErrorCode& status) { | 1535 UErrorCode& status) { |
1439 // following should not set wrong status | 1536 // following should not set wrong status |
1440 int32_t itvPtnIndex = DateIntervalInfo::calendarFieldToIntervalIndex(field, | 1537 int32_t itvPtnIndex = DateIntervalInfo::calendarFieldToIntervalIndex(field, |
1441 status); | 1538 status); |
1442 if ( U_FAILURE(status) ) { | 1539 if ( U_FAILURE(status) ) { |
1443 return; | 1540 return; |
1444 } | 1541 } |
1445 PatternInfo& timeItvPtnInfo = fIntervalPatterns[itvPtnIndex]; | 1542 PatternInfo& timeItvPtnInfo = fIntervalPatterns[itvPtnIndex]; |
1446 if ( !timeItvPtnInfo.firstPart.isEmpty() ) { | 1543 if ( !timeItvPtnInfo.firstPart.isEmpty() ) { |
1447 // UnicodeString allocated here is adopted, so no need to delete | 1544 // UnicodeString allocated here is adopted, so no need to delete |
1448 UnicodeString* timeIntervalPattern = new UnicodeString(timeItvPtnInfo.fi
rstPart); | 1545 UnicodeString* timeIntervalPattern = new UnicodeString(timeItvPtnInfo.fi
rstPart); |
1449 timeIntervalPattern->append(timeItvPtnInfo.secondPart); | 1546 timeIntervalPattern->append(timeItvPtnInfo.secondPart); |
1450 UnicodeString* dateStr = new UnicodeString(datePattern); | 1547 UnicodeString* dateStr = new UnicodeString(datePattern); |
1451 Formattable fmtArray[2]; | 1548 Formattable fmtArray[2]; |
1452 fmtArray[0].adoptString(timeIntervalPattern); | 1549 fmtArray[0].adoptString(timeIntervalPattern); |
1453 fmtArray[1].adoptString(dateStr); | 1550 fmtArray[1].adoptString(dateStr); |
1454 UnicodeString combinedPattern; | 1551 UnicodeString combinedPattern; |
1455 MessageFormat::format(UnicodeString(TRUE, format, formatLen), | 1552 MessageFormat::format(format, fmtArray, 2, combinedPattern, status); |
1456 fmtArray, 2, combinedPattern, status); | |
1457 if ( U_FAILURE(status) ) { | 1553 if ( U_FAILURE(status) ) { |
1458 return; | 1554 return; |
1459 } | 1555 } |
1460 setIntervalPattern(field, combinedPattern, timeItvPtnInfo.laterDateFirst
); | 1556 setIntervalPattern(field, combinedPattern, timeItvPtnInfo.laterDateFirst
); |
1461 } | 1557 } |
1462 // else: fall back | 1558 // else: fall back |
1463 // it should not happen if the interval format defined is valid | 1559 // it should not happen if the interval format defined is valid |
1464 } | 1560 } |
1465 | 1561 |
1466 | 1562 |
1467 | 1563 |
1468 const UChar | 1564 const UChar |
1469 DateIntervalFormat::fgCalendarFieldToPatternLetter[] = | 1565 DateIntervalFormat::fgCalendarFieldToPatternLetter[] = |
1470 { | 1566 { |
1471 /*GyM*/ CAP_G, LOW_Y, CAP_M, | 1567 /*GyM*/ CAP_G, LOW_Y, CAP_M, |
1472 /*wWd*/ LOW_W, CAP_W, LOW_D, | 1568 /*wWd*/ LOW_W, CAP_W, LOW_D, |
1473 /*DEF*/ CAP_D, CAP_E, CAP_F, | 1569 /*DEF*/ CAP_D, CAP_E, CAP_F, |
1474 /*ahH*/ LOW_A, LOW_H, CAP_H, | 1570 /*ahH*/ LOW_A, LOW_H, CAP_H, |
1475 /*msS*/ LOW_M, LOW_S, CAP_S, // MINUTE, SECOND, MILLISECOND | 1571 /*msS*/ LOW_M, LOW_S, CAP_S, // MINUTE, SECOND, MILLISECOND |
1476 /*z.Y*/ LOW_Z, SPACE, CAP_Y, // ZONE_OFFSET, DST_OFFSET, YEAR_WOY, | 1572 /*z.Y*/ LOW_Z, SPACE, CAP_Y, // ZONE_OFFSET, DST_OFFSET, YEAR_WOY, |
1477 /*eug*/ LOW_E, LOW_U, LOW_G, // DOW_LOCAL, EXTENDED_YEAR, JULIAN_DAY, | 1573 /*eug*/ LOW_E, LOW_U, LOW_G, // DOW_LOCAL, EXTENDED_YEAR, JULIAN_DAY, |
1478 /*A..*/ CAP_A, SPACE, SPACE, // MILLISECONDS_IN_DAY, IS_LEAP_MONTH, FIELD_CO
UNT | 1574 /*A..*/ CAP_A, SPACE, SPACE, // MILLISECONDS_IN_DAY, IS_LEAP_MONTH, FIELD_CO
UNT |
1479 }; | 1575 }; |
1480 | 1576 |
1481 | 1577 |
1482 U_NAMESPACE_END | 1578 U_NAMESPACE_END |
1483 | 1579 |
1484 #endif | 1580 #endif |
OLD | NEW |