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