2 ******************************************************************************
3 * Copyright (C) 2014, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ******************************************************************************
8 ******************************************************************************
11 #include "unicode/reldatefmt.h"
13 #if !UCONFIG_NO_FORMATTING && !UCONFIG_NO_BREAK_ITERATION
15 #include "unicode/localpointer.h"
16 #include "quantityformatter.h"
17 #include "unicode/plurrule.h"
18 #include "unicode/msgfmt.h"
19 #include "unicode/decimfmt.h"
20 #include "unicode/numfmt.h"
21 #include "unicode/brkiter.h"
23 #include "unicode/ures.h"
30 #include "sharedbreakiterator.h"
31 #include "sharedpluralrules.h"
32 #include "sharednumberformat.h"
33 #include "unifiedcache.h"
35 // Copied from uscript_props.cpp
37 static UMutex gBrkIterMutex
= U_MUTEX_INITIALIZER
;
41 // RelativeDateTimeFormatter specific data for a single locale
42 class RelativeDateTimeCacheData
: public SharedObject
{
44 RelativeDateTimeCacheData() : combinedDateAndTime(NULL
) { }
45 virtual ~RelativeDateTimeCacheData();
47 // no numbers: e.g Next Tuesday; Yesterday; etc.
48 UnicodeString absoluteUnits
[UDAT_STYLE_COUNT
][UDAT_ABSOLUTE_UNIT_COUNT
][UDAT_DIRECTION_COUNT
];
50 // has numbers: e.g Next Tuesday; Yesterday; etc. For second index, 0
51 // means past e.g 5 days ago; 1 means future e.g in 5 days.
52 QuantityFormatter relativeUnits
[UDAT_STYLE_COUNT
][UDAT_RELATIVE_UNIT_COUNT
][2];
54 void adoptCombinedDateAndTime(MessageFormat
*mfToAdopt
) {
55 delete combinedDateAndTime
;
56 combinedDateAndTime
= mfToAdopt
;
58 const MessageFormat
*getCombinedDateAndTime() const {
59 return combinedDateAndTime
;
62 MessageFormat
*combinedDateAndTime
;
63 RelativeDateTimeCacheData(const RelativeDateTimeCacheData
&other
);
64 RelativeDateTimeCacheData
& operator=(
65 const RelativeDateTimeCacheData
&other
);
68 RelativeDateTimeCacheData::~RelativeDateTimeCacheData() {
69 delete combinedDateAndTime
;
72 static UBool
getStringWithFallback(
73 const UResourceBundle
*resource
,
75 UnicodeString
&result
,
78 const UChar
*resStr
= ures_getStringByKeyWithFallback(
79 resource
, key
, &len
, &status
);
80 if (U_FAILURE(status
)) {
83 result
.setTo(TRUE
, resStr
, len
);
87 static UBool
getOptionalStringWithFallback(
88 const UResourceBundle
*resource
,
90 UnicodeString
&result
,
92 if (U_FAILURE(status
)) {
96 const UChar
*resStr
= ures_getStringByKey(
97 resource
, key
, &len
, &status
);
98 if (status
== U_MISSING_RESOURCE_ERROR
) {
100 status
= U_ZERO_ERROR
;
103 if (U_FAILURE(status
)) {
106 result
.setTo(TRUE
, resStr
, len
);
110 static UBool
getString(
111 const UResourceBundle
*resource
,
112 UnicodeString
&result
,
113 UErrorCode
&status
) {
115 const UChar
*resStr
= ures_getString(resource
, &len
, &status
);
116 if (U_FAILURE(status
)) {
119 result
.setTo(TRUE
, resStr
, len
);
123 static UBool
getStringByIndex(
124 const UResourceBundle
*resource
,
126 UnicodeString
&result
,
127 UErrorCode
&status
) {
129 const UChar
*resStr
= ures_getStringByIndex(
130 resource
, idx
, &len
, &status
);
131 if (U_FAILURE(status
)) {
134 result
.setTo(TRUE
, resStr
, len
);
138 static void initAbsoluteUnit(
139 const UResourceBundle
*resource
,
140 const UnicodeString
&unitName
,
141 UnicodeString
*absoluteUnit
,
142 UErrorCode
&status
) {
143 getStringWithFallback(
146 absoluteUnit
[UDAT_DIRECTION_LAST
],
148 getStringWithFallback(
151 absoluteUnit
[UDAT_DIRECTION_THIS
],
153 getStringWithFallback(
156 absoluteUnit
[UDAT_DIRECTION_NEXT
],
158 getOptionalStringWithFallback(
161 absoluteUnit
[UDAT_DIRECTION_LAST_2
],
163 getOptionalStringWithFallback(
166 absoluteUnit
[UDAT_DIRECTION_NEXT_2
],
168 absoluteUnit
[UDAT_DIRECTION_PLAIN
] = unitName
;
171 static void initQuantityFormatter(
172 const UResourceBundle
*resource
,
173 QuantityFormatter
&formatter
,
174 UErrorCode
&status
) {
175 if (U_FAILURE(status
)) {
178 int32_t size
= ures_getSize(resource
);
179 for (int32_t i
= 0; i
< size
; ++i
) {
180 LocalUResourceBundlePointer
pluralBundle(
181 ures_getByIndex(resource
, i
, NULL
, &status
));
182 if (U_FAILURE(status
)) {
185 UnicodeString rawPattern
;
186 if (!getString(pluralBundle
.getAlias(), rawPattern
, status
)) {
190 ures_getKey(pluralBundle
.getAlias()),
198 static void initRelativeUnit(
199 const UResourceBundle
*resource
,
200 QuantityFormatter
*relativeUnit
,
201 UErrorCode
&status
) {
202 LocalUResourceBundlePointer
topLevel(
203 ures_getByKeyWithFallback(
204 resource
, "relativeTime", NULL
, &status
));
205 if (U_FAILURE(status
)) {
208 LocalUResourceBundlePointer
futureBundle(ures_getByKeyWithFallback(
209 topLevel
.getAlias(), "future", NULL
, &status
));
210 if (U_FAILURE(status
)) {
213 initQuantityFormatter(
214 futureBundle
.getAlias(),
217 LocalUResourceBundlePointer
pastBundle(ures_getByKeyWithFallback(
218 topLevel
.getAlias(), "past", NULL
, &status
));
219 if (U_FAILURE(status
)) {
222 initQuantityFormatter(
223 pastBundle
.getAlias(),
228 static void initRelativeUnit(
229 const UResourceBundle
*resource
,
231 QuantityFormatter
*relativeUnit
,
232 UErrorCode
&status
) {
233 LocalUResourceBundlePointer
topLevel(
234 ures_getByKeyWithFallback(resource
, path
, NULL
, &status
));
235 if (U_FAILURE(status
)) {
238 initRelativeUnit(topLevel
.getAlias(), relativeUnit
, status
);
241 static void addTimeUnit(
242 const UResourceBundle
*resource
,
244 QuantityFormatter
*relativeUnit
,
245 UnicodeString
*absoluteUnit
,
246 UErrorCode
&status
) {
247 LocalUResourceBundlePointer
topLevel(
248 ures_getByKeyWithFallback(resource
, path
, NULL
, &status
));
249 if (U_FAILURE(status
)) {
252 initRelativeUnit(topLevel
.getAlias(), relativeUnit
, status
);
253 UnicodeString unitName
;
254 if (!getStringWithFallback(topLevel
.getAlias(), "dn", unitName
, status
)) {
257 // TODO(Travis Keep): This is a hack to get around CLDR bug 6818.
258 const char *localeId
= ures_getLocaleByType(
259 topLevel
.getAlias(), ULOC_ACTUAL_LOCALE
, &status
);
260 if (U_FAILURE(status
)) {
263 Locale
locale(localeId
);
264 if (uprv_strcmp("en", locale
.getLanguage()) == 0) {
268 ures_getByKeyWithFallback(
269 topLevel
.getAlias(), "relative", topLevel
.getAlias(), &status
);
270 if (U_FAILURE(status
)) {
280 static void readDaysOfWeek(
281 const UResourceBundle
*resource
,
283 UnicodeString
*daysOfWeek
,
284 UErrorCode
&status
) {
285 LocalUResourceBundlePointer
topLevel(
286 ures_getByKeyWithFallback(resource
, path
, NULL
, &status
));
287 if (U_FAILURE(status
)) {
290 int32_t size
= ures_getSize(topLevel
.getAlias());
292 status
= U_INTERNAL_PROGRAM_ERROR
;
295 for (int32_t i
= 0; i
< size
; ++i
) {
296 if (!getStringByIndex(topLevel
.getAlias(), i
, daysOfWeek
[i
], status
)) {
302 static void addWeekDay(
303 const UResourceBundle
*resource
,
305 const UnicodeString
*daysOfWeek
,
306 UDateAbsoluteUnit absoluteUnit
,
307 UnicodeString absoluteUnits
[][UDAT_DIRECTION_COUNT
],
308 UErrorCode
&status
) {
309 LocalUResourceBundlePointer
topLevel(
310 ures_getByKeyWithFallback(resource
, path
, NULL
, &status
));
311 if (U_FAILURE(status
)) {
316 daysOfWeek
[absoluteUnit
- UDAT_ABSOLUTE_SUNDAY
],
317 absoluteUnits
[absoluteUnit
],
321 static void addTimeUnits(
322 const UResourceBundle
*resource
,
323 const char *path
, const char *pathShort
, const char *pathNarrow
,
324 UDateRelativeUnit relativeUnit
,
325 UDateAbsoluteUnit absoluteUnit
,
326 RelativeDateTimeCacheData
&cacheData
,
327 UErrorCode
&status
) {
331 cacheData
.relativeUnits
[UDAT_STYLE_LONG
][relativeUnit
],
332 cacheData
.absoluteUnits
[UDAT_STYLE_LONG
][absoluteUnit
],
337 cacheData
.relativeUnits
[UDAT_STYLE_SHORT
][relativeUnit
],
338 cacheData
.absoluteUnits
[UDAT_STYLE_SHORT
][absoluteUnit
],
340 if (U_FAILURE(status
)) {
346 cacheData
.relativeUnits
[UDAT_STYLE_NARROW
][relativeUnit
],
347 cacheData
.absoluteUnits
[UDAT_STYLE_NARROW
][absoluteUnit
],
349 if (status
== U_MISSING_RESOURCE_ERROR
) {
350 // retry addTimeUnit for UDAT_STYLE_NARROW using pathShort
351 status
= U_ZERO_ERROR
;
355 cacheData
.relativeUnits
[UDAT_STYLE_NARROW
][relativeUnit
],
356 cacheData
.absoluteUnits
[UDAT_STYLE_NARROW
][absoluteUnit
],
361 static void initRelativeUnits(
362 const UResourceBundle
*resource
,
363 const char *path
, const char *pathShort
, const char *pathNarrow
,
364 UDateRelativeUnit relativeUnit
,
365 QuantityFormatter relativeUnits
[][UDAT_RELATIVE_UNIT_COUNT
][2],
366 UErrorCode
&status
) {
370 relativeUnits
[UDAT_STYLE_LONG
][relativeUnit
],
375 relativeUnits
[UDAT_STYLE_SHORT
][relativeUnit
],
377 if (U_FAILURE(status
)) {
383 relativeUnits
[UDAT_STYLE_NARROW
][relativeUnit
],
385 if (status
== U_MISSING_RESOURCE_ERROR
) {
386 // retry initRelativeUnit for UDAT_STYLE_NARROW using pathShort
387 status
= U_ZERO_ERROR
;
391 relativeUnits
[UDAT_STYLE_NARROW
][relativeUnit
],
396 static void addWeekDays(
397 const UResourceBundle
*resource
,
398 const char *path
, const char *pathShort
, const char *pathNarrow
,
399 const UnicodeString daysOfWeek
[][7],
400 UDateAbsoluteUnit absoluteUnit
,
401 UnicodeString absoluteUnits
[][UDAT_ABSOLUTE_UNIT_COUNT
][UDAT_DIRECTION_COUNT
],
402 UErrorCode
&status
) {
406 daysOfWeek
[UDAT_STYLE_LONG
],
408 absoluteUnits
[UDAT_STYLE_LONG
],
413 daysOfWeek
[UDAT_STYLE_SHORT
],
415 absoluteUnits
[UDAT_STYLE_SHORT
],
417 if (U_FAILURE(status
)) {
423 daysOfWeek
[UDAT_STYLE_NARROW
],
425 absoluteUnits
[UDAT_STYLE_NARROW
],
427 if (status
== U_MISSING_RESOURCE_ERROR
) {
428 // retry addWeekDay for UDAT_STYLE_NARROW using pathShort
429 status
= U_ZERO_ERROR
;
433 daysOfWeek
[UDAT_STYLE_NARROW
],
435 absoluteUnits
[UDAT_STYLE_NARROW
],
440 static UBool
loadUnitData(
441 const UResourceBundle
*resource
,
442 RelativeDateTimeCacheData
&cacheData
,
443 UErrorCode
&status
) {
446 "fields/day", "fields/day-short", "fields/day-narrow",
453 "fields/week", "fields/week-short", "fields/week-narrow",
460 "fields/month", "fields/month-short", "fields/month-narrow",
461 UDAT_RELATIVE_MONTHS
,
467 "fields/year", "fields/year-short", "fields/year-narrow",
474 "fields/second", "fields/second-short", "fields/second-narrow",
475 UDAT_RELATIVE_SECONDS
,
476 cacheData
.relativeUnits
,
480 "fields/minute", "fields/minute-short", "fields/minute-narrow",
481 UDAT_RELATIVE_MINUTES
,
482 cacheData
.relativeUnits
,
486 "fields/hour", "fields/hour-short", "fields/hour-narrow",
488 cacheData
.relativeUnits
,
490 getStringWithFallback(
492 "fields/second/relative/0",
493 cacheData
.absoluteUnits
[UDAT_STYLE_LONG
][UDAT_ABSOLUTE_NOW
][UDAT_DIRECTION_PLAIN
],
495 getStringWithFallback(
497 "fields/second-short/relative/0",
498 cacheData
.absoluteUnits
[UDAT_STYLE_SHORT
][UDAT_ABSOLUTE_NOW
][UDAT_DIRECTION_PLAIN
],
500 getStringWithFallback(
502 "fields/second-narrow/relative/0",
503 cacheData
.absoluteUnits
[UDAT_STYLE_NARROW
][UDAT_ABSOLUTE_NOW
][UDAT_DIRECTION_PLAIN
],
505 UnicodeString daysOfWeek
[UDAT_STYLE_COUNT
][7];
508 "calendar/gregorian/dayNames/stand-alone/wide",
509 daysOfWeek
[UDAT_STYLE_LONG
],
513 "calendar/gregorian/dayNames/stand-alone/short",
514 daysOfWeek
[UDAT_STYLE_SHORT
],
518 "calendar/gregorian/dayNames/stand-alone/narrow",
519 daysOfWeek
[UDAT_STYLE_NARROW
],
523 "fields/mon/relative",
524 "fields/mon-short/relative",
525 "fields/mon-narrow/relative",
527 UDAT_ABSOLUTE_MONDAY
,
528 cacheData
.absoluteUnits
,
532 "fields/tue/relative",
533 "fields/tue-short/relative",
534 "fields/tue-narrow/relative",
536 UDAT_ABSOLUTE_TUESDAY
,
537 cacheData
.absoluteUnits
,
541 "fields/wed/relative",
542 "fields/wed-short/relative",
543 "fields/wed-narrow/relative",
545 UDAT_ABSOLUTE_WEDNESDAY
,
546 cacheData
.absoluteUnits
,
550 "fields/thu/relative",
551 "fields/thu-short/relative",
552 "fields/thu-narrow/relative",
554 UDAT_ABSOLUTE_THURSDAY
,
555 cacheData
.absoluteUnits
,
559 "fields/fri/relative",
560 "fields/fri-short/relative",
561 "fields/fri-narrow/relative",
563 UDAT_ABSOLUTE_FRIDAY
,
564 cacheData
.absoluteUnits
,
568 "fields/sat/relative",
569 "fields/sat-short/relative",
570 "fields/sat-narrow/relative",
572 UDAT_ABSOLUTE_SATURDAY
,
573 cacheData
.absoluteUnits
,
577 "fields/sun/relative",
578 "fields/sun-short/relative",
579 "fields/sun-narrow/relative",
581 UDAT_ABSOLUTE_SUNDAY
,
582 cacheData
.absoluteUnits
,
584 return U_SUCCESS(status
);
587 static UBool
getDateTimePattern(
588 const UResourceBundle
*resource
,
589 UnicodeString
&result
,
590 UErrorCode
&status
) {
591 UnicodeString defaultCalendarName
;
592 if (!getStringWithFallback(
599 CharString pathBuffer
;
600 pathBuffer
.append("calendar/", status
)
601 .appendInvariantChars(defaultCalendarName
, status
)
602 .append("/DateTimePatterns", status
);
603 LocalUResourceBundlePointer
topLevel(
604 ures_getByKeyWithFallback(
605 resource
, pathBuffer
.data(), NULL
, &status
));
606 if (U_FAILURE(status
)) {
609 int32_t size
= ures_getSize(topLevel
.getAlias());
611 // Oops, size is to small to access the index that we want, fallback
612 // to a hard-coded value.
613 result
= UNICODE_STRING_SIMPLE("{1} {0}");
616 return getStringByIndex(topLevel
.getAlias(), 8, result
, status
);
619 template<> U_I18N_API
620 const RelativeDateTimeCacheData
*LocaleCacheKey
<RelativeDateTimeCacheData
>::createObject(const void * /*unused*/, UErrorCode
&status
) const {
621 const char *localeId
= fLoc
.getName();
622 LocalUResourceBundlePointer
topLevel(ures_open(NULL
, localeId
, &status
));
623 if (U_FAILURE(status
)) {
626 LocalPointer
<RelativeDateTimeCacheData
> result(
627 new RelativeDateTimeCacheData());
628 if (result
.isNull()) {
629 status
= U_MEMORY_ALLOCATION_ERROR
;
638 UnicodeString dateTimePattern
;
639 if (!getDateTimePattern(topLevel
.getAlias(), dateTimePattern
, status
)) {
642 result
->adoptCombinedDateAndTime(
643 new MessageFormat(dateTimePattern
, localeId
, status
));
644 if (U_FAILURE(status
)) {
648 return result
.orphan();
651 RelativeDateTimeFormatter::RelativeDateTimeFormatter(UErrorCode
& status
) :
655 fStyle(UDAT_STYLE_LONG
),
656 fContext(UDISPCTX_CAPITALIZATION_NONE
),
657 fOptBreakIterator(NULL
) {
658 init(NULL
, NULL
, status
);
661 RelativeDateTimeFormatter::RelativeDateTimeFormatter(
662 const Locale
& locale
, UErrorCode
& status
) :
666 fStyle(UDAT_STYLE_LONG
),
667 fContext(UDISPCTX_CAPITALIZATION_NONE
),
668 fOptBreakIterator(NULL
),
670 init(NULL
, NULL
, status
);
673 RelativeDateTimeFormatter::RelativeDateTimeFormatter(
674 const Locale
& locale
, NumberFormat
*nfToAdopt
, UErrorCode
& status
) :
678 fStyle(UDAT_STYLE_LONG
),
679 fContext(UDISPCTX_CAPITALIZATION_NONE
),
680 fOptBreakIterator(NULL
),
682 init(nfToAdopt
, NULL
, status
);
685 RelativeDateTimeFormatter::RelativeDateTimeFormatter(
686 const Locale
& locale
,
687 NumberFormat
*nfToAdopt
,
688 UDateRelativeDateTimeFormatterStyle styl
,
689 UDisplayContext capitalizationContext
,
690 UErrorCode
& status
) :
695 fContext(capitalizationContext
),
696 fOptBreakIterator(NULL
),
698 if (U_FAILURE(status
)) {
701 if ((capitalizationContext
>> 8) != UDISPCTX_TYPE_CAPITALIZATION
) {
702 status
= U_ILLEGAL_ARGUMENT_ERROR
;
705 if (capitalizationContext
== UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE
) {
706 BreakIterator
*bi
= BreakIterator::createSentenceInstance(locale
, status
);
707 if (U_FAILURE(status
)) {
710 init(nfToAdopt
, bi
, status
);
712 init(nfToAdopt
, NULL
, status
);
716 RelativeDateTimeFormatter::RelativeDateTimeFormatter(
717 const RelativeDateTimeFormatter
& other
)
719 fCache(other
.fCache
),
720 fNumberFormat(other
.fNumberFormat
),
721 fPluralRules(other
.fPluralRules
),
722 fStyle(other
.fStyle
),
723 fContext(other
.fContext
),
724 fOptBreakIterator(other
.fOptBreakIterator
),
725 fLocale(other
.fLocale
) {
727 fNumberFormat
->addRef();
728 fPluralRules
->addRef();
729 if (fOptBreakIterator
!= NULL
) {
730 fOptBreakIterator
->addRef();
734 RelativeDateTimeFormatter
& RelativeDateTimeFormatter::operator=(
735 const RelativeDateTimeFormatter
& other
) {
736 if (this != &other
) {
737 SharedObject::copyPtr(other
.fCache
, fCache
);
738 SharedObject::copyPtr(other
.fNumberFormat
, fNumberFormat
);
739 SharedObject::copyPtr(other
.fPluralRules
, fPluralRules
);
740 SharedObject::copyPtr(other
.fOptBreakIterator
, fOptBreakIterator
);
741 fStyle
= other
.fStyle
;
742 fContext
= other
.fContext
;
743 fLocale
= other
.fLocale
;
748 RelativeDateTimeFormatter::~RelativeDateTimeFormatter() {
749 if (fCache
!= NULL
) {
752 if (fNumberFormat
!= NULL
) {
753 fNumberFormat
->removeRef();
755 if (fPluralRules
!= NULL
) {
756 fPluralRules
->removeRef();
758 if (fOptBreakIterator
!= NULL
) {
759 fOptBreakIterator
->removeRef();
763 const NumberFormat
& RelativeDateTimeFormatter::getNumberFormat() const {
764 return **fNumberFormat
;
767 UDisplayContext
RelativeDateTimeFormatter::getCapitalizationContext() const {
771 UDateRelativeDateTimeFormatterStyle
RelativeDateTimeFormatter::getFormatStyle() const {
775 UnicodeString
& RelativeDateTimeFormatter::format(
776 double quantity
, UDateDirection direction
, UDateRelativeUnit unit
,
777 UnicodeString
& appendTo
, UErrorCode
& status
) const {
778 if (U_FAILURE(status
)) {
781 if (direction
!= UDAT_DIRECTION_LAST
&& direction
!= UDAT_DIRECTION_NEXT
) {
782 status
= U_ILLEGAL_ARGUMENT_ERROR
;
785 int32_t bFuture
= direction
== UDAT_DIRECTION_NEXT
? 1 : 0;
786 FieldPosition
pos(FieldPosition::DONT_CARE
);
787 if (fOptBreakIterator
== NULL
) {
788 return fCache
->relativeUnits
[fStyle
][unit
][bFuture
].format(
796 UnicodeString result
;
797 fCache
->relativeUnits
[fStyle
][unit
][bFuture
].format(
804 adjustForContext(result
);
805 return appendTo
.append(result
);
808 UnicodeString
& RelativeDateTimeFormatter::format(
809 UDateDirection direction
, UDateAbsoluteUnit unit
,
810 UnicodeString
& appendTo
, UErrorCode
& status
) const {
811 if (U_FAILURE(status
)) {
814 if (unit
== UDAT_ABSOLUTE_NOW
&& direction
!= UDAT_DIRECTION_PLAIN
) {
815 status
= U_ILLEGAL_ARGUMENT_ERROR
;
818 if (fOptBreakIterator
== NULL
) {
819 return appendTo
.append(fCache
->absoluteUnits
[fStyle
][unit
][direction
]);
821 UnicodeString
result(fCache
->absoluteUnits
[fStyle
][unit
][direction
]);
822 adjustForContext(result
);
823 return appendTo
.append(result
);
826 UnicodeString
& RelativeDateTimeFormatter::combineDateAndTime(
827 const UnicodeString
& relativeDateString
, const UnicodeString
& timeString
,
828 UnicodeString
& appendTo
, UErrorCode
& status
) const {
829 Formattable args
[2] = {timeString
, relativeDateString
};
830 FieldPosition
fpos(0);
831 return fCache
->getCombinedDateAndTime()->format(
832 args
, 2, appendTo
, fpos
, status
);
835 void RelativeDateTimeFormatter::adjustForContext(UnicodeString
&str
) const {
836 if (fOptBreakIterator
== NULL
837 || str
.length() == 0 || !u_islower(str
.char32At(0))) {
841 // Must guarantee that one thread at a time accesses the shared break
843 Mutex
lock(&gBrkIterMutex
);
845 fOptBreakIterator
->get(),
847 U_TITLECASE_NO_LOWERCASE
| U_TITLECASE_NO_BREAK_ADJUSTMENT
);
850 void RelativeDateTimeFormatter::init(
851 NumberFormat
*nfToAdopt
,
852 BreakIterator
*biToAdopt
,
853 UErrorCode
&status
) {
854 LocalPointer
<NumberFormat
> nf(nfToAdopt
);
855 LocalPointer
<BreakIterator
> bi(biToAdopt
);
856 UnifiedCache::getByLocale(fLocale
, fCache
, status
);
857 if (U_FAILURE(status
)) {
860 const SharedPluralRules
*pr
= PluralRules::createSharedInstance(
861 fLocale
, UPLURAL_TYPE_CARDINAL
, status
);
862 if (U_FAILURE(status
)) {
865 SharedObject::copyPtr(pr
, fPluralRules
);
868 const SharedNumberFormat
*shared
= NumberFormat::createSharedInstance(
869 fLocale
, UNUM_DECIMAL
, status
);
870 if (U_FAILURE(status
)) {
873 SharedObject::copyPtr(shared
, fNumberFormat
);
876 SharedNumberFormat
*shared
= new SharedNumberFormat(nf
.getAlias());
877 if (shared
== NULL
) {
878 status
= U_MEMORY_ALLOCATION_ERROR
;
882 SharedObject::copyPtr(shared
, fNumberFormat
);
885 SharedObject::clearPtr(fOptBreakIterator
);
887 SharedBreakIterator
*shared
= new SharedBreakIterator(bi
.getAlias());
888 if (shared
== NULL
) {
889 status
= U_MEMORY_ALLOCATION_ERROR
;
893 SharedObject::copyPtr(shared
, fOptBreakIterator
);
900 #endif /* !UCONFIG_NO_FORMATTING */