• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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