| 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 |