Home | History | Annotate | Download | only in i18n
      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 
     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 37 * LocaleCacheKey<DateFmtBestPattern>::hashCode() + 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_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
    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 }
    590 //----------------------------------------------------------------------
    591 
    592 void
    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*
    604 DateFormat::getNumberFormat() const
    605 {
    606     return fNumberFormat;
    607 }
    608 
    609 //----------------------------------------------------------------------
    610 
    611 void
    612 DateFormat::adoptTimeZone(TimeZone* zone)
    613 {
    614     if (fCalendar != NULL) {
    615         fCalendar->adoptTimeZone(zone);
    616     }
    617 }
    618 //----------------------------------------------------------------------
    619 
    620 void
    621 DateFormat::setTimeZone(const TimeZone& zone)
    622 {
    623     if (fCalendar != NULL) {
    624         fCalendar->setTimeZone(zone);
    625     }
    626 }
    627 
    628 //----------------------------------------------------------------------
    629 
    630 const TimeZone&
    631 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
    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
    657 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
    670 DateFormat::setCalendarLenient(UBool lenient)
    671 {
    672     if (fCalendar != NULL) {
    673         fCalendar->setLenient(lenient);
    674     }
    675 }
    676 
    677 //----------------------------------------------------------------------
    678 
    679 UBool
    680 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 
    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 
    708 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&
    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
    739 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