Coverage Report

Created: 2025-06-24 06:43

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