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