]>
Commit | Line | Data |
---|---|---|
f3c0d7a5 A |
1 | // © 2016 and later: Unicode, Inc. and others. |
2 | // License & terms of use: http://www.unicode.org/copyright.html | |
b75a7d8f | 3 | /* |
46f4442e | 4 | ******************************************************************************* |
2ca993e8 | 5 | * Copyright (C) 1997-2015, International Business Machines Corporation and * |
46f4442e A |
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 | */ | |
b75a7d8f A |
21 | |
22 | #include "unicode/utypes.h" | |
23 | ||
24 | #if !UCONFIG_NO_FORMATTING | |
25 | ||
374ca955 | 26 | #include "unicode/ures.h" |
b75a7d8f A |
27 | #include "unicode/datefmt.h" |
28 | #include "unicode/smpdtfmt.h" | |
46f4442e | 29 | #include "unicode/dtptngen.h" |
57a6839d | 30 | #include "unicode/udisplaycontext.h" |
46f4442e | 31 | #include "reldtfmt.h" |
2ca993e8 A |
32 | #include "sharedobject.h" |
33 | #include "unifiedcache.h" | |
34 | #include "uarrsort.h" | |
b75a7d8f | 35 | |
73c04bcf A |
36 | #include "cstring.h" |
37 | #include "windtfmt.h" | |
38 | ||
374ca955 A |
39 | #if defined( U_DEBUG_CALSVC ) || defined (U_DEBUG_CAL) |
40 | #include <stdio.h> | |
41 | #endif | |
42 | ||
b75a7d8f A |
43 | // ***************************************************************************** |
44 | // class DateFormat | |
45 | // ***************************************************************************** | |
46 | ||
47 | U_NAMESPACE_BEGIN | |
48 | ||
2ca993e8 A |
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 { | |
f3c0d7a5 | 83 | return (int32_t)(37u * (uint32_t)LocaleCacheKey<DateFmtBestPattern>::hashCode() + (uint32_t)fSkeleton.hashCode()); |
2ca993e8 A |
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 | ||
b75a7d8f A |
125 | DateFormat::DateFormat() |
126 | : fCalendar(0), | |
57a6839d A |
127 | fNumberFormat(0), |
128 | fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE) | |
b75a7d8f A |
129 | { |
130 | } | |
131 | ||
132 | //---------------------------------------------------------------------- | |
133 | ||
134 | DateFormat::DateFormat(const DateFormat& other) | |
135 | : Format(other), | |
136 | fCalendar(0), | |
57a6839d A |
137 | fNumberFormat(0), |
138 | fCapitalizationContext(UDISPCTX_CAPITALIZATION_NONE) | |
b75a7d8f A |
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) { | |
340931cb | 157 | fNumberFormat = other.fNumberFormat->clone(); |
b75a7d8f A |
158 | } else { |
159 | fNumberFormat = NULL; | |
160 | } | |
57a6839d A |
161 | fBoolFlags = other.fBoolFlags; |
162 | fCapitalizationContext = other.fCapitalizationContext; | |
b75a7d8f A |
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 | ||
374ca955 | 184 | // Format::operator== guarantees that this cast is safe |
b75a7d8f A |
185 | DateFormat* fmt = (DateFormat*)&other; |
186 | ||
187 | return (this == fmt) || | |
374ca955 | 188 | (Format::operator==(other) && |
b75a7d8f | 189 | fCalendar&&(fCalendar->isEquivalentTo(*fmt->fCalendar)) && |
57a6839d A |
190 | (fNumberFormat && *fNumberFormat == *fmt->fNumberFormat) && |
191 | (fCapitalizationContext == fmt->fCapitalizationContext) ); | |
b75a7d8f A |
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 | ||
729e4ab9 A |
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 | ||
b75a7d8f A |
280 | UnicodeString& |
281 | DateFormat::format(UDate date, UnicodeString& appendTo, FieldPosition& fieldPosition) const { | |
282 | if (fCalendar != NULL) { | |
4388f060 A |
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; | |
b75a7d8f A |
292 | } |
293 | } | |
294 | return appendTo; | |
295 | } | |
296 | ||
297 | //---------------------------------------------------------------------- | |
298 | ||
729e4ab9 A |
299 | UnicodeString& |
300 | DateFormat::format(UDate date, UnicodeString& appendTo, FieldPositionIterator* posIter, | |
301 | UErrorCode& status) const { | |
302 | if (fCalendar != NULL) { | |
4388f060 A |
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; | |
729e4ab9 A |
310 | } |
311 | } | |
312 | return appendTo; | |
313 | } | |
314 | ||
315 | //---------------------------------------------------------------------- | |
316 | ||
b75a7d8f A |
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. | |
f3c0d7a5 | 322 | FieldPosition fpos(FieldPosition::DONT_CARE); |
b75a7d8f A |
323 | return format(date, appendTo, fpos); |
324 | } | |
325 | ||
326 | //---------------------------------------------------------------------- | |
327 | ||
328 | UDate | |
329 | DateFormat::parse(const UnicodeString& text, | |
330 | ParsePosition& pos) const | |
331 | { | |
46f4442e | 332 | UDate d = 0; // Error return UDate is 0 (the epoch) |
b75a7d8f | 333 | if (fCalendar != NULL) { |
4388f060 A |
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 | } | |
b75a7d8f | 350 | } |
4388f060 | 351 | delete calClone; |
b75a7d8f A |
352 | } |
353 | } | |
46f4442e | 354 | return d; |
b75a7d8f A |
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); | |
374ca955 A |
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 | } | |
b75a7d8f A |
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 | ||
374ca955 | 389 | DateFormat* U_EXPORT2 |
b75a7d8f A |
390 | DateFormat::createTimeInstance(DateFormat::EStyle style, |
391 | const Locale& aLocale) | |
392 | { | |
b331163b | 393 | return createDateTimeInstance(kNone, style, aLocale); |
b75a7d8f A |
394 | } |
395 | ||
396 | //---------------------------------------------------------------------- | |
397 | ||
374ca955 | 398 | DateFormat* U_EXPORT2 |
b75a7d8f A |
399 | DateFormat::createDateInstance(DateFormat::EStyle style, |
400 | const Locale& aLocale) | |
401 | { | |
b331163b | 402 | return createDateTimeInstance(style, kNone, aLocale); |
b75a7d8f A |
403 | } |
404 | ||
405 | //---------------------------------------------------------------------- | |
406 | ||
374ca955 | 407 | DateFormat* U_EXPORT2 |
b75a7d8f A |
408 | DateFormat::createDateTimeInstance(EStyle dateStyle, |
409 | EStyle timeStyle, | |
410 | const Locale& aLocale) | |
411 | { | |
b331163b A |
412 | if(dateStyle != kNone) |
413 | { | |
414 | dateStyle = (EStyle) (dateStyle + kDateOffset); | |
415 | } | |
416 | return create(timeStyle, dateStyle, aLocale); | |
b75a7d8f A |
417 | } |
418 | ||
419 | //---------------------------------------------------------------------- | |
420 | ||
374ca955 | 421 | DateFormat* U_EXPORT2 |
b75a7d8f A |
422 | DateFormat::createInstance() |
423 | { | |
b331163b A |
424 | return createDateTimeInstance(kShort, kShort, Locale::getDefault()); |
425 | } | |
426 | ||
427 | //---------------------------------------------------------------------- | |
428 | ||
2ca993e8 A |
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 | ||
b331163b A |
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 | } | |
3d1f044b A |
463 | Locale localeWithCalendar = locale; |
464 | localeWithCalendar.setKeywordValue("calendar", calendar->getType(), status); | |
465 | if (U_FAILURE(status)) { | |
466 | return NULL; | |
467 | } | |
468 | DateFormat *result = createInstanceForSkeleton(skeleton, localeWithCalendar, status); | |
b331163b A |
469 | if (U_FAILURE(status)) { |
470 | return NULL; | |
471 | } | |
472 | result->adoptCalendar(calendar.orphan()); | |
473 | return result; | |
474 | } | |
475 | ||
476 | DateFormat* U_EXPORT2 | |
477 | DateFormat::createInstanceForSkeleton( | |
478 | const UnicodeString& skeleton, | |
479 | const Locale &locale, | |
480 | UErrorCode &status) { | |
b331163b A |
481 | if (U_FAILURE(status)) { |
482 | return NULL; | |
483 | } | |
2ca993e8 A |
484 | LocalPointer<DateFormat> df( |
485 | new SimpleDateFormat( | |
486 | getBestPattern(locale, skeleton, status), | |
487 | locale, status), | |
488 | status); | |
489 | return U_SUCCESS(status) ? df.orphan() : NULL; | |
b331163b A |
490 | } |
491 | ||
492 | DateFormat* U_EXPORT2 | |
493 | DateFormat::createInstanceForSkeleton( | |
494 | const UnicodeString& skeleton, | |
495 | UErrorCode &status) { | |
496 | return createInstanceForSkeleton( | |
497 | skeleton, Locale::getDefault(), status); | |
498 | } | |
499 | ||
b75a7d8f A |
500 | //---------------------------------------------------------------------- |
501 | ||
374ca955 | 502 | DateFormat* U_EXPORT2 |
b75a7d8f A |
503 | DateFormat::create(EStyle timeStyle, EStyle dateStyle, const Locale& locale) |
504 | { | |
b75a7d8f | 505 | UErrorCode status = U_ZERO_ERROR; |
f3c0d7a5 | 506 | #if U_PLATFORM_USES_ONLY_WIN32_API |
73c04bcf A |
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 | ||
46f4442e A |
522 | // is it relative? |
523 | if(/*((timeStyle!=UDAT_NONE)&&(timeStyle & UDAT_RELATIVE)) || */((dateStyle!=kNone)&&((dateStyle-kDateOffset) & UDAT_RELATIVE))) { | |
524 | RelativeDateFormat *r = new RelativeDateFormat((UDateFormatStyle)timeStyle, (UDateFormatStyle)(dateStyle-kDateOffset), locale, status); | |
525 | if(U_SUCCESS(status)) return r; | |
526 | delete r; | |
527 | status = U_ZERO_ERROR; | |
528 | } | |
73c04bcf A |
529 | |
530 | // Try to create a SimpleDateFormat of the desired style. | |
b75a7d8f A |
531 | SimpleDateFormat *f = new SimpleDateFormat(timeStyle, dateStyle, locale, status); |
532 | if (U_SUCCESS(status)) return f; | |
533 | delete f; | |
534 | ||
535 | // If that fails, try to create a format using the default pattern and | |
536 | // the DateFormatSymbols for this locale. | |
537 | status = U_ZERO_ERROR; | |
538 | f = new SimpleDateFormat(locale, status); | |
539 | if (U_SUCCESS(status)) return f; | |
540 | 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 | return 0; | |
546 | } | |
547 | ||
548 | //---------------------------------------------------------------------- | |
549 | ||
374ca955 | 550 | const Locale* U_EXPORT2 |
b75a7d8f A |
551 | DateFormat::getAvailableLocales(int32_t& count) |
552 | { | |
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 | return Locale::getAvailableLocales(count); | |
557 | } | |
558 | ||
559 | //---------------------------------------------------------------------- | |
560 | ||
561 | void | |
562 | DateFormat::adoptCalendar(Calendar* newCalendar) | |
563 | { | |
564 | delete fCalendar; | |
565 | fCalendar = newCalendar; | |
566 | } | |
567 | ||
568 | //---------------------------------------------------------------------- | |
569 | void | |
570 | DateFormat::setCalendar(const Calendar& newCalendar) | |
571 | { | |
0f5d89e8 A |
572 | if (fCalendar && fCalendar->isEquivalentTo( newCalendar )) |
573 | return; | |
46f4442e A |
574 | Calendar* newCalClone = newCalendar.clone(); |
575 | if (newCalClone != NULL) { | |
576 | adoptCalendar(newCalClone); | |
577 | } | |
b75a7d8f A |
578 | } |
579 | ||
580 | //---------------------------------------------------------------------- | |
581 | ||
582 | const Calendar* | |
583 | DateFormat::getCalendar() const | |
584 | { | |
585 | return fCalendar; | |
586 | } | |
587 | ||
588 | //---------------------------------------------------------------------- | |
589 | ||
590 | void | |
591 | DateFormat::adoptNumberFormat(NumberFormat* newNumberFormat) | |
592 | { | |
593 | delete fNumberFormat; | |
594 | fNumberFormat = newNumberFormat; | |
595 | newNumberFormat->setParseIntegerOnly(TRUE); | |
0f5d89e8 | 596 | newNumberFormat->setGroupingUsed(FALSE); |
b75a7d8f A |
597 | } |
598 | //---------------------------------------------------------------------- | |
599 | ||
600 | void | |
601 | DateFormat::setNumberFormat(const NumberFormat& newNumberFormat) | |
602 | { | |
340931cb | 603 | NumberFormat* newNumFmtClone = newNumberFormat.clone(); |
46f4442e A |
604 | if (newNumFmtClone != NULL) { |
605 | adoptNumberFormat(newNumFmtClone); | |
606 | } | |
b75a7d8f A |
607 | } |
608 | ||
609 | //---------------------------------------------------------------------- | |
610 | ||
611 | const NumberFormat* | |
612 | DateFormat::getNumberFormat() const | |
613 | { | |
614 | return fNumberFormat; | |
615 | } | |
616 | ||
617 | //---------------------------------------------------------------------- | |
618 | ||
619 | void | |
620 | DateFormat::adoptTimeZone(TimeZone* zone) | |
621 | { | |
46f4442e A |
622 | if (fCalendar != NULL) { |
623 | fCalendar->adoptTimeZone(zone); | |
624 | } | |
b75a7d8f A |
625 | } |
626 | //---------------------------------------------------------------------- | |
627 | ||
628 | void | |
629 | DateFormat::setTimeZone(const TimeZone& zone) | |
630 | { | |
46f4442e A |
631 | if (fCalendar != NULL) { |
632 | fCalendar->setTimeZone(zone); | |
633 | } | |
b75a7d8f A |
634 | } |
635 | ||
636 | //---------------------------------------------------------------------- | |
637 | ||
638 | const TimeZone& | |
639 | DateFormat::getTimeZone() const | |
640 | { | |
46f4442e A |
641 | if (fCalendar != NULL) { |
642 | return fCalendar->getTimeZone(); | |
643 | } | |
644 | // If calendar doesn't exists, create default timezone. | |
645 | // fCalendar is rarely null | |
646 | return *(TimeZone::createDefault()); | |
b75a7d8f A |
647 | } |
648 | ||
649 | //---------------------------------------------------------------------- | |
650 | ||
651 | void | |
652 | DateFormat::setLenient(UBool lenient) | |
653 | { | |
46f4442e A |
654 | if (fCalendar != NULL) { |
655 | fCalendar->setLenient(lenient); | |
656 | } | |
57a6839d A |
657 | UErrorCode status = U_ZERO_ERROR; |
658 | setBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, lenient, status); | |
659 | setBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, lenient, status); | |
b75a7d8f A |
660 | } |
661 | ||
662 | //---------------------------------------------------------------------- | |
663 | ||
664 | UBool | |
665 | DateFormat::isLenient() const | |
57a6839d A |
666 | { |
667 | UBool lenient = TRUE; | |
668 | if (fCalendar != NULL) { | |
669 | lenient = fCalendar->isLenient(); | |
670 | } | |
671 | UErrorCode status = U_ZERO_ERROR; | |
672 | return lenient | |
673 | && getBooleanAttribute(UDAT_PARSE_ALLOW_WHITESPACE, status) | |
674 | && getBooleanAttribute(UDAT_PARSE_ALLOW_NUMERIC, status); | |
675 | } | |
676 | ||
677 | void | |
678 | DateFormat::setCalendarLenient(UBool lenient) | |
679 | { | |
680 | if (fCalendar != NULL) { | |
681 | fCalendar->setLenient(lenient); | |
682 | } | |
683 | } | |
684 | ||
685 | //---------------------------------------------------------------------- | |
686 | ||
687 | UBool | |
688 | DateFormat::isCalendarLenient() const | |
b75a7d8f | 689 | { |
46f4442e A |
690 | if (fCalendar != NULL) { |
691 | return fCalendar->isLenient(); | |
692 | } | |
693 | // fCalendar is rarely null | |
694 | return FALSE; | |
b75a7d8f A |
695 | } |
696 | ||
57a6839d A |
697 | |
698 | //---------------------------------------------------------------------- | |
699 | ||
700 | ||
701 | void DateFormat::setContext(UDisplayContext value, UErrorCode& status) | |
702 | { | |
703 | if (U_FAILURE(status)) | |
704 | return; | |
705 | if ( (UDisplayContextType)((uint32_t)value >> 8) == UDISPCTX_TYPE_CAPITALIZATION ) { | |
706 | fCapitalizationContext = value; | |
707 | } else { | |
708 | status = U_ILLEGAL_ARGUMENT_ERROR; | |
709 | } | |
710 | } | |
711 | ||
712 | ||
713 | //---------------------------------------------------------------------- | |
714 | ||
715 | ||
716 | UDisplayContext DateFormat::getContext(UDisplayContextType type, UErrorCode& status) const | |
717 | { | |
718 | if (U_FAILURE(status)) | |
719 | return (UDisplayContext)0; | |
720 | if (type != UDISPCTX_TYPE_CAPITALIZATION) { | |
721 | status = U_ILLEGAL_ARGUMENT_ERROR; | |
722 | return (UDisplayContext)0; | |
723 | } | |
724 | return fCapitalizationContext; | |
725 | } | |
726 | ||
727 | ||
728 | //---------------------------------------------------------------------- | |
729 | ||
730 | ||
731 | DateFormat& | |
732 | DateFormat::setBooleanAttribute(UDateFormatBooleanAttribute attr, | |
733 | UBool newValue, | |
734 | UErrorCode &status) { | |
735 | if(!fBoolFlags.isValidValue(newValue)) { | |
736 | status = U_ILLEGAL_ARGUMENT_ERROR; | |
737 | } else { | |
738 | fBoolFlags.set(attr, newValue); | |
739 | } | |
740 | ||
741 | return *this; | |
742 | } | |
743 | ||
744 | //---------------------------------------------------------------------- | |
745 | ||
746 | UBool | |
747 | DateFormat::getBooleanAttribute(UDateFormatBooleanAttribute attr, UErrorCode &/*status*/) const { | |
748 | ||
0f5d89e8 | 749 | return static_cast<UBool>(fBoolFlags.get(attr)); |
57a6839d A |
750 | } |
751 | ||
b75a7d8f A |
752 | U_NAMESPACE_END |
753 | ||
754 | #endif /* #if !UCONFIG_NO_FORMATTING */ | |
755 | ||
756 | //eof |