ICU-64243.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / udat.cpp
CommitLineData
f3c0d7a5
A
1// © 2016 and later: Unicode, Inc. and others.
2// License & terms of use: http://www.unicode.org/copyright.html
b75a7d8f
A
3/*
4*******************************************************************************
b331163b 5* Copyright (C) 1996-2015, International Business Machines
b75a7d8f
A
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"
51004dcb 26#include "unicode/udisplaycontext.h"
b331163b 27#include "unicode/ufieldpositer.h"
f3c0d7a5 28#include "unicode/ucasemap.h"
b75a7d8f 29#include "cpputils.h"
46f4442e 30#include "reldtfmt.h"
4388f060 31#include "umutex.h"
b75a7d8f
A
32
33U_NAMESPACE_USE
34
46f4442e
A
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 */
40static void verifyIsSimpleDateFormat(const UDateFormat* fmt, UErrorCode *status) {
729e4ab9
A
41 if(U_SUCCESS(*status) &&
42 dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==NULL) {
46f4442e
A
43 *status = U_ILLEGAL_ARGUMENT_ERROR;
44 }
45}
46
729e4ab9
A
47// This mirrors the correspondence between the
48// SimpleDateFormat::fgPatternIndexToDateFormatField and
49// SimpleDateFormat::fgPatternIndexToCalendarField arrays.
50static 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
57a6839d
A
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)
729e4ab9
A
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
57a6839d 80 UCAL_ZONE_OFFSET, // UDAT_TIMEZONE_SPECIAL_FIELD = 29 (also UCAL_DST_OFFSET)
4388f060 81 UCAL_YEAR, // UDAT_YEAR_NAME_FIELD = 30
57a6839d
A
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
729e4ab9
A
87 // UCAL_IS_LEAP_MONTH is not the target of a mapping
88};
89
90U_CAPI UCalendarDateFields U_EXPORT2
91udat_toCalendarDateField(UDateFormatField field) {
92 return gDateFieldMapping[field];
93}
94
4388f060
A
95/* For now- one opener. */
96static UDateFormatOpener gOpener = NULL;
97
98U_INTERNAL void U_EXPORT2
99udat_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
111U_INTERNAL UDateFormatOpener U_EXPORT2
112udat_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
b75a7d8f
A
129U_CAPI UDateFormat* U_EXPORT2
130udat_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{
73c04bcf
A
139 DateFormat *fmt;
140 if(U_FAILURE(*status)) {
b75a7d8f 141 return 0;
374ca955 142 }
4388f060
A
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 }
51004dcb 149 if(timeStyle != UDAT_PATTERN) {
73c04bcf 150 if(locale == 0) {
374ca955
A
151 fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
152 (DateFormat::EStyle)timeStyle);
73c04bcf
A
153 }
154 else {
374ca955
A
155 fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
156 (DateFormat::EStyle)timeStyle,
157 Locale(locale));
b75a7d8f 158 }
73c04bcf
A
159 }
160 else {
161 UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength);
374ca955 162
73c04bcf
A
163 if(locale == 0) {
164 fmt = new SimpleDateFormat(pat, *status);
165 }
166 else {
167 fmt = new SimpleDateFormat(pat, Locale(locale), *status);
374ca955 168 }
374ca955 169 }
374ca955 170
73c04bcf
A
171 if(fmt == 0) {
172 *status = U_MEMORY_ALLOCATION_ERROR;
173 return 0;
174 }
374ca955 175
73c04bcf
A
176 if(tzID != 0) {
177 TimeZone *zone = TimeZone::createTimeZone(UnicodeString((UBool)(tzIDLength == -1), tzID, tzIDLength));
178 if(zone == 0) {
374ca955 179 *status = U_MEMORY_ALLOCATION_ERROR;
73c04bcf 180 delete fmt;
374ca955
A
181 return 0;
182 }
73c04bcf 183 fmt->adoptTimeZone(zone);
374ca955 184 }
73c04bcf
A
185
186 return (UDateFormat*)fmt;
b75a7d8f
A
187}
188
189
190U_CAPI void U_EXPORT2
191udat_close(UDateFormat* format)
192{
374ca955 193 delete (DateFormat*)format;
b75a7d8f
A
194}
195
196U_CAPI UDateFormat* U_EXPORT2
197udat_clone(const UDateFormat *fmt,
198 UErrorCode *status)
199{
374ca955 200 if(U_FAILURE(*status)) return 0;
b75a7d8f 201
46f4442e 202 Format *res = ((DateFormat*)fmt)->clone();
b75a7d8f 203
374ca955
A
204 if(res == 0) {
205 *status = U_MEMORY_ALLOCATION_ERROR;
206 return 0;
207 }
b75a7d8f 208
374ca955 209 return (UDateFormat*) res;
b75a7d8f
A
210}
211
212U_CAPI int32_t U_EXPORT2
213udat_format( const UDateFormat* format,
214 UDate dateToFormat,
215 UChar* result,
216 int32_t resultLength,
217 UFieldPosition* position,
218 UErrorCode* status)
219{
b331163b
A
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 }
374ca955
A
227
228 UnicodeString res;
b331163b 229 if (result != NULL) {
374ca955
A
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;
b75a7d8f 236
374ca955
A
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);
b75a7d8f
A
248}
249
b331163b
A
250U_CAPI int32_t U_EXPORT2
251udat_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
288U_CAPI int32_t U_EXPORT2
289udat_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
316U_CAPI int32_t U_EXPORT2
317udat_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
b75a7d8f
A
344U_CAPI UDate U_EXPORT2
345udat_parse( const UDateFormat* format,
346 const UChar* text,
347 int32_t textLength,
348 int32_t *parsePos,
349 UErrorCode *status)
350{
374ca955 351 if(U_FAILURE(*status)) return (UDate)0;
b75a7d8f 352
374ca955
A
353 const UnicodeString src((UBool)(textLength == -1), text, textLength);
354 ParsePosition pp;
355 int32_t stackParsePos = 0;
356 UDate res;
b75a7d8f 357
374ca955
A
358 if(parsePos == NULL) {
359 parsePos = &stackParsePos;
360 }
b75a7d8f 361
b75a7d8f
A
362 pp.setIndex(*parsePos);
363
374ca955 364 res = ((DateFormat*)format)->parse(src, pp);
b75a7d8f 365
b75a7d8f 366 if(pp.getErrorIndex() == -1)
374ca955 367 *parsePos = pp.getIndex();
b75a7d8f 368 else {
374ca955
A
369 *parsePos = pp.getErrorIndex();
370 *status = U_PARSE_ERROR;
b75a7d8f 371 }
374ca955
A
372
373 return res;
b75a7d8f
A
374}
375
376U_CAPI void U_EXPORT2
377udat_parseCalendar(const UDateFormat* format,
378 UCalendar* calendar,
379 const UChar* text,
380 int32_t textLength,
381 int32_t *parsePos,
382 UErrorCode *status)
383{
374ca955 384 if(U_FAILURE(*status)) return;
b75a7d8f 385
374ca955
A
386 const UnicodeString src((UBool)(textLength == -1), text, textLength);
387 ParsePosition pp;
b331163b 388 int32_t stackParsePos = 0;
b75a7d8f 389
b331163b
A
390 if(parsePos == NULL) {
391 parsePos = &stackParsePos;
392 }
393
394 pp.setIndex(*parsePos);
b75a7d8f 395
374ca955 396 ((DateFormat*)format)->parse(src, *(Calendar*)calendar, pp);
b75a7d8f 397
b331163b
A
398 if(pp.getErrorIndex() == -1)
399 *parsePos = pp.getIndex();
400 else {
401 *parsePos = pp.getErrorIndex();
402 *status = U_PARSE_ERROR;
b75a7d8f 403 }
b75a7d8f
A
404}
405
406U_CAPI UBool U_EXPORT2
407udat_isLenient(const UDateFormat* fmt)
408{
374ca955 409 return ((DateFormat*)fmt)->isLenient();
b75a7d8f
A
410}
411
412U_CAPI void U_EXPORT2
413udat_setLenient( UDateFormat* fmt,
414 UBool isLenient)
415{
374ca955 416 ((DateFormat*)fmt)->setLenient(isLenient);
b75a7d8f
A
417}
418
57a6839d
A
419U_DRAFT UBool U_EXPORT2
420udat_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
429U_DRAFT void U_EXPORT2
430udat_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
b75a7d8f
A
439U_CAPI const UCalendar* U_EXPORT2
440udat_getCalendar(const UDateFormat* fmt)
441{
374ca955 442 return (const UCalendar*) ((DateFormat*)fmt)->getCalendar();
b75a7d8f
A
443}
444
445U_CAPI void U_EXPORT2
374ca955
A
446udat_setCalendar(UDateFormat* fmt,
447 const UCalendar* calendarToSet)
b75a7d8f 448{
374ca955 449 ((DateFormat*)fmt)->setCalendar(*((Calendar*)calendarToSet));
b75a7d8f
A
450}
451
b331163b
A
452U_DRAFT const UNumberFormat* U_EXPORT2
453udat_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
b75a7d8f
A
461U_CAPI const UNumberFormat* U_EXPORT2
462udat_getNumberFormat(const UDateFormat* fmt)
463{
374ca955 464 return (const UNumberFormat*) ((DateFormat*)fmt)->getNumberFormat();
b75a7d8f
A
465}
466
b331163b
A
467U_DRAFT void U_EXPORT2
468udat_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
b75a7d8f 482U_CAPI void U_EXPORT2
374ca955
A
483udat_setNumberFormat(UDateFormat* fmt,
484 const UNumberFormat* numberFormatToSet)
b75a7d8f 485{
374ca955 486 ((DateFormat*)fmt)->setNumberFormat(*((NumberFormat*)numberFormatToSet));
b75a7d8f
A
487}
488
b331163b
A
489U_DRAFT void U_EXPORT2
490udat_adoptNumberFormat( UDateFormat* fmt,
491 UNumberFormat* numberFormatToAdopt)
492{
493 ((DateFormat*)fmt)->adoptNumberFormat((NumberFormat*)numberFormatToAdopt);
494}
495
b75a7d8f
A
496U_CAPI const char* U_EXPORT2
497udat_getAvailable(int32_t index)
498{
374ca955 499 return uloc_getAvailable(index);
b75a7d8f
A
500}
501
502U_CAPI int32_t U_EXPORT2
503udat_countAvailable()
504{
374ca955 505 return uloc_countAvailable();
b75a7d8f
A
506}
507
508U_CAPI UDate U_EXPORT2
509udat_get2DigitYearStart( const UDateFormat *fmt,
374ca955 510 UErrorCode *status)
b75a7d8f 511{
46f4442e 512 verifyIsSimpleDateFormat(fmt, status);
374ca955
A
513 if(U_FAILURE(*status)) return (UDate)0;
514 return ((SimpleDateFormat*)fmt)->get2DigitYearStart(*status);
b75a7d8f
A
515}
516
517U_CAPI void U_EXPORT2
518udat_set2DigitYearStart( UDateFormat *fmt,
374ca955
A
519 UDate d,
520 UErrorCode *status)
b75a7d8f 521{
46f4442e 522 verifyIsSimpleDateFormat(fmt, status);
374ca955
A
523 if(U_FAILURE(*status)) return;
524 ((SimpleDateFormat*)fmt)->set2DigitYearStart(d, *status);
b75a7d8f
A
525}
526
527U_CAPI int32_t U_EXPORT2
528udat_toPattern( const UDateFormat *fmt,
529 UBool localized,
530 UChar *result,
531 int32_t resultLength,
532 UErrorCode *status)
533{
b331163b
A
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 }
b75a7d8f 541
374ca955 542 UnicodeString res;
b331163b 543 if (result != NULL) {
374ca955
A
544 // NULL destination for pure preflighting: empty dummy string
545 // otherwise, alias the destination buffer
546 res.setTo(result, 0, resultLength);
547 }
b75a7d8f 548
729e4ab9
A
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) {
46f4442e 553 if(localized)
729e4ab9 554 sdtfmt->toLocalizedPattern(res, *status);
46f4442e 555 else
729e4ab9
A
556 sdtfmt->toPattern(res);
557 } else if (!localized && (reldtfmt=dynamic_cast<const RelativeDateFormat *>(df))!=NULL) {
558 reldtfmt->toPattern(res, *status);
46f4442e
A
559 } else {
560 *status = U_ILLEGAL_ARGUMENT_ERROR;
561 return -1;
562 }
b75a7d8f 563
374ca955 564 return res.extract(result, resultLength, *status);
b75a7d8f
A
565}
566
729e4ab9
A
567// TODO: should this take an UErrorCode?
568// A: Yes. Of course.
b75a7d8f 569U_CAPI void U_EXPORT2
374ca955 570udat_applyPattern( UDateFormat *format,
b75a7d8f
A
571 UBool localized,
572 const UChar *pattern,
573 int32_t patternLength)
574{
729e4ab9 575 const UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength);
374ca955 576 UErrorCode status = U_ZERO_ERROR;
729e4ab9 577
46f4442e
A
578 verifyIsSimpleDateFormat(format, &status);
579 if(U_FAILURE(status)) {
580 return;
581 }
729e4ab9 582
374ca955
A
583 if(localized)
584 ((SimpleDateFormat*)format)->applyLocalizedPattern(pat, status);
585 else
586 ((SimpleDateFormat*)format)->applyPattern(pat);
b75a7d8f
A
587}
588
a62d09fc
A
589// Apple addition
590static 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
b75a7d8f 634U_CAPI int32_t U_EXPORT2
374ca955
A
635udat_getSymbols(const UDateFormat *fmt,
636 UDateFormatSymbolType type,
637 int32_t index,
638 UChar *result,
639 int32_t resultLength,
640 UErrorCode *status)
b75a7d8f 641{
729e4ab9
A
642 const DateFormatSymbols *syms;
643 const SimpleDateFormat* sdtfmt;
644 const RelativeDateFormat* rdtfmt;
a62d09fc 645 BreakIterator* capitalizationBrkIter;
729e4ab9 646 if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
51004dcb 647 syms = sdtfmt->getDateFormatSymbols();
a62d09fc 648 capitalizationBrkIter = sdtfmt->getCapitalizationBrkIter();
729e4ab9 649 } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
51004dcb 650 syms = rdtfmt->getDateFormatSymbols();
a62d09fc 651 capitalizationBrkIter = rdtfmt->getCapitalizationBrkIter();
729e4ab9
A
652 } else {
653 return -1;
654 }
3d1f044b 655 int32_t count = 0;
73c04bcf 656 const UnicodeString *res = NULL;
374ca955
A
657
658 switch(type) {
659 case UDAT_ERAS:
660 res = syms->getEras(count);
73c04bcf
A
661 break;
662
663 case UDAT_ERA_NAMES:
664 res = syms->getEraNames(count);
374ca955 665 break;
b75a7d8f 666
374ca955
A
667 case UDAT_MONTHS:
668 res = syms->getMonths(count);
374ca955 669 break;
b75a7d8f 670
374ca955
A
671 case UDAT_SHORT_MONTHS:
672 res = syms->getShortMonths(count);
374ca955 673 break;
b75a7d8f 674
374ca955
A
675 case UDAT_WEEKDAYS:
676 res = syms->getWeekdays(count);
374ca955 677 break;
b75a7d8f 678
374ca955
A
679 case UDAT_SHORT_WEEKDAYS:
680 res = syms->getShortWeekdays(count);
374ca955 681 break;
b75a7d8f 682
374ca955
A
683 case UDAT_AM_PMS:
684 res = syms->getAmPmStrings(count);
374ca955
A
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 }
73c04bcf
A
698
699 case UDAT_NARROW_MONTHS:
700 res = syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
701 break;
702
51004dcb
A
703 case UDAT_SHORTER_WEEKDAYS:
704 res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT);
705 break;
706
73c04bcf
A
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
51004dcb
A
731 case UDAT_STANDALONE_SHORTER_WEEKDAYS:
732 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT);
733 break;
734
73c04bcf
A
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
b331163b
A
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
57a6839d 779 case UADAT_CYCLIC_ZODIAC_NAMES:
b331163b 780 res = syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
57a6839d
A
781 index = (index > 0)? (index - 1) % 12: 0;
782 break;
783
b75a7d8f 784 }
b75a7d8f 785
73c04bcf 786 if(index < count) {
a62d09fc
A
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
73c04bcf
A
821 return res[index].extract(result, resultLength, *status);
822 }
374ca955 823 return 0;
b75a7d8f
A
824}
825
729e4ab9 826// TODO: also needs an errorCode.
b75a7d8f
A
827U_CAPI int32_t U_EXPORT2
828udat_countSymbols( const UDateFormat *fmt,
829 UDateFormatSymbolType type)
830{
729e4ab9
A
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) {
51004dcb 835 syms = sdtfmt->getDateFormatSymbols();
729e4ab9 836 } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
51004dcb 837 syms = rdtfmt->getDateFormatSymbols();
729e4ab9 838 } else {
46f4442e
A
839 return 0;
840 }
374ca955
A
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;
73c04bcf
A
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
51004dcb
A
880 case UDAT_SHORTER_WEEKDAYS:
881 syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT);
882 break;
883
73c04bcf
A
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
51004dcb
A
908 case UDAT_STANDALONE_SHORTER_WEEKDAYS:
909 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT);
910 break;
911
73c04bcf
A
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
b331163b
A
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
57a6839d 956 case UADAT_CYCLIC_ZODIAC_NAMES:
b331163b 957 syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
57a6839d 958 break;
b331163b
A
959
960 }
b75a7d8f 961
374ca955 962 return count;
b75a7d8f
A
963}
964
965U_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 */
991class DateFormatSymbolsSingleSetter /* not : public UObject because all methods are static */ {
992public:
374ca955
A
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
73c04bcf
A
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
374ca955
A
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
73c04bcf
A
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
374ca955
A
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
51004dcb
A
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
73c04bcf
A
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
51004dcb
A
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
73c04bcf
A
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
b331163b
A
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
374ca955
A
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);
b75a7d8f 1174 }
b75a7d8f
A
1175};
1176
1177U_NAMESPACE_END
1178
1179U_CAPI void U_EXPORT2
1180udat_setSymbols( UDateFormat *format,
1181 UDateFormatSymbolType type,
1182 int32_t index,
1183 UChar *value,
1184 int32_t valueLength,
1185 UErrorCode *status)
1186{
46f4442e 1187 verifyIsSimpleDateFormat(format, status);
374ca955 1188 if(U_FAILURE(*status)) return;
b75a7d8f 1189
374ca955 1190 DateFormatSymbols *syms = (DateFormatSymbols *)((SimpleDateFormat *)format)->getDateFormatSymbols();
b75a7d8f 1191
374ca955
A
1192 switch(type) {
1193 case UDAT_ERAS:
1194 DateFormatSymbolsSingleSetter::setEra(syms, index, value, valueLength, *status);
1195 break;
b75a7d8f 1196
73c04bcf
A
1197 case UDAT_ERA_NAMES:
1198 DateFormatSymbolsSingleSetter::setEraName(syms, index, value, valueLength, *status);
1199 break;
1200
374ca955
A
1201 case UDAT_MONTHS:
1202 DateFormatSymbolsSingleSetter::setMonth(syms, index, value, valueLength, *status);
1203 break;
b75a7d8f 1204
374ca955
A
1205 case UDAT_SHORT_MONTHS:
1206 DateFormatSymbolsSingleSetter::setShortMonth(syms, index, value, valueLength, *status);
1207 break;
b75a7d8f 1208
73c04bcf
A
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
374ca955
A
1225 case UDAT_WEEKDAYS:
1226 DateFormatSymbolsSingleSetter::setWeekday(syms, index, value, valueLength, *status);
1227 break;
b75a7d8f 1228
374ca955
A
1229 case UDAT_SHORT_WEEKDAYS:
1230 DateFormatSymbolsSingleSetter::setShortWeekday(syms, index, value, valueLength, *status);
1231 break;
b75a7d8f 1232
51004dcb
A
1233 case UDAT_SHORTER_WEEKDAYS:
1234 DateFormatSymbolsSingleSetter::setShorterWeekday(syms, index, value, valueLength, *status);
1235 break;
1236
73c04bcf
A
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
51004dcb
A
1249 case UDAT_STANDALONE_SHORTER_WEEKDAYS:
1250 DateFormatSymbolsSingleSetter::setStandaloneShorterWeekday(syms, index, value, valueLength, *status);
1251 break;
1252
73c04bcf
A
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
b331163b
A
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
374ca955
A
1281 case UDAT_AM_PMS:
1282 DateFormatSymbolsSingleSetter::setAmPm(syms, index, value, valueLength, *status);
1283 break;
b75a7d8f 1284
374ca955
A
1285 case UDAT_LOCALIZED_CHARS:
1286 DateFormatSymbolsSingleSetter::setLocalPatternChars(syms, value, valueLength, *status);
1287 break;
73c04bcf
A
1288
1289 default:
1290 *status = U_UNSUPPORTED_ERROR;
1291 break;
1292
374ca955 1293 }
b75a7d8f
A
1294}
1295
374ca955
A
1296U_CAPI const char* U_EXPORT2
1297udat_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}
46f4442e 1309
4388f060 1310U_CAPI void U_EXPORT2
51004dcb 1311udat_setContext(UDateFormat* fmt, UDisplayContext value, UErrorCode* status)
4388f060 1312{
4388f060
A
1313 if (U_FAILURE(*status)) {
1314 return;
1315 }
57a6839d
A
1316 ((DateFormat*)fmt)->setContext(value, *status);
1317 return;
4388f060
A
1318}
1319
51004dcb 1320U_CAPI UDisplayContext U_EXPORT2
57a6839d 1321udat_getContext(const UDateFormat* fmt, UDisplayContextType type, UErrorCode* status)
4388f060 1322{
4388f060 1323 if (U_FAILURE(*status)) {
51004dcb 1324 return (UDisplayContext)0;
4388f060 1325 }
57a6839d 1326 return ((const DateFormat*)fmt)->getContext(type, *status);
4388f060
A
1327}
1328
1329
46f4442e
A
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 */
1335static void verifyIsRelativeDateFormat(const UDateFormat* fmt, UErrorCode *status) {
729e4ab9
A
1336 if(U_SUCCESS(*status) &&
1337 dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==NULL) {
46f4442e
A
1338 *status = U_ILLEGAL_ARGUMENT_ERROR;
1339 }
1340}
1341
1342
1343U_CAPI int32_t U_EXPORT2
1344udat_toPatternRelativeDate(const UDateFormat *fmt,
1345 UChar *result,
1346 int32_t resultLength,
1347 UErrorCode *status)
1348{
1349 verifyIsRelativeDateFormat(fmt, status);
b331163b
A
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 }
46f4442e
A
1357
1358 UnicodeString datePattern;
b331163b 1359 if (result != NULL) {
46f4442e
A
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
1368U_CAPI int32_t U_EXPORT2
1369udat_toPatternRelativeTime(const UDateFormat *fmt,
1370 UChar *result,
1371 int32_t resultLength,
1372 UErrorCode *status)
1373{
1374 verifyIsRelativeDateFormat(fmt, status);
b331163b
A
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 }
46f4442e
A
1382
1383 UnicodeString timePattern;
b331163b 1384 if (result != NULL) {
46f4442e
A
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
1393U_CAPI void U_EXPORT2
1394udat_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
b75a7d8f 1408#endif /* #if !UCONFIG_NO_FORMATTING */