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