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