1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 *******************************************************************************
5 * Copyright (C) 1997-2015, International Business Machines Corporation and *
6 * others. All Rights Reserved. *
7 *******************************************************************************
8 *
9 * File DATEFMT.CPP
10 *
11 * Modification History:
12 *
13 * Date Name Description
14 * 02/19/97 aliu Converted from java.
15 * 03/31/97 aliu Modified extensively to work with 50 locales.
16 * 04/01/97 aliu Added support for centuries.
17 * 08/12/97 aliu Fixed operator== to use Calendar::equivalentTo.
18 * 07/20/98 stephen Changed ParsePosition initialization
19 ********************************************************************************
20 */
21
22 #include "unicode/utypes.h"
23
24 #if !UCONFIG_NO_FORMATTING
25
26 #include "unicode/ures.h"
27 #include "unicode/datefmt.h"
28 #include "unicode/smpdtfmt.h"
29 #include "unicode/dtptngen.h"
30 #include "unicode/udisplaycontext.h"
31 #include "reldtfmt.h"
32 #include "sharedobject.h"
33 #include "unifiedcache.h"
34 #include "uarrsort.h"
35
36 #include "cstring.h"
37 #include "windtfmt.h"
38
39 #if defined( U_DEBUG_CALSVC ) || defined (U_DEBUG_CAL)
40 #include <stdio.h>
41 #endif
42
43 // *****************************************************************************
44 // class DateFormat
45 // *****************************************************************************
46
47 U_NAMESPACE_BEGIN
48
49 class U_I18N_API DateFmtBestPattern : public SharedObject {
50 public:
51 UnicodeString fPattern;
52
DateFmtBestPattern(const UnicodeString & pattern)53 DateFmtBestPattern(const UnicodeString &pattern)
54 : fPattern(pattern) { }
55 ~DateFmtBestPattern();
56 };
57
~DateFmtBestPattern()58 DateFmtBestPattern::~DateFmtBestPattern() {
59 }
60
61 template<> U_I18N_API
createObject(const void *,UErrorCode & status) const62 const DateFmtBestPattern *LocaleCacheKey<DateFmtBestPattern>::createObject(
63 const void * /*creationContext*/, UErrorCode &status) const {
64 status = U_UNSUPPORTED_ERROR;
65 return NULL;
66 }
67
68 class U_I18N_API DateFmtBestPatternKey : public LocaleCacheKey<DateFmtBestPattern> {
69 private:
70 UnicodeString fSkeleton;
71 protected:
equals(const CacheKeyBase & other) const72 virtual bool equals(const CacheKeyBase &other) const override {
73 if (!LocaleCacheKey<DateFmtBestPattern>::equals(other)) {
74 return false;
75 }
76 // We know that this and other are of same class if we get this far.
77 return operator==(static_cast<const DateFmtBestPatternKey &>(other));
78 }
79 public:
DateFmtBestPatternKey(const Locale & loc,const UnicodeString & skeleton,UErrorCode & status)80 DateFmtBestPatternKey(
81 const Locale &loc,
82 const UnicodeString &skeleton,
83 UErrorCode &status)
84 : LocaleCacheKey<DateFmtBestPattern>(loc),
85 fSkeleton(DateTimePatternGenerator::staticGetSkeleton(skeleton, status)) { }
DateFmtBestPatternKey(const DateFmtBestPatternKey & other)86 DateFmtBestPatternKey(const DateFmtBestPatternKey &other) :
87 LocaleCacheKey<DateFmtBestPattern>(other),
88 fSkeleton(other.fSkeleton) { }
89 virtual ~DateFmtBestPatternKey();
hashCode() const90 virtual int32_t hashCode() const override {
91 return (int32_t)(37u * (uint32_t)LocaleCacheKey<DateFmtBestPattern>::hashCode() + (uint32_t)fSkeleton.hashCode());
92 }
operator ==(const DateFmtBestPatternKey & other) const93 inline bool operator==(const DateFmtBestPatternKey &other) const {
94 return fSkeleton == other.fSkeleton;
95 }
clone() const96 virtual CacheKeyBase *clone() const override {
97 return new DateFmtBestPatternKey(*this);
98 }
createObject(const void *,UErrorCode & status) const99 virtual const DateFmtBestPattern *createObject(
100 const void * /*unused*/, UErrorCode &status) const override {
101 LocalPointer<DateTimePatternGenerator> dtpg(
102 DateTimePatternGenerator::createInstance(fLoc, status));
103 if (U_FAILURE(status)) {
104 return NULL;
105 }
106
107 LocalPointer<DateFmtBestPattern> pattern(
108 new DateFmtBestPattern(
109 dtpg->getBestPattern(fSkeleton, status)),
110 status);
111 if (U_FAILURE(status)) {
112 return NULL;
113 }
114 DateFmtBestPattern *result = pattern.orphan();
115 result->addRef();
116 return result;
117 }
118 };
119
~DateFmtBestPatternKey()120 DateFmtBestPatternKey::~DateFmtBestPatternKey() { }
121
122
DateFormat()123 DateFormat::DateFormat()
124 : fCalendar(0),
125 fNumberFormat(0),
126 fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
127 {
128 }
129
130 //----------------------------------------------------------------------
131
DateFormat(const DateFormat & other)132 DateFormat::DateFormat(const DateFormat& other)
133 : Format(other),
134 fCalendar(0),
135 fNumberFormat(0),
136 fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
137 {
138 *this = other;
139 }
140
141 //----------------------------------------------------------------------
142
operator =(const DateFormat & other)143 DateFormat& DateFormat::operator=(const DateFormat& other)
144 {
145 if (this != &other)
146 {
147 delete fCalendar;
148 delete fNumberFormat;
149 if(other.fCalendar) {
150 fCalendar = other.fCalendar->clone();
151 } else {
152 fCalendar = NULL;
153 }
154 if(other.fNumberFormat) {
155 fNumberFormat = other.fNumberFormat->clone();
156 } else {
157 fNumberFormat = NULL;
158 }
159 fBoolFlags = other.fBoolFlags;
160 fCapitalizationContext = other.fCapitalizationContext;
161 }
162 return *this;
163 }
164
165 //----------------------------------------------------------------------
166
~DateFormat()167 DateFormat::~DateFormat()
168 {
169 delete fCalendar;
170 delete fNumberFormat;
171 }
172
173 //----------------------------------------------------------------------
174
175 bool
operator ==(const Format & other) const176 DateFormat::operator==(const Format& other) const
177 {
178 // This protected comparison operator should only be called by subclasses
179 // which have confirmed that the other object being compared against is
180 // an instance of a sublcass of DateFormat. THIS IS IMPORTANT.
181
182 // Format::operator== guarantees that this cast is safe
183 DateFormat* fmt = (DateFormat*)&other;
184
185 return (this == fmt) ||
186 (Format::operator==(other) &&
187 fCalendar&&(fCalendar->isEquivalentTo(*fmt->fCalendar)) &&
188 (fNumberFormat && *fNumberFormat == *fmt->fNumberFormat) &&
189 (fCapitalizationContext == fmt->fCapitalizationContext) );
190 }
191
192 //----------------------------------------------------------------------
193
194 UnicodeString&
format(const Formattable & obj,UnicodeString & appendTo,FieldPosition & fieldPosition,UErrorCode & status) const195 DateFormat::format(const Formattable& obj,
196 UnicodeString& appendTo,
197 FieldPosition& fieldPosition,
198 UErrorCode& status) const
199 {
200 if (U_FAILURE(status)) return appendTo;
201
202 // if the type of the Formattable is double or long, treat it as if it were a Date
203 UDate date = 0;
204 switch (obj.getType())
205 {
206 case Formattable::kDate:
207 date = obj.getDate();
208 break;
209 case Formattable::kDouble:
210 date = (UDate)obj.getDouble();
211 break;
212 case Formattable::kLong:
213 date = (UDate)obj.getLong();
214 break;
215 default:
216 status = U_ILLEGAL_ARGUMENT_ERROR;
217 return appendTo;
218 }
219
220 // Is this right?
221 //if (fieldPosition.getBeginIndex() == fieldPosition.getEndIndex())
222 // status = U_ILLEGAL_ARGUMENT_ERROR;
223
224 return format(date, appendTo, fieldPosition);
225 }
226
227 //----------------------------------------------------------------------
228
229 UnicodeString&
format(const Formattable & obj,UnicodeString & appendTo,FieldPositionIterator * posIter,UErrorCode & status) const230 DateFormat::format(const Formattable& obj,
231 UnicodeString& appendTo,
232 FieldPositionIterator* posIter,
233 UErrorCode& status) const
234 {
235 if (U_FAILURE(status)) return appendTo;
236
237 // if the type of the Formattable is double or long, treat it as if it were a Date
238 UDate date = 0;
239 switch (obj.getType())
240 {
241 case Formattable::kDate:
242 date = obj.getDate();
243 break;
244 case Formattable::kDouble:
245 date = (UDate)obj.getDouble();
246 break;
247 case Formattable::kLong:
248 date = (UDate)obj.getLong();
249 break;
250 default:
251 status = U_ILLEGAL_ARGUMENT_ERROR;
252 return appendTo;
253 }
254
255 // Is this right?
256 //if (fieldPosition.getBeginIndex() == fieldPosition.getEndIndex())
257 // status = U_ILLEGAL_ARGUMENT_ERROR;
258
259 return format(date, appendTo, posIter, status);
260 }
261
262 //----------------------------------------------------------------------
263
264 // Default implementation for backwards compatibility, subclasses should implement.
265 UnicodeString&
format(Calendar &,UnicodeString & appendTo,FieldPositionIterator *,UErrorCode & status) const266 DateFormat::format(Calendar& /* unused cal */,
267 UnicodeString& appendTo,
268 FieldPositionIterator* /* unused posIter */,
269 UErrorCode& status) const {
270 if (U_SUCCESS(status)) {
271 status = U_UNSUPPORTED_ERROR;
272 }
273 return appendTo;
274 }
275
276 //----------------------------------------------------------------------
277
278 UnicodeString&
format(UDate date,UnicodeString & appendTo,FieldPosition & fieldPosition) const279 DateFormat::format(UDate date, UnicodeString& appendTo, FieldPosition& fieldPosition) const {
280 if (fCalendar != NULL) {
281 // Use a clone of our calendar instance
282 Calendar* calClone = fCalendar->clone();
283 if (calClone != NULL) {
284 UErrorCode ec = U_ZERO_ERROR;
285 calClone->setTime(date, ec);
286 if (U_SUCCESS(ec)) {
287 format(*calClone, appendTo, fieldPosition);
288 }
289 delete calClone;
290 }
291 }
292 return appendTo;
293 }
294
295 //----------------------------------------------------------------------
296
297 UnicodeString&
format(UDate date,UnicodeString & appendTo,FieldPositionIterator * posIter,UErrorCode & status) const298 DateFormat::format(UDate date, UnicodeString& appendTo, FieldPositionIterator* posIter,
299 UErrorCode& status) const {
300 if (fCalendar != NULL) {
301 Calendar* calClone = fCalendar->clone();
302 if (calClone != NULL) {
303 calClone->setTime(date, status);
304 if (U_SUCCESS(status)) {
305 format(*calClone, appendTo, posIter, status);
306 }
307 delete calClone;
308 }
309 }
310 return appendTo;
311 }
312
313 //----------------------------------------------------------------------
314
315 UnicodeString&
format(UDate date,UnicodeString & appendTo) const316 DateFormat::format(UDate date, UnicodeString& appendTo) const
317 {
318 // Note that any error information is just lost. That's okay
319 // for this convenience method.
320 FieldPosition fpos(FieldPosition::DONT_CARE);
321 return format(date, appendTo, fpos);
322 }
323
324 //----------------------------------------------------------------------
325
326 UDate
parse(const UnicodeString & text,ParsePosition & pos) const327 DateFormat::parse(const UnicodeString& text,
328 ParsePosition& pos) const
329 {
330 UDate d = 0; // Error return UDate is 0 (the epoch)
331 if (fCalendar != NULL) {
332 Calendar* calClone = fCalendar->clone();
333 if (calClone != NULL) {
334 int32_t start = pos.getIndex();
335 calClone->clear();
336 parse(text, *calClone, pos);
337 if (pos.getIndex() != start) {
338 UErrorCode ec = U_ZERO_ERROR;
339 d = calClone->getTime(ec);
340 if (U_FAILURE(ec)) {
341 // We arrive here if fCalendar => calClone is non-lenient and
342 // there is an out-of-range field. We don't know which field
343 // was illegal so we set the error index to the start.
344 pos.setIndex(start);
345 pos.setErrorIndex(start);
346 d = 0;
347 }
348 }
349 delete calClone;
350 }
351 }
352 return d;
353 }
354
355 //----------------------------------------------------------------------
356
357 UDate
parse(const UnicodeString & text,UErrorCode & status) const358 DateFormat::parse(const UnicodeString& text,
359 UErrorCode& status) const
360 {
361 if (U_FAILURE(status)) return 0;
362
363 ParsePosition pos(0);
364 UDate result = parse(text, pos);
365 if (pos.getIndex() == 0) {
366 #if defined (U_DEBUG_CAL)
367 fprintf(stderr, "%s:%d - - failed to parse - err index %d\n"
368 , __FILE__, __LINE__, pos.getErrorIndex() );
369 #endif
370 status = U_ILLEGAL_ARGUMENT_ERROR;
371 }
372 return result;
373 }
374
375 //----------------------------------------------------------------------
376
377 void
parseObject(const UnicodeString & source,Formattable & result,ParsePosition & pos) const378 DateFormat::parseObject(const UnicodeString& source,
379 Formattable& result,
380 ParsePosition& pos) const
381 {
382 result.setDate(parse(source, pos));
383 }
384
385 //----------------------------------------------------------------------
386
387 DateFormat* U_EXPORT2
createTimeInstance(DateFormat::EStyle style,const Locale & aLocale)388 DateFormat::createTimeInstance(DateFormat::EStyle style,
389 const Locale& aLocale)
390 {
391 return createDateTimeInstance(kNone, style, aLocale);
392 }
393
394 //----------------------------------------------------------------------
395
396 DateFormat* U_EXPORT2
createDateInstance(DateFormat::EStyle style,const Locale & aLocale)397 DateFormat::createDateInstance(DateFormat::EStyle style,
398 const Locale& aLocale)
399 {
400 return createDateTimeInstance(style, kNone, aLocale);
401 }
402
403 //----------------------------------------------------------------------
404
405 DateFormat* U_EXPORT2
createDateTimeInstance(EStyle dateStyle,EStyle timeStyle,const Locale & aLocale)406 DateFormat::createDateTimeInstance(EStyle dateStyle,
407 EStyle timeStyle,
408 const Locale& aLocale)
409 {
410 if(dateStyle != kNone)
411 {
412 dateStyle = (EStyle) (dateStyle + kDateOffset);
413 }
414 return create(timeStyle, dateStyle, aLocale);
415 }
416
417 //----------------------------------------------------------------------
418
419 DateFormat* U_EXPORT2
createInstance()420 DateFormat::createInstance()
421 {
422 return createDateTimeInstance(kShort, kShort, Locale::getDefault());
423 }
424
425 //----------------------------------------------------------------------
426
427 UnicodeString U_EXPORT2
getBestPattern(const Locale & locale,const UnicodeString & skeleton,UErrorCode & status)428 DateFormat::getBestPattern(
429 const Locale &locale,
430 const UnicodeString &skeleton,
431 UErrorCode &status) {
432 UnifiedCache *cache = UnifiedCache::getInstance(status);
433 if (U_FAILURE(status)) {
434 return UnicodeString();
435 }
436 DateFmtBestPatternKey key(locale, skeleton, status);
437 const DateFmtBestPattern *patternPtr = NULL;
438 cache->get(key, patternPtr, status);
439 if (U_FAILURE(status)) {
440 return UnicodeString();
441 }
442 UnicodeString result(patternPtr->fPattern);
443 patternPtr->removeRef();
444 return result;
445 }
446
447 DateFormat* U_EXPORT2
createInstanceForSkeleton(Calendar * calendarToAdopt,const UnicodeString & skeleton,const Locale & locale,UErrorCode & status)448 DateFormat::createInstanceForSkeleton(
449 Calendar *calendarToAdopt,
450 const UnicodeString& skeleton,
451 const Locale &locale,
452 UErrorCode &status) {
453 LocalPointer<Calendar> calendar(calendarToAdopt);
454 if (U_FAILURE(status)) {
455 return NULL;
456 }
457 if (calendar.isNull()) {
458 status = U_ILLEGAL_ARGUMENT_ERROR;
459 return NULL;
460 }
461 Locale localeWithCalendar = locale;
462 localeWithCalendar.setKeywordValue("calendar", calendar->getType(), status);
463 if (U_FAILURE(status)) {
464 return NULL;
465 }
466 DateFormat *result = createInstanceForSkeleton(skeleton, localeWithCalendar, status);
467 if (U_FAILURE(status)) {
468 return NULL;
469 }
470 result->adoptCalendar(calendar.orphan());
471 return result;
472 }
473
474 DateFormat* U_EXPORT2
createInstanceForSkeleton(const UnicodeString & skeleton,const Locale & locale,UErrorCode & status)475 DateFormat::createInstanceForSkeleton(
476 const UnicodeString& skeleton,
477 const Locale &locale,
478 UErrorCode &status) {
479 if (U_FAILURE(status)) {
480 return NULL;
481 }
482 LocalPointer<DateFormat> df(
483 new SimpleDateFormat(
484 getBestPattern(locale, skeleton, status),
485 locale, status),
486 status);
487 return U_SUCCESS(status) ? df.orphan() : NULL;
488 }
489
490 DateFormat* U_EXPORT2
createInstanceForSkeleton(const UnicodeString & skeleton,UErrorCode & status)491 DateFormat::createInstanceForSkeleton(
492 const UnicodeString& skeleton,
493 UErrorCode &status) {
494 return createInstanceForSkeleton(
495 skeleton, Locale::getDefault(), status);
496 }
497
498 //----------------------------------------------------------------------
499
500 DateFormat* U_EXPORT2
create(EStyle timeStyle,EStyle dateStyle,const Locale & locale)501 DateFormat::create(EStyle timeStyle, EStyle dateStyle, const Locale& locale)
502 {
503 UErrorCode status = U_ZERO_ERROR;
504 #if U_PLATFORM_USES_ONLY_WIN32_API
505 char buffer[8];
506 int32_t count = locale.getKeywordValue("compat", buffer, sizeof(buffer), status);
507
508 // if the locale has "@compat=host", create a host-specific DateFormat...
509 if (count > 0 && uprv_strcmp(buffer, "host") == 0) {
510 Win32DateFormat *f = new Win32DateFormat(timeStyle, dateStyle, locale, status);
511
512 if (U_SUCCESS(status)) {
513 return f;
514 }
515
516 delete f;
517 }
518 #endif
519
520 // is it relative?
521 if(/*((timeStyle!=UDAT_NONE)&&(timeStyle & UDAT_RELATIVE)) || */((dateStyle!=kNone)&&((dateStyle-kDateOffset) & UDAT_RELATIVE))) {
522 RelativeDateFormat *r = new RelativeDateFormat((UDateFormatStyle)timeStyle, (UDateFormatStyle)(dateStyle-kDateOffset), locale, status);
523 if(U_SUCCESS(status)) return r;
524 delete r;
525 status = U_ZERO_ERROR;
526 }
527
528 // Try to create a SimpleDateFormat of the desired style.
529 SimpleDateFormat *f = new SimpleDateFormat(timeStyle, dateStyle, locale, status);
530 if (U_SUCCESS(status)) return f;
531 delete f;
532
533 // If that fails, try to create a format using the default pattern and
534 // the DateFormatSymbols for this locale.
535 status = U_ZERO_ERROR;
536 f = new SimpleDateFormat(locale, status);
537 if (U_SUCCESS(status)) return f;
538 delete f;
539
540 // This should never really happen, because the preceding constructor
541 // should always succeed. If the resource data is unavailable, a last
542 // resort object should be returned.
543 return 0;
544 }
545
546 //----------------------------------------------------------------------
547
548 const Locale* U_EXPORT2
getAvailableLocales(int32_t & count)549 DateFormat::getAvailableLocales(int32_t& count)
550 {
551 // Get the list of installed locales.
552 // Even if root has the correct date format for this locale,
553 // it's still a valid locale (we don't worry about data fallbacks).
554 return Locale::getAvailableLocales(count);
555 }
556
557 //----------------------------------------------------------------------
558
559 void
adoptCalendar(Calendar * newCalendar)560 DateFormat::adoptCalendar(Calendar* newCalendar)
561 {
562 delete fCalendar;
563 fCalendar = newCalendar;
564 }
565
566 //----------------------------------------------------------------------
567 void
setCalendar(const Calendar & newCalendar)568 DateFormat::setCalendar(const Calendar& newCalendar)
569 {
570 Calendar* newCalClone = newCalendar.clone();
571 if (newCalClone != NULL) {
572 adoptCalendar(newCalClone);
573 }
574 }
575
576 //----------------------------------------------------------------------
577
578 const Calendar*
getCalendar() const579 DateFormat::getCalendar() const
580 {
581 return fCalendar;
582 }
583
584 //----------------------------------------------------------------------
585
586 void
adoptNumberFormat(NumberFormat * newNumberFormat)587 DateFormat::adoptNumberFormat(NumberFormat* newNumberFormat)
588 {
589 delete fNumberFormat;
590 fNumberFormat = newNumberFormat;
591 newNumberFormat->setParseIntegerOnly(TRUE);
592 newNumberFormat->setGroupingUsed(FALSE);
593 }
594 //----------------------------------------------------------------------
595
596 void
setNumberFormat(const NumberFormat & newNumberFormat)597 DateFormat::setNumberFormat(const NumberFormat& newNumberFormat)
598 {
599 NumberFormat* newNumFmtClone = newNumberFormat.clone();
600 if (newNumFmtClone != NULL) {
601 adoptNumberFormat(newNumFmtClone);
602 }
603 }
604
605 //----------------------------------------------------------------------
606
607 const NumberFormat*
getNumberFormat() const608 DateFormat::getNumberFormat() const
609 {
610 return fNumberFormat;
611 }
612
613 //----------------------------------------------------------------------
614
615 void
adoptTimeZone(TimeZone * zone)616 DateFormat::adoptTimeZone(TimeZone* zone)
617 {
618 if (fCalendar != NULL) {
619 fCalendar->adoptTimeZone(zone);
620 }
621 }
622 //----------------------------------------------------------------------
623
624 void
setTimeZone(const TimeZone & zone)625 DateFormat::setTimeZone(const TimeZone& zone)
626 {
627 if (fCalendar != NULL) {
628 fCalendar->setTimeZone(zone);
629 }
630 }
631
632 //----------------------------------------------------------------------
633
634 const TimeZone&
getTimeZone() const635 DateFormat::getTimeZone() const
636 {
637 if (fCalendar != NULL) {
638 return fCalendar->getTimeZone();
639 }
640 // If calendar doesn't exists, create default timezone.
641 // fCalendar is rarely null
642 return *(TimeZone::createDefault());
643 }
644
645 //----------------------------------------------------------------------
646
647 void
setLenient(UBool lenient)648 DateFormat::setLenient(UBool lenient)
649 {
650 if (fCalendar != NULL) {
651 fCalendar->setLenient(lenient);
652 }
653 UErrorCode status = U_ZERO_ERROR;
654 setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, lenient, status);
655 setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, lenient, status);
656 }
657
658 //----------------------------------------------------------------------
659
660 UBool
isLenient() const661 DateFormat::isLenient() const
662 {
663 UBool lenient = TRUE;
664 if (fCalendar != NULL) {
665 lenient = fCalendar->isLenient();
666 }
667 UErrorCode status = U_ZERO_ERROR;
668 return lenient
669 && getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status)
670 && getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status);
671 }
672
673 void
setCalendarLenient(UBool lenient)674 DateFormat::setCalendarLenient(UBool lenient)
675 {
676 if (fCalendar != NULL) {
677 fCalendar->setLenient(lenient);
678 }
679 }
680
681 //----------------------------------------------------------------------
682
683 UBool
isCalendarLenient() const684 DateFormat::isCalendarLenient() const
685 {
686 if (fCalendar != NULL) {
687 return fCalendar->isLenient();
688 }
689 // fCalendar is rarely null
690 return FALSE;
691 }
692
693
694 //----------------------------------------------------------------------
695
696
setContext(UDisplayContext value,UErrorCode & status)697 void DateFormat::setContext(UDisplayContext value, UErrorCode& status)
698 {
699 if (U_FAILURE(status))
700 return;
701 if ( (UDisplayContextType)((uint32_t)value >> 8) == UDISPCTX_TYPE_CAPITALIZATION ) {
702 fCapitalizationContext = value;
703 } else {
704 status = U_ILLEGAL_ARGUMENT_ERROR;
705 }
706 }
707
708
709 //----------------------------------------------------------------------
710
711
getContext(UDisplayContextType type,UErrorCode & status) const712 UDisplayContext DateFormat::getContext(UDisplayContextType type, UErrorCode& status) const
713 {
714 if (U_FAILURE(status))
715 return (UDisplayContext)0;
716 if (type != UDISPCTX_TYPE_CAPITALIZATION) {
717 status = U_ILLEGAL_ARGUMENT_ERROR;
718 return (UDisplayContext)0;
719 }
720 return fCapitalizationContext;
721 }
722
723
724 //----------------------------------------------------------------------
725
726
727 DateFormat&
setBooleanAttribute(UDateFormatBooleanAttribute attr,UBool newValue,UErrorCode & status)728 DateFormat::setBooleanAttribute(UDateFormatBooleanAttribute attr,
729 UBool newValue,
730 UErrorCode &status) {
731 if(!fBoolFlags.isValidValue(newValue)) {
732 status = U_ILLEGAL_ARGUMENT_ERROR;
733 } else {
734 fBoolFlags.set(attr, newValue);
735 }
736
737 return *this;
738 }
739
740 //----------------------------------------------------------------------
741
742 UBool
getBooleanAttribute(UDateFormatBooleanAttribute attr,UErrorCode &) const743 DateFormat::getBooleanAttribute(UDateFormatBooleanAttribute attr, UErrorCode &/*status*/) const {
744
745 return static_cast<UBool>(fBoolFlags.get(attr));
746 }
747
748 U_NAMESPACE_END
749
750 #endif /* #if !UCONFIG_NO_FORMATTING */
751
752 //eof
753