Home | History | Annotate | Download | only in i18n
      1 /*
      2  *******************************************************************************
      3  * Copyright (C) 1997-2015, International Business Machines Corporation and    *
      4  * others. All Rights Reserved.                                                *
      5  *******************************************************************************
      6  *
      7  * File DATEFMT.CPP
      8  *
      9  * Modification History:
     10  *
     11  *   Date        Name        Description
     12  *   02/19/97    aliu        Converted from java.
     13  *   03/31/97    aliu        Modified extensively to work with 50 locales.
     14  *   04/01/97    aliu        Added support for centuries.
     15  *   08/12/97    aliu        Fixed operator== to use Calendar::equivalentTo.
     16  *   07/20/98    stephen     Changed ParsePosition initialization
     17  ********************************************************************************
     18  */
     19 
     20 #include "unicode/utypes.h"
     21 
     22 #if !UCONFIG_NO_FORMATTING
     23 
     24 #include "unicode/ures.h"
     25 #include "unicode/datefmt.h"
     26 #include "unicode/smpdtfmt.h"
     27 #include "unicode/dtptngen.h"
     28 #include "unicode/udisplaycontext.h"
     29 #include "reldtfmt.h"
     30 #include "sharedobject.h"
     31 #include "unifiedcache.h"
     32 #include "uarrsort.h"
     33 
     34 #include "cstring.h"
     35 #include "windtfmt.h"
     36 
     37 #if defined( U_DEBUG_CALSVC ) || defined (U_DEBUG_CAL)
     38 #include <stdio.h>
     39 #endif
     40 
     41 // *****************************************************************************
     42 // class DateFormat
     43 // *****************************************************************************
     44 
     45 U_NAMESPACE_BEGIN
     46 
     47 class U_I18N_API DateFmtBestPattern : public SharedObject {
     48 public:
     49     UnicodeString fPattern;
     50 
     51     DateFmtBestPattern(const UnicodeString &pattern)
     52             : fPattern(pattern) { }
     53     ~DateFmtBestPattern();
     54 };
     55 
     56 DateFmtBestPattern::~DateFmtBestPattern() {
     57 }
     58 
     59 template<> U_I18N_API
     60 const DateFmtBestPattern *LocaleCacheKey<DateFmtBestPattern>::createObject(
     61         const void * /*creationContext*/, UErrorCode &status) const {
     62     status = U_UNSUPPORTED_ERROR;
     63     return NULL;
     64 }
     65 
     66 class U_I18N_API DateFmtBestPatternKey : public LocaleCacheKey<DateFmtBestPattern> {
     67 private:
     68     UnicodeString fSkeleton;
     69 public:
     70     DateFmtBestPatternKey(
     71         const Locale &loc,
     72         const UnicodeString &skeleton,
     73         UErrorCode &status)
     74             : LocaleCacheKey<DateFmtBestPattern>(loc),
     75               fSkeleton(DateTimePatternGenerator::staticGetSkeleton(skeleton, status)) { }
     76     DateFmtBestPatternKey(const DateFmtBestPatternKey &other) :
     77             LocaleCacheKey<DateFmtBestPattern>(other),
     78             fSkeleton(other.fSkeleton) { }
     79     virtual ~DateFmtBestPatternKey();
     80     virtual int32_t hashCode() const {
     81         return 37 * LocaleCacheKey<DateFmtBestPattern>::hashCode() + fSkeleton.hashCode();
     82     }
     83     virtual UBool operator==(const CacheKeyBase &other) const {
     84        // reflexive
     85        if (this == &other) {
     86            return TRUE;
     87        }
     88        if (!LocaleCacheKey<DateFmtBestPattern>::operator==(other)) {
     89            return FALSE;
     90        }
     91        // We know that this and other are of same class if we get this far.
     92        const DateFmtBestPatternKey &realOther =
     93                static_cast<const DateFmtBestPatternKey &>(other);
     94        return (realOther.fSkeleton == fSkeleton);
     95     }
     96     virtual CacheKeyBase *clone() const {
     97         return new DateFmtBestPatternKey(*this);
     98     }
     99     virtual const DateFmtBestPattern *createObject(
    100             const void * /*unused*/, UErrorCode &status) const {
    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 
    120 DateFmtBestPatternKey::~DateFmtBestPatternKey() { }
    121 
    122 
    123 DateFormat::DateFormat()
    124 :   fCalendar(0),
    125     fNumberFormat(0),
    126     fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
    127 {
    128 }
    129 
    130 //----------------------------------------------------------------------
    131 
    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 
    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 = (NumberFormat*)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 
    167 DateFormat::~DateFormat()
    168 {
    169     delete fCalendar;
    170     delete fNumberFormat;
    171 }
    172 
    173 //----------------------------------------------------------------------
    174 
    175 UBool
    176 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&
    195 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&
    230 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&
    266 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&
    279 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&
    298 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&
    316 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(0);
    321     return format(date, appendTo, fpos);
    322 }
    323 
    324 //----------------------------------------------------------------------
    325 
    326 UDate
    327 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
    358 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
    378 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
    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
    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
    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
    420 DateFormat::createInstance()
    421 {
    422     return createDateTimeInstance(kShort, kShort, Locale::getDefault());
    423 }
    424 
    425 //----------------------------------------------------------------------
    426 
    427 UnicodeString U_EXPORT2
    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
    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     DateFormat *result = createInstanceForSkeleton(skeleton, locale, status);
    462     if (U_FAILURE(status)) {
    463         return NULL;
    464     }
    465     result->adoptCalendar(calendar.orphan());
    466     return result;
    467 }
    468 
    469 DateFormat* U_EXPORT2
    470 DateFormat::createInstanceForSkeleton(
    471         const UnicodeString& skeleton,
    472         const Locale &locale,
    473         UErrorCode &status) {
    474     if (U_FAILURE(status)) {
    475         return NULL;
    476     }
    477     LocalPointer<DateFormat> df(
    478         new SimpleDateFormat(
    479             getBestPattern(locale, skeleton, status),
    480             locale, status),
    481         status);
    482     return U_SUCCESS(status) ? df.orphan() : NULL;
    483 }
    484 
    485 DateFormat* U_EXPORT2
    486 DateFormat::createInstanceForSkeleton(
    487         const UnicodeString& skeleton,
    488         UErrorCode &status) {
    489     return createInstanceForSkeleton(
    490             skeleton, Locale::getDefault(), status);
    491 }
    492 
    493 //----------------------------------------------------------------------
    494 
    495 DateFormat* U_EXPORT2
    496 DateFormat::create(EStyle timeStyle, EStyle dateStyle, const Locale& locale)
    497 {
    498     UErrorCode status = U_ZERO_ERROR;
    499 #if U_PLATFORM_HAS_WIN32_API
    500     char buffer[8];
    501     int32_t count = locale.getKeywordValue("compat", buffer, sizeof(buffer), status);
    502 
    503     // if the locale has "@compat=host", create a host-specific DateFormat...
    504     if (count > 0 && uprv_strcmp(buffer, "host") == 0) {
    505         Win32DateFormat *f = new Win32DateFormat(timeStyle, dateStyle, locale, status);
    506 
    507         if (U_SUCCESS(status)) {
    508             return f;
    509         }
    510 
    511         delete f;
    512     }
    513 #endif
    514 
    515     // is it relative?
    516     if(/*((timeStyle!=UDAT_NONE)&&(timeStyle & UDAT_RELATIVE)) || */((dateStyle!=kNone)&&((dateStyle-kDateOffset) & UDAT_RELATIVE))) {
    517         RelativeDateFormat *r = new RelativeDateFormat((UDateFormatStyle)timeStyle, (UDateFormatStyle)(dateStyle-kDateOffset), locale, status);
    518         if(U_SUCCESS(status)) return r;
    519         delete r;
    520         status = U_ZERO_ERROR;
    521     }
    522 
    523     // Try to create a SimpleDateFormat of the desired style.
    524     SimpleDateFormat *f = new SimpleDateFormat(timeStyle, dateStyle, locale, status);
    525     if (U_SUCCESS(status)) return f;
    526     delete f;
    527 
    528     // If that fails, try to create a format using the default pattern and
    529     // the DateFormatSymbols for this locale.
    530     status = U_ZERO_ERROR;
    531     f = new SimpleDateFormat(locale, status);
    532     if (U_SUCCESS(status)) return f;
    533     delete f;
    534 
    535     // This should never really happen, because the preceding constructor
    536     // should always succeed.  If the resource data is unavailable, a last
    537     // resort object should be returned.
    538     return 0;
    539 }
    540 
    541 //----------------------------------------------------------------------
    542 
    543 const Locale* U_EXPORT2
    544 DateFormat::getAvailableLocales(int32_t& count)
    545 {
    546     // Get the list of installed locales.
    547     // Even if root has the correct date format for this locale,
    548     // it's still a valid locale (we don't worry about data fallbacks).
    549     return Locale::getAvailableLocales(count);
    550 }
    551 
    552 //----------------------------------------------------------------------
    553 
    554 void
    555 DateFormat::adoptCalendar(Calendar* newCalendar)
    556 {
    557     delete fCalendar;
    558     fCalendar = newCalendar;
    559 }
    560 
    561 //----------------------------------------------------------------------
    562 void
    563 DateFormat::setCalendar(const Calendar& newCalendar)
    564 {
    565     Calendar* newCalClone = newCalendar.clone();
    566     if (newCalClone != NULL) {
    567         adoptCalendar(newCalClone);
    568     }
    569 }
    570 
    571 //----------------------------------------------------------------------
    572 
    573 const Calendar*
    574 DateFormat::getCalendar() const
    575 {
    576     return fCalendar;
    577 }
    578 
    579 //----------------------------------------------------------------------
    580 
    581 void
    582 DateFormat::adoptNumberFormat(NumberFormat* newNumberFormat)
    583 {
    584     delete fNumberFormat;
    585     fNumberFormat = newNumberFormat;
    586     newNumberFormat->setParseIntegerOnly(TRUE);
    587 }
    588 //----------------------------------------------------------------------
    589 
    590 void
    591 DateFormat::setNumberFormat(const NumberFormat& newNumberFormat)
    592 {
    593     NumberFormat* newNumFmtClone = (NumberFormat*)newNumberFormat.clone();
    594     if (newNumFmtClone != NULL) {
    595         adoptNumberFormat(newNumFmtClone);
    596     }
    597 }
    598 
    599 //----------------------------------------------------------------------
    600 
    601 const NumberFormat*
    602 DateFormat::getNumberFormat() const
    603 {
    604     return fNumberFormat;
    605 }
    606 
    607 //----------------------------------------------------------------------
    608 
    609 void
    610 DateFormat::adoptTimeZone(TimeZone* zone)
    611 {
    612     if (fCalendar != NULL) {
    613         fCalendar->adoptTimeZone(zone);
    614     }
    615 }
    616 //----------------------------------------------------------------------
    617 
    618 void
    619 DateFormat::setTimeZone(const TimeZone& zone)
    620 {
    621     if (fCalendar != NULL) {
    622         fCalendar->setTimeZone(zone);
    623     }
    624 }
    625 
    626 //----------------------------------------------------------------------
    627 
    628 const TimeZone&
    629 DateFormat::getTimeZone() const
    630 {
    631     if (fCalendar != NULL) {
    632         return fCalendar->getTimeZone();
    633     }
    634     // If calendar doesn't exists, create default timezone.
    635     // fCalendar is rarely null
    636     return *(TimeZone::createDefault());
    637 }
    638 
    639 //----------------------------------------------------------------------
    640 
    641 void
    642 DateFormat::setLenient(UBool lenient)
    643 {
    644     if (fCalendar != NULL) {
    645         fCalendar->setLenient(lenient);
    646     }
    647     UErrorCode status = U_ZERO_ERROR;
    648     setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, lenient, status);
    649     setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, lenient, status);
    650 }
    651 
    652 //----------------------------------------------------------------------
    653 
    654 UBool
    655 DateFormat::isLenient() const
    656 {
    657     UBool lenient = TRUE;
    658     if (fCalendar != NULL) {
    659         lenient = fCalendar->isLenient();
    660     }
    661     UErrorCode status = U_ZERO_ERROR;
    662     return lenient
    663         && getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status)
    664         && getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status);
    665 }
    666 
    667 void
    668 DateFormat::setCalendarLenient(UBool lenient)
    669 {
    670     if (fCalendar != NULL) {
    671         fCalendar->setLenient(lenient);
    672     }
    673 }
    674 
    675 //----------------------------------------------------------------------
    676 
    677 UBool
    678 DateFormat::isCalendarLenient() const
    679 {
    680     if (fCalendar != NULL) {
    681         return fCalendar->isLenient();
    682     }
    683     // fCalendar is rarely null
    684     return FALSE;
    685 }
    686 
    687 
    688 //----------------------------------------------------------------------
    689 
    690 
    691 void DateFormat::setContext(UDisplayContext value, UErrorCode& status)
    692 {
    693     if (U_FAILURE(status))
    694         return;
    695     if ( (UDisplayContextType)((uint32_t)value >> 8) == UDISPCTX_TYPE_CAPITALIZATION ) {
    696         fCapitalizationContext = value;
    697     } else {
    698         status = U_ILLEGAL_ARGUMENT_ERROR;
    699    }
    700 }
    701 
    702 
    703 //----------------------------------------------------------------------
    704 
    705 
    706 UDisplayContext DateFormat::getContext(UDisplayContextType type, UErrorCode& status) const
    707 {
    708     if (U_FAILURE(status))
    709         return (UDisplayContext)0;
    710     if (type != UDISPCTX_TYPE_CAPITALIZATION) {
    711         status = U_ILLEGAL_ARGUMENT_ERROR;
    712         return (UDisplayContext)0;
    713     }
    714     return fCapitalizationContext;
    715 }
    716 
    717 
    718 //----------------------------------------------------------------------
    719 
    720 
    721 DateFormat&
    722 DateFormat::setBooleanAttribute(UDateFormatBooleanAttribute attr,
    723     									UBool newValue,
    724     									UErrorCode &status) {
    725     if(!fBoolFlags.isValidValue(newValue)) {
    726         status = U_ILLEGAL_ARGUMENT_ERROR;
    727     } else {
    728         fBoolFlags.set(attr, newValue);
    729     }
    730 
    731     return *this;
    732 }
    733 
    734 //----------------------------------------------------------------------
    735 
    736 UBool
    737 DateFormat::getBooleanAttribute(UDateFormatBooleanAttribute attr, UErrorCode &/*status*/) const {
    738 
    739     return fBoolFlags.get(attr);
    740 }
    741 
    742 U_NAMESPACE_END
    743 
    744 #endif /* #if !UCONFIG_NO_FORMATTING */
    745 
    746 //eof
    747