Line data Source code
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 0 : 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 0 : const DateFmtBestPattern *LocaleCacheKey<DateFmtBestPattern>::createObject(
63 : const void * /*creationContext*/, UErrorCode &status) const {
64 0 : status = U_UNSUPPORTED_ERROR;
65 0 : return NULL;
66 : }
67 :
68 : class U_I18N_API DateFmtBestPatternKey : public LocaleCacheKey<DateFmtBestPattern> {
69 : private:
70 : UnicodeString fSkeleton;
71 : public:
72 0 : 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 0 : DateFmtBestPatternKey(const DateFmtBestPatternKey &other) :
79 : 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 : }
85 0 : virtual UBool operator==(const CacheKeyBase &other) const {
86 : // reflexive
87 0 : if (this == &other) {
88 0 : return TRUE;
89 : }
90 0 : if (!LocaleCacheKey<DateFmtBestPattern>::operator==(other)) {
91 0 : return FALSE;
92 : }
93 : // We know that this and other are of same class if we get this far.
94 : const DateFmtBestPatternKey &realOther =
95 0 : static_cast<const DateFmtBestPatternKey &>(other);
96 0 : return (realOther.fSkeleton == fSkeleton);
97 : }
98 0 : virtual CacheKeyBase *clone() const {
99 0 : return new DateFmtBestPatternKey(*this);
100 : }
101 0 : virtual const DateFmtBestPattern *createObject(
102 : const void * /*unused*/, UErrorCode &status) const {
103 : LocalPointer<DateTimePatternGenerator> dtpg(
104 0 : DateTimePatternGenerator::createInstance(fLoc, status));
105 0 : if (U_FAILURE(status)) {
106 0 : return NULL;
107 : }
108 :
109 : LocalPointer<DateFmtBestPattern> pattern(
110 : new DateFmtBestPattern(
111 0 : dtpg->getBestPattern(fSkeleton, status)),
112 0 : status);
113 0 : if (U_FAILURE(status)) {
114 0 : return NULL;
115 : }
116 0 : DateFmtBestPattern *result = pattern.orphan();
117 0 : result->addRef();
118 0 : return result;
119 : }
120 : };
121 :
122 0 : DateFmtBestPatternKey::~DateFmtBestPatternKey() { }
123 :
124 :
125 0 : DateFormat::DateFormat()
126 : : fCalendar(0),
127 : fNumberFormat(0),
128 0 : fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
129 : {
130 0 : }
131 :
132 : //----------------------------------------------------------------------
133 :
134 0 : DateFormat::DateFormat(const DateFormat& other)
135 : : Format(other),
136 : fCalendar(0),
137 : fNumberFormat(0),
138 0 : fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE)
139 : {
140 0 : *this = other;
141 0 : }
142 :
143 : //----------------------------------------------------------------------
144 :
145 0 : DateFormat& DateFormat::operator=(const DateFormat& other)
146 : {
147 0 : if (this != &other)
148 : {
149 0 : delete fCalendar;
150 0 : delete fNumberFormat;
151 0 : if(other.fCalendar) {
152 0 : fCalendar = other.fCalendar->clone();
153 : } else {
154 0 : fCalendar = NULL;
155 : }
156 0 : if(other.fNumberFormat) {
157 0 : fNumberFormat = (NumberFormat*)other.fNumberFormat->clone();
158 : } else {
159 0 : fNumberFormat = NULL;
160 : }
161 0 : fBoolFlags = other.fBoolFlags;
162 0 : fCapitalizationContext = other.fCapitalizationContext;
163 : }
164 0 : return *this;
165 : }
166 :
167 : //----------------------------------------------------------------------
168 :
169 0 : DateFormat::~DateFormat()
170 : {
171 0 : delete fCalendar;
172 0 : delete fNumberFormat;
173 0 : }
174 :
175 : //----------------------------------------------------------------------
176 :
177 : UBool
178 0 : 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 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 : }
193 :
194 : //----------------------------------------------------------------------
195 :
196 : UnicodeString&
197 0 : DateFormat::format(const Formattable& obj,
198 : UnicodeString& appendTo,
199 : FieldPosition& fieldPosition,
200 : UErrorCode& status) const
201 : {
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 : {
208 : case Formattable::kDate:
209 0 : date = obj.getDate();
210 0 : break;
211 : case Formattable::kDouble:
212 0 : date = (UDate)obj.getDouble();
213 0 : break;
214 : case Formattable::kLong:
215 0 : date = (UDate)obj.getLong();
216 0 : break;
217 : default:
218 0 : status = U_ILLEGAL_ARGUMENT_ERROR;
219 0 : return appendTo;
220 : }
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 : }
228 :
229 : //----------------------------------------------------------------------
230 :
231 : UnicodeString&
232 0 : DateFormat::format(const Formattable& obj,
233 : UnicodeString& appendTo,
234 : FieldPositionIterator* posIter,
235 : UErrorCode& status) const
236 : {
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 : {
243 : case Formattable::kDate:
244 0 : date = obj.getDate();
245 0 : break;
246 : case Formattable::kDouble:
247 0 : date = (UDate)obj.getDouble();
248 0 : break;
249 : case Formattable::kLong:
250 0 : date = (UDate)obj.getLong();
251 0 : break;
252 : default:
253 0 : status = U_ILLEGAL_ARGUMENT_ERROR;
254 0 : return appendTo;
255 : }
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 : }
263 :
264 : //----------------------------------------------------------------------
265 :
266 : // Default implementation for backwards compatibility, subclasses should implement.
267 : UnicodeString&
268 0 : DateFormat::format(Calendar& /* unused cal */,
269 : UnicodeString& appendTo,
270 : FieldPositionIterator* /* unused posIter */,
271 : UErrorCode& status) const {
272 0 : if (U_SUCCESS(status)) {
273 0 : status = U_UNSUPPORTED_ERROR;
274 : }
275 0 : return appendTo;
276 : }
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 : }
291 0 : delete calClone;
292 : }
293 : }
294 0 : return appendTo;
295 : }
296 :
297 : //----------------------------------------------------------------------
298 :
299 : UnicodeString&
300 0 : DateFormat::format(UDate date, UnicodeString& appendTo, FieldPositionIterator* posIter,
301 : 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 : }
309 0 : delete calClone;
310 : }
311 : }
312 0 : return appendTo;
313 : }
314 :
315 : //----------------------------------------------------------------------
316 :
317 : UnicodeString&
318 0 : 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 0 : FieldPosition fpos(FieldPosition::DONT_CARE);
323 0 : return format(date, appendTo, fpos);
324 : }
325 :
326 : //----------------------------------------------------------------------
327 :
328 : UDate
329 0 : DateFormat::parse(const UnicodeString& text,
330 : ParsePosition& pos) const
331 : {
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 : }
350 : }
351 0 : delete calClone;
352 : }
353 : }
354 0 : return d;
355 : }
356 :
357 : //----------------------------------------------------------------------
358 :
359 : UDate
360 0 : DateFormat::parse(const UnicodeString& text,
361 : UErrorCode& status) const
362 : {
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 : }
374 0 : return result;
375 : }
376 :
377 : //----------------------------------------------------------------------
378 :
379 : void
380 0 : DateFormat::parseObject(const UnicodeString& source,
381 : Formattable& result,
382 : ParsePosition& pos) const
383 : {
384 0 : result.setDate(parse(source, pos));
385 0 : }
386 :
387 : //----------------------------------------------------------------------
388 :
389 : DateFormat* U_EXPORT2
390 0 : DateFormat::createTimeInstance(DateFormat::EStyle style,
391 : const Locale& aLocale)
392 : {
393 0 : return createDateTimeInstance(kNone, style, aLocale);
394 : }
395 :
396 : //----------------------------------------------------------------------
397 :
398 : DateFormat* U_EXPORT2
399 0 : DateFormat::createDateInstance(DateFormat::EStyle style,
400 : const Locale& aLocale)
401 : {
402 0 : return createDateTimeInstance(style, kNone, aLocale);
403 : }
404 :
405 : //----------------------------------------------------------------------
406 :
407 : DateFormat* U_EXPORT2
408 0 : DateFormat::createDateTimeInstance(EStyle dateStyle,
409 : EStyle timeStyle,
410 : const Locale& aLocale)
411 : {
412 0 : if(dateStyle != kNone)
413 : {
414 0 : dateStyle = (EStyle) (dateStyle + kDateOffset);
415 : }
416 0 : return create(timeStyle, dateStyle, aLocale);
417 : }
418 :
419 : //----------------------------------------------------------------------
420 :
421 : DateFormat* U_EXPORT2
422 0 : DateFormat::createInstance()
423 : {
424 0 : return createDateTimeInstance(kShort, kShort, Locale::getDefault());
425 : }
426 :
427 : //----------------------------------------------------------------------
428 :
429 : UnicodeString U_EXPORT2
430 0 : DateFormat::getBestPattern(
431 : const Locale &locale,
432 : const UnicodeString &skeleton,
433 : UErrorCode &status) {
434 0 : UnifiedCache *cache = UnifiedCache::getInstance(status);
435 0 : if (U_FAILURE(status)) {
436 0 : return UnicodeString();
437 : }
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 : }
444 0 : UnicodeString result(patternPtr->fPattern);
445 0 : patternPtr->removeRef();
446 0 : return result;
447 : }
448 :
449 : DateFormat* U_EXPORT2
450 0 : DateFormat::createInstanceForSkeleton(
451 : Calendar *calendarToAdopt,
452 : const UnicodeString& skeleton,
453 : const Locale &locale,
454 : UErrorCode &status) {
455 0 : LocalPointer<Calendar> calendar(calendarToAdopt);
456 0 : if (U_FAILURE(status)) {
457 0 : return NULL;
458 : }
459 0 : if (calendar.isNull()) {
460 0 : status = U_ILLEGAL_ARGUMENT_ERROR;
461 0 : return NULL;
462 : }
463 0 : DateFormat *result = createInstanceForSkeleton(skeleton, locale, status);
464 0 : if (U_FAILURE(status)) {
465 0 : return NULL;
466 : }
467 0 : result->adoptCalendar(calendar.orphan());
468 0 : return result;
469 : }
470 :
471 : DateFormat* U_EXPORT2
472 0 : DateFormat::createInstanceForSkeleton(
473 : const UnicodeString& skeleton,
474 : const Locale &locale,
475 : UErrorCode &status) {
476 0 : if (U_FAILURE(status)) {
477 0 : return NULL;
478 : }
479 : LocalPointer<DateFormat> df(
480 0 : new SimpleDateFormat(
481 0 : getBestPattern(locale, skeleton, status),
482 0 : locale, status),
483 0 : status);
484 0 : return U_SUCCESS(status) ? df.orphan() : NULL;
485 : }
486 :
487 : DateFormat* U_EXPORT2
488 0 : DateFormat::createInstanceForSkeleton(
489 : const UnicodeString& skeleton,
490 : UErrorCode &status) {
491 0 : return createInstanceForSkeleton(
492 0 : skeleton, Locale::getDefault(), status);
493 : }
494 :
495 : //----------------------------------------------------------------------
496 :
497 : DateFormat* U_EXPORT2
498 0 : DateFormat::create(EStyle timeStyle, EStyle dateStyle, const Locale& locale)
499 : {
500 0 : 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 0 : if(/*((timeStyle!=UDAT_NONE)&&(timeStyle & UDAT_RELATIVE)) || */((dateStyle!=kNone)&&((dateStyle-kDateOffset) & UDAT_RELATIVE))) {
519 0 : RelativeDateFormat *r = new RelativeDateFormat((UDateFormatStyle)timeStyle, (UDateFormatStyle)(dateStyle-kDateOffset), locale, status);
520 0 : if(U_SUCCESS(status)) return r;
521 0 : delete r;
522 0 : status = U_ZERO_ERROR;
523 : }
524 :
525 : // Try to create a SimpleDateFormat of the desired style.
526 0 : SimpleDateFormat *f = new SimpleDateFormat(timeStyle, dateStyle, locale, status);
527 0 : if (U_SUCCESS(status)) return f;
528 0 : delete f;
529 :
530 : // If that fails, try to create a format using the default pattern and
531 : // the DateFormatSymbols for this locale.
532 0 : status = U_ZERO_ERROR;
533 0 : f = new SimpleDateFormat(locale, status);
534 0 : if (U_SUCCESS(status)) return f;
535 0 : 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 0 : return 0;
541 : }
542 :
543 : //----------------------------------------------------------------------
544 :
545 : const Locale* U_EXPORT2
546 0 : 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 0 : return Locale::getAvailableLocales(count);
552 : }
553 :
554 : //----------------------------------------------------------------------
555 :
556 : void
557 0 : DateFormat::adoptCalendar(Calendar* newCalendar)
558 : {
559 0 : delete fCalendar;
560 0 : fCalendar = newCalendar;
561 0 : }
562 :
563 : //----------------------------------------------------------------------
564 : void
565 0 : DateFormat::setCalendar(const Calendar& newCalendar)
566 : {
567 0 : Calendar* newCalClone = newCalendar.clone();
568 0 : if (newCalClone != NULL) {
569 0 : adoptCalendar(newCalClone);
570 : }
571 0 : }
572 :
573 : //----------------------------------------------------------------------
574 :
575 : const Calendar*
576 0 : DateFormat::getCalendar() const
577 : {
578 0 : return fCalendar;
579 : }
580 :
581 : //----------------------------------------------------------------------
582 :
583 : void
584 0 : DateFormat::adoptNumberFormat(NumberFormat* newNumberFormat)
585 : {
586 0 : delete fNumberFormat;
587 0 : fNumberFormat = newNumberFormat;
588 0 : newNumberFormat->setParseIntegerOnly(TRUE);
589 0 : }
590 : //----------------------------------------------------------------------
591 :
592 : void
593 0 : DateFormat::setNumberFormat(const NumberFormat& newNumberFormat)
594 : {
595 0 : NumberFormat* newNumFmtClone = (NumberFormat*)newNumberFormat.clone();
596 0 : if (newNumFmtClone != NULL) {
597 0 : adoptNumberFormat(newNumFmtClone);
598 : }
599 0 : }
600 :
601 : //----------------------------------------------------------------------
602 :
603 : const NumberFormat*
604 0 : DateFormat::getNumberFormat() const
605 : {
606 0 : return fNumberFormat;
607 : }
608 :
609 : //----------------------------------------------------------------------
610 :
611 : void
612 0 : DateFormat::adoptTimeZone(TimeZone* zone)
613 : {
614 0 : if (fCalendar != NULL) {
615 0 : fCalendar->adoptTimeZone(zone);
616 : }
617 0 : }
618 : //----------------------------------------------------------------------
619 :
620 : void
621 0 : DateFormat::setTimeZone(const TimeZone& zone)
622 : {
623 0 : if (fCalendar != NULL) {
624 0 : fCalendar->setTimeZone(zone);
625 : }
626 0 : }
627 :
628 : //----------------------------------------------------------------------
629 :
630 : const TimeZone&
631 0 : DateFormat::getTimeZone() const
632 : {
633 0 : if (fCalendar != NULL) {
634 0 : return fCalendar->getTimeZone();
635 : }
636 : // If calendar doesn't exists, create default timezone.
637 : // fCalendar is rarely null
638 0 : return *(TimeZone::createDefault());
639 : }
640 :
641 : //----------------------------------------------------------------------
642 :
643 : void
644 0 : DateFormat::setLenient(UBool lenient)
645 : {
646 0 : if (fCalendar != NULL) {
647 0 : fCalendar->setLenient(lenient);
648 : }
649 0 : UErrorCode status = U_ZERO_ERROR;
650 0 : setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, lenient, status);
651 0 : setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, lenient, status);
652 0 : }
653 :
654 : //----------------------------------------------------------------------
655 :
656 : UBool
657 0 : DateFormat::isLenient() const
658 : {
659 0 : UBool lenient = TRUE;
660 0 : if (fCalendar != NULL) {
661 0 : lenient = fCalendar->isLenient();
662 : }
663 0 : UErrorCode status = U_ZERO_ERROR;
664 : return lenient
665 0 : && getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status)
666 0 : && getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status);
667 : }
668 :
669 : void
670 0 : DateFormat::setCalendarLenient(UBool lenient)
671 : {
672 0 : if (fCalendar != NULL) {
673 0 : fCalendar->setLenient(lenient);
674 : }
675 0 : }
676 :
677 : //----------------------------------------------------------------------
678 :
679 : UBool
680 0 : DateFormat::isCalendarLenient() const
681 : {
682 0 : if (fCalendar != NULL) {
683 0 : return fCalendar->isLenient();
684 : }
685 : // fCalendar is rarely null
686 0 : return FALSE;
687 : }
688 :
689 :
690 : //----------------------------------------------------------------------
691 :
692 :
693 0 : void DateFormat::setContext(UDisplayContext value, UErrorCode& status)
694 : {
695 0 : if (U_FAILURE(status))
696 0 : return;
697 0 : if ( (UDisplayContextType)((uint32_t)value >> 8) == UDISPCTX_TYPE_CAPITALIZATION ) {
698 0 : fCapitalizationContext = value;
699 : } else {
700 0 : status = U_ILLEGAL_ARGUMENT_ERROR;
701 : }
702 : }
703 :
704 :
705 : //----------------------------------------------------------------------
706 :
707 :
708 0 : UDisplayContext DateFormat::getContext(UDisplayContextType type, UErrorCode& status) const
709 : {
710 0 : if (U_FAILURE(status))
711 0 : return (UDisplayContext)0;
712 0 : if (type != UDISPCTX_TYPE_CAPITALIZATION) {
713 0 : status = U_ILLEGAL_ARGUMENT_ERROR;
714 0 : return (UDisplayContext)0;
715 : }
716 0 : return fCapitalizationContext;
717 : }
718 :
719 :
720 : //----------------------------------------------------------------------
721 :
722 :
723 : DateFormat&
724 0 : DateFormat::setBooleanAttribute(UDateFormatBooleanAttribute attr,
725 : UBool newValue,
726 : UErrorCode &status) {
727 0 : if(!fBoolFlags.isValidValue(newValue)) {
728 0 : status = U_ILLEGAL_ARGUMENT_ERROR;
729 : } else {
730 0 : fBoolFlags.set(attr, newValue);
731 : }
732 :
733 0 : return *this;
734 : }
735 :
736 : //----------------------------------------------------------------------
737 :
738 : UBool
739 0 : DateFormat::getBooleanAttribute(UDateFormatBooleanAttribute attr, UErrorCode &/*status*/) const {
740 :
741 0 : return fBoolFlags.get(attr);
742 : }
743 :
744 : U_NAMESPACE_END
745 :
746 : #endif /* #if !UCONFIG_NO_FORMATTING */
747 :
748 : //eof
|