Home | History | Annotate | Download | only in i18n
      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 
     53     DateFmtBestPattern(const UnicodeString &pattern)
     54             : fPattern(pattern) { }
     55     ~DateFmtBestPattern();
     56 };
     57 
     58 DateFmtBestPattern::~DateFmtBestPattern() {
     59 }
     60 
     61 template<> U_I18N_API
     62 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:
     72     DateFmtBestPatternKey(
     73         const Locale &loc,
     74         const UnicodeString &skeleton,
     75         UErrorCode &status)
     76             : LocaleCacheKey<DateFmtBestPattern>(loc),
     77               fSkeleton(DateTimePatternGenerator::staticGetSkeleton(skeleton, status)) { }
     78     DateFmtBestPatternKey(const DateFmtBestPatternKey &other) :
     79             LocaleCacheKey<DateFmtBestPattern>(other),
     80             fSkeleton(other.fSkeleton) { }
     81     virtual ~DateFmtBestPatternKey();
     82     virtual int32_t hashCode() const {
     83         return (int32_t)(37u * (uint32_t)LocaleCacheKey<DateFmtBestPattern>::hashCode() + (uint32_t)fSkeleton.hashCode());
     84     }
     85     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     }
     98     virtual CacheKeyBase *clone() const {
     99         return new DateFmtBestPatternKey(*this);
    100     }
    101     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 
    122 DateFmtBestPatternKey::~DateFmtBestPatternKey() { }
    123 
    124 
    125 DateFormat::DateFormat()
    126 :   fCalendar(0),
    127     fNumberFormat(0),
    128     fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
    129 {
    130 }
    131 
    132 //----------------------------------------------------------------------
    133 
    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 
    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 
    169 DateFormat::~DateFormat()
    170 {
    171     delete fCalendar;
    172     delete fNumberFormat;
    173 }
    174 
    175 //----------------------------------------------------------------------
    176 
    177 UBool
    178 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&
    197 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&
    232 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&
    268 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&
    281 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&
    300 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&
    318 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
    329 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
    360 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
    380 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
    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
    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
    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
    422 DateFormat::createInstance()
    423 {
    424     return createDateTimeInstance(kShort, kShort, Locale::getDefault());
    425 }
    426 
    427 //----------------------------------------------------------------------
    428 
    429 UnicodeString U_EXPORT2
    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
    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
    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
    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
    498 DateFormat::create(EStyle timeStyle, EStyle dateStyle, const Locale& locale)
    499 {
    500     UErrorCode status = U_ZERO_ERROR;
    501 #if U_PLATFORM_USES_ONLY_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
    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
    557 DateFormat::adoptCalendar(Calendar* newCalendar)
    558 {
    559     delete fCalendar;
    560     fCalendar = newCalendar;
    561 }
    562 
    563 //----------------------------------------------------------------------
    564 void
    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*
    576 DateFormat::getCalendar() const
    577 {
    578     return fCalendar;
    579 }
    580 
    581 //----------------------------------------------------------------------
    582 
    583 void
    584 DateFormat::adoptNumberFormat(NumberFormat* newNumberFormat)
    585 {
    586     delete fNumberFormat;
    587     fNumberFormat = newNumberFormat;
    588     newNumberFormat->setParseIntegerOnly(TRUE);
    589     newNumberFormat->setGroupingUsed(FALSE);
    590 }
    591 //----------------------------------------------------------------------
    592 
    593 void
    594 DateFormat::setNumberFormat(const NumberFormat& newNumberFormat)
    595 {
    596     NumberFormat* newNumFmtClone = (NumberFormat*)newNumberFormat.clone();
    597     if (newNumFmtClone != NULL) {
    598         adoptNumberFormat(newNumFmtClone);
    599     }
    600 }
    601 
    602 //----------------------------------------------------------------------
    603 
    604 const NumberFormat*
    605 DateFormat::getNumberFormat() const
    606 {
    607     return fNumberFormat;
    608 }
    609 
    610 //----------------------------------------------------------------------
    611 
    612 void
    613 DateFormat::adoptTimeZone(TimeZone* zone)
    614 {
    615     if (fCalendar != NULL) {
    616         fCalendar->adoptTimeZone(zone);
    617     }
    618 }
    619 //----------------------------------------------------------------------
    620 
    621 void
    622 DateFormat::setTimeZone(const TimeZone& zone)
    623 {
    624     if (fCalendar != NULL) {
    625         fCalendar->setTimeZone(zone);
    626     }
    627 }
    628 
    629 //----------------------------------------------------------------------
    630 
    631 const TimeZone&
    632 DateFormat::getTimeZone() const
    633 {
    634     if (fCalendar != NULL) {
    635         return fCalendar->getTimeZone();
    636     }
    637     // If calendar doesn't exists, create default timezone.
    638     // fCalendar is rarely null
    639     return *(TimeZone::createDefault());
    640 }
    641 
    642 //----------------------------------------------------------------------
    643 
    644 void
    645 DateFormat::setLenient(UBool lenient)
    646 {
    647     if (fCalendar != NULL) {
    648         fCalendar->setLenient(lenient);
    649     }
    650     UErrorCode status = U_ZERO_ERROR;
    651     setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, lenient, status);
    652     setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, lenient, status);
    653 }
    654 
    655 //----------------------------------------------------------------------
    656 
    657 UBool
    658 DateFormat::isLenient() const
    659 {
    660     UBool lenient = TRUE;
    661     if (fCalendar != NULL) {
    662         lenient = fCalendar->isLenient();
    663     }
    664     UErrorCode status = U_ZERO_ERROR;
    665     return lenient
    666         && getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status)
    667         && getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status);
    668 }
    669 
    670 void
    671 DateFormat::setCalendarLenient(UBool lenient)
    672 {
    673     if (fCalendar != NULL) {
    674         fCalendar->setLenient(lenient);
    675     }
    676 }
    677 
    678 //----------------------------------------------------------------------
    679 
    680 UBool
    681 DateFormat::isCalendarLenient() const
    682 {
    683     if (fCalendar != NULL) {
    684         return fCalendar->isLenient();
    685     }
    686     // fCalendar is rarely null
    687     return FALSE;
    688 }
    689 
    690 
    691 //----------------------------------------------------------------------
    692 
    693 
    694 void DateFormat::setContext(UDisplayContext value, UErrorCode& status)
    695 {
    696     if (U_FAILURE(status))
    697         return;
    698     if ( (UDisplayContextType)((uint32_t)value >> 8) == UDISPCTX_TYPE_CAPITALIZATION ) {
    699         fCapitalizationContext = value;
    700     } else {
    701         status = U_ILLEGAL_ARGUMENT_ERROR;
    702    }
    703 }
    704 
    705 
    706 //----------------------------------------------------------------------
    707 
    708 
    709 UDisplayContext DateFormat::getContext(UDisplayContextType type, UErrorCode& status) const
    710 {
    711     if (U_FAILURE(status))
    712         return (UDisplayContext)0;
    713     if (type != UDISPCTX_TYPE_CAPITALIZATION) {
    714         status = U_ILLEGAL_ARGUMENT_ERROR;
    715         return (UDisplayContext)0;
    716     }
    717     return fCapitalizationContext;
    718 }
    719 
    720 
    721 //----------------------------------------------------------------------
    722 
    723 
    724 DateFormat&
    725 DateFormat::setBooleanAttribute(UDateFormatBooleanAttribute attr,
    726     									UBool newValue,
    727     									UErrorCode &status) {
    728     if(!fBoolFlags.isValidValue(newValue)) {
    729         status = U_ILLEGAL_ARGUMENT_ERROR;
    730     } else {
    731         fBoolFlags.set(attr, newValue);
    732     }
    733 
    734     return *this;
    735 }
    736 
    737 //----------------------------------------------------------------------
    738 
    739 UBool
    740 DateFormat::getBooleanAttribute(UDateFormatBooleanAttribute attr, UErrorCode &/*status*/) const {
    741 
    742     return static_cast<UBool>(fBoolFlags.get(attr));
    743 }
    744 
    745 U_NAMESPACE_END
    746 
    747 #endif /* #if !UCONFIG_NO_FORMATTING */
    748 
    749 //eof
    750