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