]> git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/udat.cpp
ICU-59180.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / udat.cpp
1 // © 2016 and later: Unicode, Inc. and others.
2 // License & terms of use: http://www.unicode.org/copyright.html
3 /*
4 *******************************************************************************
5 * Copyright (C) 1996-2015, International Business Machines
6 * Corporation and others. All Rights Reserved.
7 *******************************************************************************
8 */
9
10 #include "unicode/utypes.h"
11
12 #if !UCONFIG_NO_FORMATTING
13
14 #include "unicode/udat.h"
15
16 #include "unicode/uloc.h"
17 #include "unicode/datefmt.h"
18 #include "unicode/timezone.h"
19 #include "unicode/smpdtfmt.h"
20 #include "unicode/fieldpos.h"
21 #include "unicode/parsepos.h"
22 #include "unicode/calendar.h"
23 #include "unicode/numfmt.h"
24 #include "unicode/dtfmtsym.h"
25 #include "unicode/ustring.h"
26 #include "unicode/udisplaycontext.h"
27 #include "unicode/ufieldpositer.h"
28 #include "unicode/ucasemap.h"
29 #include "cpputils.h"
30 #include "reldtfmt.h"
31 #include "umutex.h"
32
33 U_NAMESPACE_USE
34
35 /**
36 * Verify that fmt is a SimpleDateFormat. Invalid error if not.
37 * @param fmt the UDateFormat, definitely a DateFormat, maybe something else
38 * @param status error code, will be set to failure if there is a familure or the fmt is NULL.
39 */
40 static void verifyIsSimpleDateFormat(const UDateFormat* fmt, UErrorCode *status) {
41 if(U_SUCCESS(*status) &&
42 dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==NULL) {
43 *status = U_ILLEGAL_ARGUMENT_ERROR;
44 }
45 }
46
47 // This mirrors the correspondence between the
48 // SimpleDateFormat::fgPatternIndexToDateFormatField and
49 // SimpleDateFormat::fgPatternIndexToCalendarField arrays.
50 static UCalendarDateFields gDateFieldMapping[] = {
51 UCAL_ERA, // UDAT_ERA_FIELD = 0
52 UCAL_YEAR, // UDAT_YEAR_FIELD = 1
53 UCAL_MONTH, // UDAT_MONTH_FIELD = 2
54 UCAL_DATE, // UDAT_DATE_FIELD = 3
55 UCAL_HOUR_OF_DAY, // UDAT_HOUR_OF_DAY1_FIELD = 4
56 UCAL_HOUR_OF_DAY, // UDAT_HOUR_OF_DAY0_FIELD = 5
57 UCAL_MINUTE, // UDAT_MINUTE_FIELD = 6
58 UCAL_SECOND, // UDAT_SECOND_FIELD = 7
59 UCAL_MILLISECOND, // UDAT_FRACTIONAL_SECOND_FIELD = 8
60 UCAL_DAY_OF_WEEK, // UDAT_DAY_OF_WEEK_FIELD = 9
61 UCAL_DAY_OF_YEAR, // UDAT_DAY_OF_YEAR_FIELD = 10
62 UCAL_DAY_OF_WEEK_IN_MONTH, // UDAT_DAY_OF_WEEK_IN_MONTH_FIELD = 11
63 UCAL_WEEK_OF_YEAR, // UDAT_WEEK_OF_YEAR_FIELD = 12
64 UCAL_WEEK_OF_MONTH, // UDAT_WEEK_OF_MONTH_FIELD = 13
65 UCAL_AM_PM, // UDAT_AM_PM_FIELD = 14
66 UCAL_HOUR, // UDAT_HOUR1_FIELD = 15
67 UCAL_HOUR, // UDAT_HOUR0_FIELD = 16
68 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_FIELD = 17
69 UCAL_YEAR_WOY, // UDAT_YEAR_WOY_FIELD = 18
70 UCAL_DOW_LOCAL, // UDAT_DOW_LOCAL_FIELD = 19
71 UCAL_EXTENDED_YEAR, // UDAT_EXTENDED_YEAR_FIELD = 20
72 UCAL_JULIAN_DAY, // UDAT_JULIAN_DAY_FIELD = 21
73 UCAL_MILLISECONDS_IN_DAY, // UDAT_MILLISECONDS_IN_DAY_FIELD = 22
74 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_RFC_FIELD = 23 (also UCAL_DST_OFFSET)
75 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_GENERIC_FIELD = 24 (also UCAL_DST_OFFSET)
76 UCAL_DOW_LOCAL, // UDAT_STANDALONE_DAY_FIELD = 25
77 UCAL_MONTH, // UDAT_STANDALONE_MONTH_FIELD = 26
78 UCAL_MONTH, // UDAT_QUARTER_FIELD = 27
79 UCAL_MONTH, // UDAT_STANDALONE_QUARTER_FIELD = 28
80 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_SPECIAL_FIELD = 29 (also UCAL_DST_OFFSET)
81 UCAL_YEAR, // UDAT_YEAR_NAME_FIELD = 30
82 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_LOCALIZED_GMT_OFFSET_FIELD = 31 (also UCAL_DST_OFFSET)
83 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_ISO_FIELD = 32 (also UCAL_DST_OFFSET)
84 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_ISO_LOCAL_FIELD = 33 (also UCAL_DST_OFFSET)
85 UCAL_EXTENDED_YEAR, // UDAT_RELATED_YEAR_FIELD = 34 (not an exact match)
86 UCAL_FIELD_COUNT, // UDAT_FIELD_COUNT = 35
87 // UCAL_IS_LEAP_MONTH is not the target of a mapping
88 };
89
90 U_CAPI UCalendarDateFields U_EXPORT2
91 udat_toCalendarDateField(UDateFormatField field) {
92 return gDateFieldMapping[field];
93 }
94
95 /* For now- one opener. */
96 static UDateFormatOpener gOpener = NULL;
97
98 U_INTERNAL void U_EXPORT2
99 udat_registerOpener(UDateFormatOpener opener, UErrorCode *status)
100 {
101 if(U_FAILURE(*status)) return;
102 umtx_lock(NULL);
103 if(gOpener==NULL) {
104 gOpener = opener;
105 } else {
106 *status = U_ILLEGAL_ARGUMENT_ERROR;
107 }
108 umtx_unlock(NULL);
109 }
110
111 U_INTERNAL UDateFormatOpener U_EXPORT2
112 udat_unregisterOpener(UDateFormatOpener opener, UErrorCode *status)
113 {
114 if(U_FAILURE(*status)) return NULL;
115 UDateFormatOpener oldOpener = NULL;
116 umtx_lock(NULL);
117 if(gOpener==NULL || gOpener!=opener) {
118 *status = U_ILLEGAL_ARGUMENT_ERROR;
119 } else {
120 oldOpener=gOpener;
121 gOpener=NULL;
122 }
123 umtx_unlock(NULL);
124 return oldOpener;
125 }
126
127
128
129 U_CAPI UDateFormat* U_EXPORT2
130 udat_open(UDateFormatStyle timeStyle,
131 UDateFormatStyle dateStyle,
132 const char *locale,
133 const UChar *tzID,
134 int32_t tzIDLength,
135 const UChar *pattern,
136 int32_t patternLength,
137 UErrorCode *status)
138 {
139 DateFormat *fmt;
140 if(U_FAILURE(*status)) {
141 return 0;
142 }
143 if(gOpener!=NULL) { // if it's registered
144 fmt = (DateFormat*) (*gOpener)(timeStyle,dateStyle,locale,tzID,tzIDLength,pattern,patternLength,status);
145 if(fmt!=NULL) {
146 return (UDateFormat*)fmt;
147 } // else fall through.
148 }
149 if(timeStyle != UDAT_PATTERN) {
150 if(locale == 0) {
151 fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
152 (DateFormat::EStyle)timeStyle);
153 }
154 else {
155 fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
156 (DateFormat::EStyle)timeStyle,
157 Locale(locale));
158 }
159 }
160 else {
161 UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength);
162
163 if(locale == 0) {
164 fmt = new SimpleDateFormat(pat, *status);
165 }
166 else {
167 fmt = new SimpleDateFormat(pat, Locale(locale), *status);
168 }
169 }
170
171 if(fmt == 0) {
172 *status = U_MEMORY_ALLOCATION_ERROR;
173 return 0;
174 }
175
176 if(tzID != 0) {
177 TimeZone *zone = TimeZone::createTimeZone(UnicodeString((UBool)(tzIDLength == -1), tzID, tzIDLength));
178 if(zone == 0) {
179 *status = U_MEMORY_ALLOCATION_ERROR;
180 delete fmt;
181 return 0;
182 }
183 fmt->adoptTimeZone(zone);
184 }
185
186 return (UDateFormat*)fmt;
187 }
188
189
190 U_CAPI void U_EXPORT2
191 udat_close(UDateFormat* format)
192 {
193 delete (DateFormat*)format;
194 }
195
196 U_CAPI UDateFormat* U_EXPORT2
197 udat_clone(const UDateFormat *fmt,
198 UErrorCode *status)
199 {
200 if(U_FAILURE(*status)) return 0;
201
202 Format *res = ((DateFormat*)fmt)->clone();
203
204 if(res == 0) {
205 *status = U_MEMORY_ALLOCATION_ERROR;
206 return 0;
207 }
208
209 return (UDateFormat*) res;
210 }
211
212 U_CAPI int32_t U_EXPORT2
213 udat_format( const UDateFormat* format,
214 UDate dateToFormat,
215 UChar* result,
216 int32_t resultLength,
217 UFieldPosition* position,
218 UErrorCode* status)
219 {
220 if(U_FAILURE(*status)) {
221 return -1;
222 }
223 if (result == NULL ? resultLength != 0 : resultLength < 0) {
224 *status = U_ILLEGAL_ARGUMENT_ERROR;
225 return -1;
226 }
227
228 UnicodeString res;
229 if (result != NULL) {
230 // NULL destination for pure preflighting: empty dummy string
231 // otherwise, alias the destination buffer
232 res.setTo(result, 0, resultLength);
233 }
234
235 FieldPosition fp;
236
237 if(position != 0)
238 fp.setField(position->field);
239
240 ((DateFormat*)format)->format(dateToFormat, res, fp);
241
242 if(position != 0) {
243 position->beginIndex = fp.getBeginIndex();
244 position->endIndex = fp.getEndIndex();
245 }
246
247 return res.extract(result, resultLength, *status);
248 }
249
250 U_CAPI int32_t U_EXPORT2
251 udat_formatCalendar(const UDateFormat* format,
252 UCalendar* calendar,
253 UChar* result,
254 int32_t resultLength,
255 UFieldPosition* position,
256 UErrorCode* status)
257 {
258 if(U_FAILURE(*status)) {
259 return -1;
260 }
261 if (result == NULL ? resultLength != 0 : resultLength < 0) {
262 *status = U_ILLEGAL_ARGUMENT_ERROR;
263 return -1;
264 }
265
266 UnicodeString res;
267 if (result != NULL) {
268 // NULL destination for pure preflighting: empty dummy string
269 // otherwise, alias the destination buffer
270 res.setTo(result, 0, resultLength);
271 }
272
273 FieldPosition fp;
274
275 if(position != 0)
276 fp.setField(position->field);
277
278 ((DateFormat*)format)->format(*(Calendar*)calendar, res, fp);
279
280 if(position != 0) {
281 position->beginIndex = fp.getBeginIndex();
282 position->endIndex = fp.getEndIndex();
283 }
284
285 return res.extract(result, resultLength, *status);
286 }
287
288 U_CAPI int32_t U_EXPORT2
289 udat_formatForFields( const UDateFormat* format,
290 UDate dateToFormat,
291 UChar* result,
292 int32_t resultLength,
293 UFieldPositionIterator* fpositer,
294 UErrorCode* status)
295 {
296 if(U_FAILURE(*status)) {
297 return -1;
298 }
299 if (result == NULL ? resultLength != 0 : resultLength < 0) {
300 *status = U_ILLEGAL_ARGUMENT_ERROR;
301 return -1;
302 }
303
304 UnicodeString res;
305 if (result != NULL) {
306 // NULL destination for pure preflighting: empty dummy string
307 // otherwise, alias the destination buffer
308 res.setTo(result, 0, resultLength);
309 }
310
311 ((DateFormat*)format)->format(dateToFormat, res, (FieldPositionIterator*)fpositer, *status);
312
313 return res.extract(result, resultLength, *status);
314 }
315
316 U_CAPI int32_t U_EXPORT2
317 udat_formatCalendarForFields(const UDateFormat* format,
318 UCalendar* calendar,
319 UChar* result,
320 int32_t resultLength,
321 UFieldPositionIterator* fpositer,
322 UErrorCode* status)
323 {
324 if(U_FAILURE(*status)) {
325 return -1;
326 }
327 if (result == NULL ? resultLength != 0 : resultLength < 0) {
328 *status = U_ILLEGAL_ARGUMENT_ERROR;
329 return -1;
330 }
331
332 UnicodeString res;
333 if (result != NULL) {
334 // NULL destination for pure preflighting: empty dummy string
335 // otherwise, alias the destination buffer
336 res.setTo(result, 0, resultLength);
337 }
338
339 ((DateFormat*)format)->format(*(Calendar*)calendar, res, (FieldPositionIterator*)fpositer, *status);
340
341 return res.extract(result, resultLength, *status);
342 }
343
344 U_CAPI UDate U_EXPORT2
345 udat_parse( const UDateFormat* format,
346 const UChar* text,
347 int32_t textLength,
348 int32_t *parsePos,
349 UErrorCode *status)
350 {
351 if(U_FAILURE(*status)) return (UDate)0;
352
353 const UnicodeString src((UBool)(textLength == -1), text, textLength);
354 ParsePosition pp;
355 int32_t stackParsePos = 0;
356 UDate res;
357
358 if(parsePos == NULL) {
359 parsePos = &stackParsePos;
360 }
361
362 pp.setIndex(*parsePos);
363
364 res = ((DateFormat*)format)->parse(src, pp);
365
366 if(pp.getErrorIndex() == -1)
367 *parsePos = pp.getIndex();
368 else {
369 *parsePos = pp.getErrorIndex();
370 *status = U_PARSE_ERROR;
371 }
372
373 return res;
374 }
375
376 U_CAPI void U_EXPORT2
377 udat_parseCalendar(const UDateFormat* format,
378 UCalendar* calendar,
379 const UChar* text,
380 int32_t textLength,
381 int32_t *parsePos,
382 UErrorCode *status)
383 {
384 if(U_FAILURE(*status)) return;
385
386 const UnicodeString src((UBool)(textLength == -1), text, textLength);
387 ParsePosition pp;
388 int32_t stackParsePos = 0;
389
390 if(parsePos == NULL) {
391 parsePos = &stackParsePos;
392 }
393
394 pp.setIndex(*parsePos);
395
396 ((DateFormat*)format)->parse(src, *(Calendar*)calendar, pp);
397
398 if(pp.getErrorIndex() == -1)
399 *parsePos = pp.getIndex();
400 else {
401 *parsePos = pp.getErrorIndex();
402 *status = U_PARSE_ERROR;
403 }
404 }
405
406 U_CAPI UBool U_EXPORT2
407 udat_isLenient(const UDateFormat* fmt)
408 {
409 return ((DateFormat*)fmt)->isLenient();
410 }
411
412 U_CAPI void U_EXPORT2
413 udat_setLenient( UDateFormat* fmt,
414 UBool isLenient)
415 {
416 ((DateFormat*)fmt)->setLenient(isLenient);
417 }
418
419 U_DRAFT UBool U_EXPORT2
420 udat_getBooleanAttribute(const UDateFormat* fmt,
421 UDateFormatBooleanAttribute attr,
422 UErrorCode* status)
423 {
424 if(U_FAILURE(*status)) return FALSE;
425 return ((DateFormat*)fmt)->getBooleanAttribute(attr, *status);
426 //return FALSE;
427 }
428
429 U_DRAFT void U_EXPORT2
430 udat_setBooleanAttribute(UDateFormat *fmt,
431 UDateFormatBooleanAttribute attr,
432 UBool newValue,
433 UErrorCode* status)
434 {
435 if(U_FAILURE(*status)) return;
436 ((DateFormat*)fmt)->setBooleanAttribute(attr, newValue, *status);
437 }
438
439 U_CAPI const UCalendar* U_EXPORT2
440 udat_getCalendar(const UDateFormat* fmt)
441 {
442 return (const UCalendar*) ((DateFormat*)fmt)->getCalendar();
443 }
444
445 U_CAPI void U_EXPORT2
446 udat_setCalendar(UDateFormat* fmt,
447 const UCalendar* calendarToSet)
448 {
449 ((DateFormat*)fmt)->setCalendar(*((Calendar*)calendarToSet));
450 }
451
452 U_DRAFT const UNumberFormat* U_EXPORT2
453 udat_getNumberFormatForField(const UDateFormat* fmt, UChar field)
454 {
455 UErrorCode status = U_ZERO_ERROR;
456 verifyIsSimpleDateFormat(fmt, &status);
457 if (U_FAILURE(status)) return (const UNumberFormat*) ((DateFormat*)fmt)->getNumberFormat();
458 return (const UNumberFormat*) ((SimpleDateFormat*)fmt)->getNumberFormatForField(field);
459 }
460
461 U_CAPI const UNumberFormat* U_EXPORT2
462 udat_getNumberFormat(const UDateFormat* fmt)
463 {
464 return (const UNumberFormat*) ((DateFormat*)fmt)->getNumberFormat();
465 }
466
467 U_DRAFT void U_EXPORT2
468 udat_adoptNumberFormatForFields( UDateFormat* fmt,
469 const UChar* fields,
470 UNumberFormat* numberFormatToSet,
471 UErrorCode* status)
472 {
473 verifyIsSimpleDateFormat(fmt, status);
474 if (U_FAILURE(*status)) return;
475
476 if (fields!=NULL) {
477 UnicodeString overrideFields(fields);
478 ((SimpleDateFormat*)fmt)->adoptNumberFormat(overrideFields, (NumberFormat*)numberFormatToSet, *status);
479 }
480 }
481
482 U_CAPI void U_EXPORT2
483 udat_setNumberFormat(UDateFormat* fmt,
484 const UNumberFormat* numberFormatToSet)
485 {
486 ((DateFormat*)fmt)->setNumberFormat(*((NumberFormat*)numberFormatToSet));
487 }
488
489 U_DRAFT void U_EXPORT2
490 udat_adoptNumberFormat( UDateFormat* fmt,
491 UNumberFormat* numberFormatToAdopt)
492 {
493 ((DateFormat*)fmt)->adoptNumberFormat((NumberFormat*)numberFormatToAdopt);
494 }
495
496 U_CAPI const char* U_EXPORT2
497 udat_getAvailable(int32_t index)
498 {
499 return uloc_getAvailable(index);
500 }
501
502 U_CAPI int32_t U_EXPORT2
503 udat_countAvailable()
504 {
505 return uloc_countAvailable();
506 }
507
508 U_CAPI UDate U_EXPORT2
509 udat_get2DigitYearStart( const UDateFormat *fmt,
510 UErrorCode *status)
511 {
512 verifyIsSimpleDateFormat(fmt, status);
513 if(U_FAILURE(*status)) return (UDate)0;
514 return ((SimpleDateFormat*)fmt)->get2DigitYearStart(*status);
515 }
516
517 U_CAPI void U_EXPORT2
518 udat_set2DigitYearStart( UDateFormat *fmt,
519 UDate d,
520 UErrorCode *status)
521 {
522 verifyIsSimpleDateFormat(fmt, status);
523 if(U_FAILURE(*status)) return;
524 ((SimpleDateFormat*)fmt)->set2DigitYearStart(d, *status);
525 }
526
527 U_CAPI int32_t U_EXPORT2
528 udat_toPattern( const UDateFormat *fmt,
529 UBool localized,
530 UChar *result,
531 int32_t resultLength,
532 UErrorCode *status)
533 {
534 if(U_FAILURE(*status)) {
535 return -1;
536 }
537 if (result == NULL ? resultLength != 0 : resultLength < 0) {
538 *status = U_ILLEGAL_ARGUMENT_ERROR;
539 return -1;
540 }
541
542 UnicodeString res;
543 if (result != NULL) {
544 // NULL destination for pure preflighting: empty dummy string
545 // otherwise, alias the destination buffer
546 res.setTo(result, 0, resultLength);
547 }
548
549 const DateFormat *df=reinterpret_cast<const DateFormat *>(fmt);
550 const SimpleDateFormat *sdtfmt=dynamic_cast<const SimpleDateFormat *>(df);
551 const RelativeDateFormat *reldtfmt;
552 if (sdtfmt!=NULL) {
553 if(localized)
554 sdtfmt->toLocalizedPattern(res, *status);
555 else
556 sdtfmt->toPattern(res);
557 } else if (!localized && (reldtfmt=dynamic_cast<const RelativeDateFormat *>(df))!=NULL) {
558 reldtfmt->toPattern(res, *status);
559 } else {
560 *status = U_ILLEGAL_ARGUMENT_ERROR;
561 return -1;
562 }
563
564 return res.extract(result, resultLength, *status);
565 }
566
567 // TODO: should this take an UErrorCode?
568 // A: Yes. Of course.
569 U_CAPI void U_EXPORT2
570 udat_applyPattern( UDateFormat *format,
571 UBool localized,
572 const UChar *pattern,
573 int32_t patternLength)
574 {
575 const UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength);
576 UErrorCode status = U_ZERO_ERROR;
577
578 verifyIsSimpleDateFormat(format, &status);
579 if(U_FAILURE(status)) {
580 return;
581 }
582
583 if(localized)
584 ((SimpleDateFormat*)format)->applyLocalizedPattern(pat, status);
585 else
586 ((SimpleDateFormat*)format)->applyPattern(pat);
587 }
588
589 // Apple addition
590 static DateFormatSymbols::ECapitalizationContextUsageType capUsageFromSymbolType(UDateFormatSymbolType type)
591 {
592 DateFormatSymbols::ECapitalizationContextUsageType capContextUsageType = DateFormatSymbols::kCapContextUsageOther;
593 switch (type) {
594 case UDAT_ERA_NAMES:
595 capContextUsageType = DateFormatSymbols::kCapContextUsageEraWide;
596 break;
597 case UDAT_ERAS:
598 capContextUsageType = DateFormatSymbols::kCapContextUsageEraAbbrev;
599 break;
600 case UDAT_MONTHS:
601 case UDAT_SHORT_MONTHS:
602 capContextUsageType = DateFormatSymbols::kCapContextUsageMonthFormat;
603 break;
604 case UDAT_STANDALONE_MONTHS:
605 case UDAT_STANDALONE_SHORT_MONTHS:
606 capContextUsageType = DateFormatSymbols::kCapContextUsageMonthStandalone;
607 break;
608 case UDAT_NARROW_MONTHS:
609 case UDAT_STANDALONE_NARROW_MONTHS:
610 capContextUsageType = DateFormatSymbols::kCapContextUsageMonthNarrow;
611 break;
612 case UDAT_WEEKDAYS:
613 case UDAT_SHORT_WEEKDAYS:
614 case UDAT_SHORTER_WEEKDAYS:
615 capContextUsageType = DateFormatSymbols::kCapContextUsageDayFormat;
616 break;
617 case UDAT_STANDALONE_WEEKDAYS:
618 case UDAT_STANDALONE_SHORT_WEEKDAYS:
619 case UDAT_STANDALONE_SHORTER_WEEKDAYS:
620 capContextUsageType = DateFormatSymbols::kCapContextUsageDayStandalone;
621 break;
622 case UDAT_STANDALONE_NARROW_WEEKDAYS:
623 case UDAT_NARROW_WEEKDAYS:
624 capContextUsageType = DateFormatSymbols::kCapContextUsageDayNarrow;
625 break;
626 default:
627 break;
628 }
629 return capContextUsageType;
630 }
631
632
633
634 U_CAPI int32_t U_EXPORT2
635 udat_getSymbols(const UDateFormat *fmt,
636 UDateFormatSymbolType type,
637 int32_t index,
638 UChar *result,
639 int32_t resultLength,
640 UErrorCode *status)
641 {
642 const DateFormatSymbols *syms;
643 const SimpleDateFormat* sdtfmt;
644 const RelativeDateFormat* rdtfmt;
645 BreakIterator* capitalizationBrkIter;
646 if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
647 syms = sdtfmt->getDateFormatSymbols();
648 capitalizationBrkIter = sdtfmt->getCapitalizationBrkIter();
649 } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
650 syms = rdtfmt->getDateFormatSymbols();
651 capitalizationBrkIter = rdtfmt->getCapitalizationBrkIter();
652 } else {
653 return -1;
654 }
655 int32_t count;
656 const UnicodeString *res = NULL;
657
658 switch(type) {
659 case UDAT_ERAS:
660 res = syms->getEras(count);
661 break;
662
663 case UDAT_ERA_NAMES:
664 res = syms->getEraNames(count);
665 break;
666
667 case UDAT_MONTHS:
668 res = syms->getMonths(count);
669 break;
670
671 case UDAT_SHORT_MONTHS:
672 res = syms->getShortMonths(count);
673 break;
674
675 case UDAT_WEEKDAYS:
676 res = syms->getWeekdays(count);
677 break;
678
679 case UDAT_SHORT_WEEKDAYS:
680 res = syms->getShortWeekdays(count);
681 break;
682
683 case UDAT_AM_PMS:
684 res = syms->getAmPmStrings(count);
685 break;
686
687 case UDAT_LOCALIZED_CHARS:
688 {
689 UnicodeString res1;
690 if(!(result==NULL && resultLength==0)) {
691 // NULL destination for pure preflighting: empty dummy string
692 // otherwise, alias the destination buffer
693 res1.setTo(result, 0, resultLength);
694 }
695 syms->getLocalPatternChars(res1);
696 return res1.extract(result, resultLength, *status);
697 }
698
699 case UDAT_NARROW_MONTHS:
700 res = syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
701 break;
702
703 case UDAT_SHORTER_WEEKDAYS:
704 res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT);
705 break;
706
707 case UDAT_NARROW_WEEKDAYS:
708 res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
709 break;
710
711 case UDAT_STANDALONE_MONTHS:
712 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
713 break;
714
715 case UDAT_STANDALONE_SHORT_MONTHS:
716 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
717 break;
718
719 case UDAT_STANDALONE_NARROW_MONTHS:
720 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
721 break;
722
723 case UDAT_STANDALONE_WEEKDAYS:
724 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
725 break;
726
727 case UDAT_STANDALONE_SHORT_WEEKDAYS:
728 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
729 break;
730
731 case UDAT_STANDALONE_SHORTER_WEEKDAYS:
732 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT);
733 break;
734
735 case UDAT_STANDALONE_NARROW_WEEKDAYS:
736 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
737 break;
738
739 case UDAT_QUARTERS:
740 res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
741 break;
742
743 case UDAT_SHORT_QUARTERS:
744 res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
745 break;
746
747 case UDAT_STANDALONE_QUARTERS:
748 res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
749 break;
750
751 case UDAT_STANDALONE_SHORT_QUARTERS:
752 res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
753 break;
754
755 case UDAT_CYCLIC_YEARS_WIDE:
756 res = syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
757 break;
758
759 case UDAT_CYCLIC_YEARS_ABBREVIATED:
760 res = syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
761 break;
762
763 case UDAT_CYCLIC_YEARS_NARROW:
764 res = syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
765 break;
766
767 case UDAT_ZODIAC_NAMES_WIDE:
768 res = syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
769 break;
770
771 case UDAT_ZODIAC_NAMES_ABBREVIATED:
772 res = syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
773 break;
774
775 case UDAT_ZODIAC_NAMES_NARROW:
776 res = syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
777 break;
778
779 case UADAT_CYCLIC_ZODIAC_NAMES:
780 res = syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
781 index = (index > 0)? (index - 1) % 12: 0;
782 break;
783
784 }
785
786 if(index < count) {
787 #if !UCONFIG_NO_BREAK_ITERATION
788 // Apple addition for <rdar://problem/27335144>
789 if (u_islower(res[index].char32At(0)) && capitalizationBrkIter != NULL) {
790 UDisplayContext capitalizationContext = ((const DateFormat*)fmt)->getContext(UDISPCTX_TYPE_CAPITALIZATION, *status);
791 UBool titlecase = FALSE;
792 switch (capitalizationContext) {
793 case UDISPCTX_CAPITALIZATION_FOR_BEGINNING_OF_SENTENCE:
794 titlecase = TRUE;
795 break;
796 case UDISPCTX_CAPITALIZATION_FOR_UI_LIST_OR_MENU:
797 titlecase = syms->capitalizeForUsage(capUsageFromSymbolType(type), 0);
798 break;
799 case UDISPCTX_CAPITALIZATION_FOR_STANDALONE:
800 titlecase = syms->capitalizeForUsage(capUsageFromSymbolType(type), 1);
801 break;
802 default:
803 // titlecase = FALSE;
804 break;
805 }
806 if (titlecase) {
807 UnicodeString symbolToModify(res[index]);
808 BreakIterator* capBrkIterToUse = capitalizationBrkIter->clone();
809 if (capBrkIterToUse != NULL) {
810 Locale locale = capBrkIterToUse->getLocale(ULOC_ACTUAL_LOCALE, *status);
811 if (U_SUCCESS(*status)) {
812 symbolToModify.toTitle(capBrkIterToUse, locale, U_TITLECASE_NO_LOWERCASE | U_TITLECASE_NO_BREAK_ADJUSTMENT);
813 delete capBrkIterToUse;
814 return symbolToModify.extract(result, resultLength, *status);
815 }
816 delete capBrkIterToUse;
817 }
818 }
819 }
820 #endif
821 return res[index].extract(result, resultLength, *status);
822 }
823 return 0;
824 }
825
826 // TODO: also needs an errorCode.
827 U_CAPI int32_t U_EXPORT2
828 udat_countSymbols( const UDateFormat *fmt,
829 UDateFormatSymbolType type)
830 {
831 const DateFormatSymbols *syms;
832 const SimpleDateFormat* sdtfmt;
833 const RelativeDateFormat* rdtfmt;
834 if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
835 syms = sdtfmt->getDateFormatSymbols();
836 } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
837 syms = rdtfmt->getDateFormatSymbols();
838 } else {
839 return 0;
840 }
841 int32_t count = 0;
842
843 switch(type) {
844 case UDAT_ERAS:
845 syms->getEras(count);
846 break;
847
848 case UDAT_MONTHS:
849 syms->getMonths(count);
850 break;
851
852 case UDAT_SHORT_MONTHS:
853 syms->getShortMonths(count);
854 break;
855
856 case UDAT_WEEKDAYS:
857 syms->getWeekdays(count);
858 break;
859
860 case UDAT_SHORT_WEEKDAYS:
861 syms->getShortWeekdays(count);
862 break;
863
864 case UDAT_AM_PMS:
865 syms->getAmPmStrings(count);
866 break;
867
868 case UDAT_LOCALIZED_CHARS:
869 count = 1;
870 break;
871
872 case UDAT_ERA_NAMES:
873 syms->getEraNames(count);
874 break;
875
876 case UDAT_NARROW_MONTHS:
877 syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
878 break;
879
880 case UDAT_SHORTER_WEEKDAYS:
881 syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT);
882 break;
883
884 case UDAT_NARROW_WEEKDAYS:
885 syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
886 break;
887
888 case UDAT_STANDALONE_MONTHS:
889 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
890 break;
891
892 case UDAT_STANDALONE_SHORT_MONTHS:
893 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
894 break;
895
896 case UDAT_STANDALONE_NARROW_MONTHS:
897 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
898 break;
899
900 case UDAT_STANDALONE_WEEKDAYS:
901 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
902 break;
903
904 case UDAT_STANDALONE_SHORT_WEEKDAYS:
905 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
906 break;
907
908 case UDAT_STANDALONE_SHORTER_WEEKDAYS:
909 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT);
910 break;
911
912 case UDAT_STANDALONE_NARROW_WEEKDAYS:
913 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
914 break;
915
916 case UDAT_QUARTERS:
917 syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
918 break;
919
920 case UDAT_SHORT_QUARTERS:
921 syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
922 break;
923
924 case UDAT_STANDALONE_QUARTERS:
925 syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
926 break;
927
928 case UDAT_STANDALONE_SHORT_QUARTERS:
929 syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
930 break;
931
932 case UDAT_CYCLIC_YEARS_WIDE:
933 syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
934 break;
935
936 case UDAT_CYCLIC_YEARS_ABBREVIATED:
937 syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
938 break;
939
940 case UDAT_CYCLIC_YEARS_NARROW:
941 syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
942 break;
943
944 case UDAT_ZODIAC_NAMES_WIDE:
945 syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
946 break;
947
948 case UDAT_ZODIAC_NAMES_ABBREVIATED:
949 syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
950 break;
951
952 case UDAT_ZODIAC_NAMES_NARROW:
953 syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
954 break;
955
956 case UADAT_CYCLIC_ZODIAC_NAMES:
957 syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
958 break;
959
960 }
961
962 return count;
963 }
964
965 U_NAMESPACE_BEGIN
966
967 /*
968 * This DateFormatSymbolsSingleSetter class is a friend of DateFormatSymbols
969 * solely for the purpose of avoiding to clone the array of strings
970 * just to modify one of them and then setting all of them back.
971 * For example, the old code looked like this:
972 * case UDAT_MONTHS:
973 * res = syms->getMonths(count);
974 * array = new UnicodeString[count];
975 * if(array == 0) {
976 * *status = U_MEMORY_ALLOCATION_ERROR;
977 * return;
978 * }
979 * uprv_arrayCopy(res, array, count);
980 * if(index < count)
981 * array[index] = val;
982 * syms->setMonths(array, count);
983 * break;
984 *
985 * Even worse, the old code actually cloned the entire DateFormatSymbols object,
986 * cloned one value array, changed one value, and then made the SimpleDateFormat
987 * replace its DateFormatSymbols object with the new one.
988 *
989 * markus 2002-oct-14
990 */
991 class DateFormatSymbolsSingleSetter /* not : public UObject because all methods are static */ {
992 public:
993 static void
994 setSymbol(UnicodeString *array, int32_t count, int32_t index,
995 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
996 {
997 if(array!=NULL) {
998 if(index>=count) {
999 errorCode=U_INDEX_OUTOFBOUNDS_ERROR;
1000 } else if(value==NULL) {
1001 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
1002 } else {
1003 array[index].setTo(value, valueLength);
1004 }
1005 }
1006 }
1007
1008 static void
1009 setEra(DateFormatSymbols *syms, int32_t index,
1010 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1011 {
1012 setSymbol(syms->fEras, syms->fErasCount, index, value, valueLength, errorCode);
1013 }
1014
1015 static void
1016 setEraName(DateFormatSymbols *syms, int32_t index,
1017 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1018 {
1019 setSymbol(syms->fEraNames, syms->fEraNamesCount, index, value, valueLength, errorCode);
1020 }
1021
1022 static void
1023 setMonth(DateFormatSymbols *syms, int32_t index,
1024 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1025 {
1026 setSymbol(syms->fMonths, syms->fMonthsCount, index, value, valueLength, errorCode);
1027 }
1028
1029 static void
1030 setShortMonth(DateFormatSymbols *syms, int32_t index,
1031 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1032 {
1033 setSymbol(syms->fShortMonths, syms->fShortMonthsCount, index, value, valueLength, errorCode);
1034 }
1035
1036 static void
1037 setNarrowMonth(DateFormatSymbols *syms, int32_t index,
1038 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1039 {
1040 setSymbol(syms->fNarrowMonths, syms->fNarrowMonthsCount, index, value, valueLength, errorCode);
1041 }
1042
1043 static void
1044 setStandaloneMonth(DateFormatSymbols *syms, int32_t index,
1045 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1046 {
1047 setSymbol(syms->fStandaloneMonths, syms->fStandaloneMonthsCount, index, value, valueLength, errorCode);
1048 }
1049
1050 static void
1051 setStandaloneShortMonth(DateFormatSymbols *syms, int32_t index,
1052 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1053 {
1054 setSymbol(syms->fStandaloneShortMonths, syms->fStandaloneShortMonthsCount, index, value, valueLength, errorCode);
1055 }
1056
1057 static void
1058 setStandaloneNarrowMonth(DateFormatSymbols *syms, int32_t index,
1059 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1060 {
1061 setSymbol(syms->fStandaloneNarrowMonths, syms->fStandaloneNarrowMonthsCount, index, value, valueLength, errorCode);
1062 }
1063
1064 static void
1065 setWeekday(DateFormatSymbols *syms, int32_t index,
1066 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1067 {
1068 setSymbol(syms->fWeekdays, syms->fWeekdaysCount, index, value, valueLength, errorCode);
1069 }
1070
1071 static void
1072 setShortWeekday(DateFormatSymbols *syms, int32_t index,
1073 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1074 {
1075 setSymbol(syms->fShortWeekdays, syms->fShortWeekdaysCount, index, value, valueLength, errorCode);
1076 }
1077
1078 static void
1079 setShorterWeekday(DateFormatSymbols *syms, int32_t index,
1080 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1081 {
1082 setSymbol(syms->fShorterWeekdays, syms->fShorterWeekdaysCount, index, value, valueLength, errorCode);
1083 }
1084
1085 static void
1086 setNarrowWeekday(DateFormatSymbols *syms, int32_t index,
1087 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1088 {
1089 setSymbol(syms->fNarrowWeekdays, syms->fNarrowWeekdaysCount, index, value, valueLength, errorCode);
1090 }
1091
1092 static void
1093 setStandaloneWeekday(DateFormatSymbols *syms, int32_t index,
1094 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1095 {
1096 setSymbol(syms->fStandaloneWeekdays, syms->fStandaloneWeekdaysCount, index, value, valueLength, errorCode);
1097 }
1098
1099 static void
1100 setStandaloneShortWeekday(DateFormatSymbols *syms, int32_t index,
1101 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1102 {
1103 setSymbol(syms->fStandaloneShortWeekdays, syms->fStandaloneShortWeekdaysCount, index, value, valueLength, errorCode);
1104 }
1105
1106 static void
1107 setStandaloneShorterWeekday(DateFormatSymbols *syms, int32_t index,
1108 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1109 {
1110 setSymbol(syms->fStandaloneShorterWeekdays, syms->fStandaloneShorterWeekdaysCount, index, value, valueLength, errorCode);
1111 }
1112
1113 static void
1114 setStandaloneNarrowWeekday(DateFormatSymbols *syms, int32_t index,
1115 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1116 {
1117 setSymbol(syms->fStandaloneNarrowWeekdays, syms->fStandaloneNarrowWeekdaysCount, index, value, valueLength, errorCode);
1118 }
1119
1120 static void
1121 setQuarter(DateFormatSymbols *syms, int32_t index,
1122 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1123 {
1124 setSymbol(syms->fQuarters, syms->fQuartersCount, index, value, valueLength, errorCode);
1125 }
1126
1127 static void
1128 setShortQuarter(DateFormatSymbols *syms, int32_t index,
1129 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1130 {
1131 setSymbol(syms->fShortQuarters, syms->fShortQuartersCount, index, value, valueLength, errorCode);
1132 }
1133
1134 static void
1135 setStandaloneQuarter(DateFormatSymbols *syms, int32_t index,
1136 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1137 {
1138 setSymbol(syms->fStandaloneQuarters, syms->fStandaloneQuartersCount, index, value, valueLength, errorCode);
1139 }
1140
1141 static void
1142 setStandaloneShortQuarter(DateFormatSymbols *syms, int32_t index,
1143 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1144 {
1145 setSymbol(syms->fStandaloneShortQuarters, syms->fStandaloneShortQuartersCount, index, value, valueLength, errorCode);
1146 }
1147
1148 static void
1149 setShortYearNames(DateFormatSymbols *syms, int32_t index,
1150 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1151 {
1152 setSymbol(syms->fShortYearNames, syms->fShortYearNamesCount, index, value, valueLength, errorCode);
1153 }
1154
1155 static void
1156 setShortZodiacNames(DateFormatSymbols *syms, int32_t index,
1157 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1158 {
1159 setSymbol(syms->fShortZodiacNames, syms->fShortZodiacNamesCount, index, value, valueLength, errorCode);
1160 }
1161
1162 static void
1163 setAmPm(DateFormatSymbols *syms, int32_t index,
1164 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1165 {
1166 setSymbol(syms->fAmPms, syms->fAmPmsCount, index, value, valueLength, errorCode);
1167 }
1168
1169 static void
1170 setLocalPatternChars(DateFormatSymbols *syms,
1171 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1172 {
1173 setSymbol(&syms->fLocalPatternChars, 1, 0, value, valueLength, errorCode);
1174 }
1175 };
1176
1177 U_NAMESPACE_END
1178
1179 U_CAPI void U_EXPORT2
1180 udat_setSymbols( UDateFormat *format,
1181 UDateFormatSymbolType type,
1182 int32_t index,
1183 UChar *value,
1184 int32_t valueLength,
1185 UErrorCode *status)
1186 {
1187 verifyIsSimpleDateFormat(format, status);
1188 if(U_FAILURE(*status)) return;
1189
1190 DateFormatSymbols *syms = (DateFormatSymbols *)((SimpleDateFormat *)format)->getDateFormatSymbols();
1191
1192 switch(type) {
1193 case UDAT_ERAS:
1194 DateFormatSymbolsSingleSetter::setEra(syms, index, value, valueLength, *status);
1195 break;
1196
1197 case UDAT_ERA_NAMES:
1198 DateFormatSymbolsSingleSetter::setEraName(syms, index, value, valueLength, *status);
1199 break;
1200
1201 case UDAT_MONTHS:
1202 DateFormatSymbolsSingleSetter::setMonth(syms, index, value, valueLength, *status);
1203 break;
1204
1205 case UDAT_SHORT_MONTHS:
1206 DateFormatSymbolsSingleSetter::setShortMonth(syms, index, value, valueLength, *status);
1207 break;
1208
1209 case UDAT_NARROW_MONTHS:
1210 DateFormatSymbolsSingleSetter::setNarrowMonth(syms, index, value, valueLength, *status);
1211 break;
1212
1213 case UDAT_STANDALONE_MONTHS:
1214 DateFormatSymbolsSingleSetter::setStandaloneMonth(syms, index, value, valueLength, *status);
1215 break;
1216
1217 case UDAT_STANDALONE_SHORT_MONTHS:
1218 DateFormatSymbolsSingleSetter::setStandaloneShortMonth(syms, index, value, valueLength, *status);
1219 break;
1220
1221 case UDAT_STANDALONE_NARROW_MONTHS:
1222 DateFormatSymbolsSingleSetter::setStandaloneNarrowMonth(syms, index, value, valueLength, *status);
1223 break;
1224
1225 case UDAT_WEEKDAYS:
1226 DateFormatSymbolsSingleSetter::setWeekday(syms, index, value, valueLength, *status);
1227 break;
1228
1229 case UDAT_SHORT_WEEKDAYS:
1230 DateFormatSymbolsSingleSetter::setShortWeekday(syms, index, value, valueLength, *status);
1231 break;
1232
1233 case UDAT_SHORTER_WEEKDAYS:
1234 DateFormatSymbolsSingleSetter::setShorterWeekday(syms, index, value, valueLength, *status);
1235 break;
1236
1237 case UDAT_NARROW_WEEKDAYS:
1238 DateFormatSymbolsSingleSetter::setNarrowWeekday(syms, index, value, valueLength, *status);
1239 break;
1240
1241 case UDAT_STANDALONE_WEEKDAYS:
1242 DateFormatSymbolsSingleSetter::setStandaloneWeekday(syms, index, value, valueLength, *status);
1243 break;
1244
1245 case UDAT_STANDALONE_SHORT_WEEKDAYS:
1246 DateFormatSymbolsSingleSetter::setStandaloneShortWeekday(syms, index, value, valueLength, *status);
1247 break;
1248
1249 case UDAT_STANDALONE_SHORTER_WEEKDAYS:
1250 DateFormatSymbolsSingleSetter::setStandaloneShorterWeekday(syms, index, value, valueLength, *status);
1251 break;
1252
1253 case UDAT_STANDALONE_NARROW_WEEKDAYS:
1254 DateFormatSymbolsSingleSetter::setStandaloneNarrowWeekday(syms, index, value, valueLength, *status);
1255 break;
1256
1257 case UDAT_QUARTERS:
1258 DateFormatSymbolsSingleSetter::setQuarter(syms, index, value, valueLength, *status);
1259 break;
1260
1261 case UDAT_SHORT_QUARTERS:
1262 DateFormatSymbolsSingleSetter::setShortQuarter(syms, index, value, valueLength, *status);
1263 break;
1264
1265 case UDAT_STANDALONE_QUARTERS:
1266 DateFormatSymbolsSingleSetter::setStandaloneQuarter(syms, index, value, valueLength, *status);
1267 break;
1268
1269 case UDAT_STANDALONE_SHORT_QUARTERS:
1270 DateFormatSymbolsSingleSetter::setStandaloneShortQuarter(syms, index, value, valueLength, *status);
1271 break;
1272
1273 case UDAT_CYCLIC_YEARS_ABBREVIATED:
1274 DateFormatSymbolsSingleSetter::setShortYearNames(syms, index, value, valueLength, *status);
1275 break;
1276
1277 case UDAT_ZODIAC_NAMES_ABBREVIATED:
1278 DateFormatSymbolsSingleSetter::setShortZodiacNames(syms, index, value, valueLength, *status);
1279 break;
1280
1281 case UDAT_AM_PMS:
1282 DateFormatSymbolsSingleSetter::setAmPm(syms, index, value, valueLength, *status);
1283 break;
1284
1285 case UDAT_LOCALIZED_CHARS:
1286 DateFormatSymbolsSingleSetter::setLocalPatternChars(syms, value, valueLength, *status);
1287 break;
1288
1289 default:
1290 *status = U_UNSUPPORTED_ERROR;
1291 break;
1292
1293 }
1294 }
1295
1296 U_CAPI const char* U_EXPORT2
1297 udat_getLocaleByType(const UDateFormat *fmt,
1298 ULocDataLocaleType type,
1299 UErrorCode* status)
1300 {
1301 if (fmt == NULL) {
1302 if (U_SUCCESS(*status)) {
1303 *status = U_ILLEGAL_ARGUMENT_ERROR;
1304 }
1305 return NULL;
1306 }
1307 return ((Format*)fmt)->getLocaleID(type, *status);
1308 }
1309
1310 U_CAPI void U_EXPORT2
1311 udat_setContext(UDateFormat* fmt, UDisplayContext value, UErrorCode* status)
1312 {
1313 if (U_FAILURE(*status)) {
1314 return;
1315 }
1316 ((DateFormat*)fmt)->setContext(value, *status);
1317 return;
1318 }
1319
1320 U_CAPI UDisplayContext U_EXPORT2
1321 udat_getContext(const UDateFormat* fmt, UDisplayContextType type, UErrorCode* status)
1322 {
1323 if (U_FAILURE(*status)) {
1324 return (UDisplayContext)0;
1325 }
1326 return ((const DateFormat*)fmt)->getContext(type, *status);
1327 }
1328
1329
1330 /**
1331 * Verify that fmt is a RelativeDateFormat. Invalid error if not.
1332 * @param fmt the UDateFormat, definitely a DateFormat, maybe something else
1333 * @param status error code, will be set to failure if there is a familure or the fmt is NULL.
1334 */
1335 static void verifyIsRelativeDateFormat(const UDateFormat* fmt, UErrorCode *status) {
1336 if(U_SUCCESS(*status) &&
1337 dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==NULL) {
1338 *status = U_ILLEGAL_ARGUMENT_ERROR;
1339 }
1340 }
1341
1342
1343 U_CAPI int32_t U_EXPORT2
1344 udat_toPatternRelativeDate(const UDateFormat *fmt,
1345 UChar *result,
1346 int32_t resultLength,
1347 UErrorCode *status)
1348 {
1349 verifyIsRelativeDateFormat(fmt, status);
1350 if(U_FAILURE(*status)) {
1351 return -1;
1352 }
1353 if (result == NULL ? resultLength != 0 : resultLength < 0) {
1354 *status = U_ILLEGAL_ARGUMENT_ERROR;
1355 return -1;
1356 }
1357
1358 UnicodeString datePattern;
1359 if (result != NULL) {
1360 // NULL destination for pure preflighting: empty dummy string
1361 // otherwise, alias the destination buffer
1362 datePattern.setTo(result, 0, resultLength);
1363 }
1364 ((RelativeDateFormat*)fmt)->toPatternDate(datePattern, *status);
1365 return datePattern.extract(result, resultLength, *status);
1366 }
1367
1368 U_CAPI int32_t U_EXPORT2
1369 udat_toPatternRelativeTime(const UDateFormat *fmt,
1370 UChar *result,
1371 int32_t resultLength,
1372 UErrorCode *status)
1373 {
1374 verifyIsRelativeDateFormat(fmt, status);
1375 if(U_FAILURE(*status)) {
1376 return -1;
1377 }
1378 if (result == NULL ? resultLength != 0 : resultLength < 0) {
1379 *status = U_ILLEGAL_ARGUMENT_ERROR;
1380 return -1;
1381 }
1382
1383 UnicodeString timePattern;
1384 if (result != NULL) {
1385 // NULL destination for pure preflighting: empty dummy string
1386 // otherwise, alias the destination buffer
1387 timePattern.setTo(result, 0, resultLength);
1388 }
1389 ((RelativeDateFormat*)fmt)->toPatternTime(timePattern, *status);
1390 return timePattern.extract(result, resultLength, *status);
1391 }
1392
1393 U_CAPI void U_EXPORT2
1394 udat_applyPatternRelative(UDateFormat *format,
1395 const UChar *datePattern,
1396 int32_t datePatternLength,
1397 const UChar *timePattern,
1398 int32_t timePatternLength,
1399 UErrorCode *status)
1400 {
1401 verifyIsRelativeDateFormat(format, status);
1402 if(U_FAILURE(*status)) return;
1403 const UnicodeString datePat((UBool)(datePatternLength == -1), datePattern, datePatternLength);
1404 const UnicodeString timePat((UBool)(timePatternLength == -1), timePattern, timePatternLength);
1405 ((RelativeDateFormat*)format)->applyPatterns(datePat, timePat, *status);
1406 }
1407
1408 #endif /* #if !UCONFIG_NO_FORMATTING */