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