2 *******************************************************************************
3 * Copyright (C) 1996-2015, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 *******************************************************************************
8 #include "unicode/utypes.h"
10 #if !UCONFIG_NO_FORMATTING
12 #include "unicode/udat.h"
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"
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.
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
;
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
87 U_CAPI UCalendarDateFields U_EXPORT2
88 udat_toCalendarDateField(UDateFormatField field
) {
89 return gDateFieldMapping
[field
];
92 /* For now- one opener. */
93 static UDateFormatOpener gOpener
= NULL
;
95 U_INTERNAL
void U_EXPORT2
96 udat_registerOpener(UDateFormatOpener opener
, UErrorCode
*status
)
98 if(U_FAILURE(*status
)) return;
103 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
108 U_INTERNAL UDateFormatOpener U_EXPORT2
109 udat_unregisterOpener(UDateFormatOpener opener
, UErrorCode
*status
)
111 if(U_FAILURE(*status
)) return NULL
;
112 UDateFormatOpener oldOpener
= NULL
;
114 if(gOpener
==NULL
|| gOpener
!=opener
) {
115 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
126 U_CAPI UDateFormat
* U_EXPORT2
127 udat_open(UDateFormatStyle timeStyle
,
128 UDateFormatStyle dateStyle
,
132 const UChar
*pattern
,
133 int32_t patternLength
,
137 if(U_FAILURE(*status
)) {
140 if(gOpener
!=NULL
) { // if it's registered
141 fmt
= (DateFormat
*) (*gOpener
)(timeStyle
,dateStyle
,locale
,tzID
,tzIDLength
,pattern
,patternLength
,status
);
143 return (UDateFormat
*)fmt
;
144 } // else fall through.
146 if(timeStyle
!= UDAT_PATTERN
) {
148 fmt
= DateFormat::createDateTimeInstance((DateFormat::EStyle
)dateStyle
,
149 (DateFormat::EStyle
)timeStyle
);
152 fmt
= DateFormat::createDateTimeInstance((DateFormat::EStyle
)dateStyle
,
153 (DateFormat::EStyle
)timeStyle
,
158 UnicodeString
pat((UBool
)(patternLength
== -1), pattern
, patternLength
);
161 fmt
= new SimpleDateFormat(pat
, *status
);
164 fmt
= new SimpleDateFormat(pat
, Locale(locale
), *status
);
169 *status
= U_MEMORY_ALLOCATION_ERROR
;
174 TimeZone
*zone
= TimeZone::createTimeZone(UnicodeString((UBool
)(tzIDLength
== -1), tzID
, tzIDLength
));
176 *status
= U_MEMORY_ALLOCATION_ERROR
;
180 fmt
->adoptTimeZone(zone
);
183 return (UDateFormat
*)fmt
;
187 U_CAPI
void U_EXPORT2
188 udat_close(UDateFormat
* format
)
190 delete (DateFormat
*)format
;
193 U_CAPI UDateFormat
* U_EXPORT2
194 udat_clone(const UDateFormat
*fmt
,
197 if(U_FAILURE(*status
)) return 0;
199 Format
*res
= ((DateFormat
*)fmt
)->clone();
202 *status
= U_MEMORY_ALLOCATION_ERROR
;
206 return (UDateFormat
*) res
;
209 U_CAPI
int32_t U_EXPORT2
210 udat_format( const UDateFormat
* format
,
213 int32_t resultLength
,
214 UFieldPosition
* position
,
217 if(U_FAILURE(*status
)) {
220 if (result
== NULL
? resultLength
!= 0 : resultLength
< 0) {
221 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
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
);
235 fp
.setField(position
->field
);
237 ((DateFormat
*)format
)->format(dateToFormat
, res
, fp
);
240 position
->beginIndex
= fp
.getBeginIndex();
241 position
->endIndex
= fp
.getEndIndex();
244 return res
.extract(result
, resultLength
, *status
);
247 U_CAPI
int32_t U_EXPORT2
248 udat_formatCalendar(const UDateFormat
* format
,
251 int32_t resultLength
,
252 UFieldPosition
* position
,
255 if(U_FAILURE(*status
)) {
258 if (result
== NULL
? resultLength
!= 0 : resultLength
< 0) {
259 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
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
);
273 fp
.setField(position
->field
);
275 ((DateFormat
*)format
)->format(*(Calendar
*)calendar
, res
, fp
);
278 position
->beginIndex
= fp
.getBeginIndex();
279 position
->endIndex
= fp
.getEndIndex();
282 return res
.extract(result
, resultLength
, *status
);
285 U_CAPI
int32_t U_EXPORT2
286 udat_formatForFields( const UDateFormat
* format
,
289 int32_t resultLength
,
290 UFieldPositionIterator
* fpositer
,
293 if(U_FAILURE(*status
)) {
296 if (result
== NULL
? resultLength
!= 0 : resultLength
< 0) {
297 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
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
);
308 ((DateFormat
*)format
)->format(dateToFormat
, res
, (FieldPositionIterator
*)fpositer
, *status
);
310 return res
.extract(result
, resultLength
, *status
);
313 U_CAPI
int32_t U_EXPORT2
314 udat_formatCalendarForFields(const UDateFormat
* format
,
317 int32_t resultLength
,
318 UFieldPositionIterator
* fpositer
,
321 if(U_FAILURE(*status
)) {
324 if (result
== NULL
? resultLength
!= 0 : resultLength
< 0) {
325 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
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
);
336 ((DateFormat
*)format
)->format(*(Calendar
*)calendar
, res
, (FieldPositionIterator
*)fpositer
, *status
);
338 return res
.extract(result
, resultLength
, *status
);
341 U_CAPI UDate U_EXPORT2
342 udat_parse( const UDateFormat
* format
,
348 if(U_FAILURE(*status
)) return (UDate
)0;
350 const UnicodeString
src((UBool
)(textLength
== -1), text
, textLength
);
352 int32_t stackParsePos
= 0;
355 if(parsePos
== NULL
) {
356 parsePos
= &stackParsePos
;
359 pp
.setIndex(*parsePos
);
361 res
= ((DateFormat
*)format
)->parse(src
, pp
);
363 if(pp
.getErrorIndex() == -1)
364 *parsePos
= pp
.getIndex();
366 *parsePos
= pp
.getErrorIndex();
367 *status
= U_PARSE_ERROR
;
373 U_CAPI
void U_EXPORT2
374 udat_parseCalendar(const UDateFormat
* format
,
381 if(U_FAILURE(*status
)) return;
383 const UnicodeString
src((UBool
)(textLength
== -1), text
, textLength
);
385 int32_t stackParsePos
= 0;
387 if(parsePos
== NULL
) {
388 parsePos
= &stackParsePos
;
391 pp
.setIndex(*parsePos
);
393 ((DateFormat
*)format
)->parse(src
, *(Calendar
*)calendar
, pp
);
395 if(pp
.getErrorIndex() == -1)
396 *parsePos
= pp
.getIndex();
398 *parsePos
= pp
.getErrorIndex();
399 *status
= U_PARSE_ERROR
;
403 U_CAPI UBool U_EXPORT2
404 udat_isLenient(const UDateFormat
* fmt
)
406 return ((DateFormat
*)fmt
)->isLenient();
409 U_CAPI
void U_EXPORT2
410 udat_setLenient( UDateFormat
* fmt
,
413 ((DateFormat
*)fmt
)->setLenient(isLenient
);
416 U_DRAFT UBool U_EXPORT2
417 udat_getBooleanAttribute(const UDateFormat
* fmt
,
418 UDateFormatBooleanAttribute attr
,
421 if(U_FAILURE(*status
)) return FALSE
;
422 return ((DateFormat
*)fmt
)->getBooleanAttribute(attr
, *status
);
426 U_DRAFT
void U_EXPORT2
427 udat_setBooleanAttribute(UDateFormat
*fmt
,
428 UDateFormatBooleanAttribute attr
,
432 if(U_FAILURE(*status
)) return;
433 ((DateFormat
*)fmt
)->setBooleanAttribute(attr
, newValue
, *status
);
436 U_CAPI
const UCalendar
* U_EXPORT2
437 udat_getCalendar(const UDateFormat
* fmt
)
439 return (const UCalendar
*) ((DateFormat
*)fmt
)->getCalendar();
442 U_CAPI
void U_EXPORT2
443 udat_setCalendar(UDateFormat
* fmt
,
444 const UCalendar
* calendarToSet
)
446 ((DateFormat
*)fmt
)->setCalendar(*((Calendar
*)calendarToSet
));
449 U_DRAFT
const UNumberFormat
* U_EXPORT2
450 udat_getNumberFormatForField(const UDateFormat
* fmt
, UChar field
)
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
);
458 U_CAPI
const UNumberFormat
* U_EXPORT2
459 udat_getNumberFormat(const UDateFormat
* fmt
)
461 return (const UNumberFormat
*) ((DateFormat
*)fmt
)->getNumberFormat();
464 U_DRAFT
void U_EXPORT2
465 udat_adoptNumberFormatForFields( UDateFormat
* fmt
,
467 UNumberFormat
* numberFormatToSet
,
470 verifyIsSimpleDateFormat(fmt
, status
);
471 if (U_FAILURE(*status
)) return;
474 UnicodeString
overrideFields(fields
);
475 ((SimpleDateFormat
*)fmt
)->adoptNumberFormat(overrideFields
, (NumberFormat
*)numberFormatToSet
, *status
);
479 U_CAPI
void U_EXPORT2
480 udat_setNumberFormat(UDateFormat
* fmt
,
481 const UNumberFormat
* numberFormatToSet
)
483 ((DateFormat
*)fmt
)->setNumberFormat(*((NumberFormat
*)numberFormatToSet
));
486 U_DRAFT
void U_EXPORT2
487 udat_adoptNumberFormat( UDateFormat
* fmt
,
488 UNumberFormat
* numberFormatToAdopt
)
490 ((DateFormat
*)fmt
)->adoptNumberFormat((NumberFormat
*)numberFormatToAdopt
);
493 U_CAPI
const char* U_EXPORT2
494 udat_getAvailable(int32_t index
)
496 return uloc_getAvailable(index
);
499 U_CAPI
int32_t U_EXPORT2
500 udat_countAvailable()
502 return uloc_countAvailable();
505 U_CAPI UDate U_EXPORT2
506 udat_get2DigitYearStart( const UDateFormat
*fmt
,
509 verifyIsSimpleDateFormat(fmt
, status
);
510 if(U_FAILURE(*status
)) return (UDate
)0;
511 return ((SimpleDateFormat
*)fmt
)->get2DigitYearStart(*status
);
514 U_CAPI
void U_EXPORT2
515 udat_set2DigitYearStart( UDateFormat
*fmt
,
519 verifyIsSimpleDateFormat(fmt
, status
);
520 if(U_FAILURE(*status
)) return;
521 ((SimpleDateFormat
*)fmt
)->set2DigitYearStart(d
, *status
);
524 U_CAPI
int32_t U_EXPORT2
525 udat_toPattern( const UDateFormat
*fmt
,
528 int32_t resultLength
,
531 if(U_FAILURE(*status
)) {
534 if (result
== NULL
? resultLength
!= 0 : resultLength
< 0) {
535 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
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
);
546 const DateFormat
*df
=reinterpret_cast<const DateFormat
*>(fmt
);
547 const SimpleDateFormat
*sdtfmt
=dynamic_cast<const SimpleDateFormat
*>(df
);
548 const RelativeDateFormat
*reldtfmt
;
551 sdtfmt
->toLocalizedPattern(res
, *status
);
553 sdtfmt
->toPattern(res
);
554 } else if (!localized
&& (reldtfmt
=dynamic_cast<const RelativeDateFormat
*>(df
))!=NULL
) {
555 reldtfmt
->toPattern(res
, *status
);
557 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
561 return res
.extract(result
, resultLength
, *status
);
564 // TODO: should this take an UErrorCode?
565 // A: Yes. Of course.
566 U_CAPI
void U_EXPORT2
567 udat_applyPattern( UDateFormat
*format
,
569 const UChar
*pattern
,
570 int32_t patternLength
)
572 const UnicodeString
pat((UBool
)(patternLength
== -1), pattern
, patternLength
);
573 UErrorCode status
= U_ZERO_ERROR
;
575 verifyIsSimpleDateFormat(format
, &status
);
576 if(U_FAILURE(status
)) {
581 ((SimpleDateFormat
*)format
)->applyLocalizedPattern(pat
, status
);
583 ((SimpleDateFormat
*)format
)->applyPattern(pat
);
586 U_CAPI
int32_t U_EXPORT2
587 udat_getSymbols(const UDateFormat
*fmt
,
588 UDateFormatSymbolType type
,
591 int32_t resultLength
,
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();
605 const UnicodeString
*res
= NULL
;
609 res
= syms
->getEras(count
);
613 res
= syms
->getEraNames(count
);
617 res
= syms
->getMonths(count
);
620 case UDAT_SHORT_MONTHS
:
621 res
= syms
->getShortMonths(count
);
625 res
= syms
->getWeekdays(count
);
628 case UDAT_SHORT_WEEKDAYS
:
629 res
= syms
->getShortWeekdays(count
);
633 res
= syms
->getAmPmStrings(count
);
636 case UDAT_LOCALIZED_CHARS
:
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
);
644 syms
->getLocalPatternChars(res1
);
645 return res1
.extract(result
, resultLength
, *status
);
648 case UDAT_NARROW_MONTHS
:
649 res
= syms
->getMonths(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::NARROW
);
652 case UDAT_SHORTER_WEEKDAYS
:
653 res
= syms
->getWeekdays(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::SHORT
);
656 case UDAT_NARROW_WEEKDAYS
:
657 res
= syms
->getWeekdays(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::NARROW
);
660 case UDAT_STANDALONE_MONTHS
:
661 res
= syms
->getMonths(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::WIDE
);
664 case UDAT_STANDALONE_SHORT_MONTHS
:
665 res
= syms
->getMonths(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::ABBREVIATED
);
668 case UDAT_STANDALONE_NARROW_MONTHS
:
669 res
= syms
->getMonths(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::NARROW
);
672 case UDAT_STANDALONE_WEEKDAYS
:
673 res
= syms
->getWeekdays(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::WIDE
);
676 case UDAT_STANDALONE_SHORT_WEEKDAYS
:
677 res
= syms
->getWeekdays(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::ABBREVIATED
);
680 case UDAT_STANDALONE_SHORTER_WEEKDAYS
:
681 res
= syms
->getWeekdays(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::SHORT
);
684 case UDAT_STANDALONE_NARROW_WEEKDAYS
:
685 res
= syms
->getWeekdays(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::NARROW
);
689 res
= syms
->getQuarters(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::WIDE
);
692 case UDAT_SHORT_QUARTERS
:
693 res
= syms
->getQuarters(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::ABBREVIATED
);
696 case UDAT_STANDALONE_QUARTERS
:
697 res
= syms
->getQuarters(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::WIDE
);
700 case UDAT_STANDALONE_SHORT_QUARTERS
:
701 res
= syms
->getQuarters(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::ABBREVIATED
);
704 case UDAT_CYCLIC_YEARS_WIDE
:
705 res
= syms
->getYearNames(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::WIDE
);
708 case UDAT_CYCLIC_YEARS_ABBREVIATED
:
709 res
= syms
->getYearNames(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::ABBREVIATED
);
712 case UDAT_CYCLIC_YEARS_NARROW
:
713 res
= syms
->getYearNames(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::NARROW
);
716 case UDAT_ZODIAC_NAMES_WIDE
:
717 res
= syms
->getZodiacNames(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::WIDE
);
720 case UDAT_ZODIAC_NAMES_ABBREVIATED
:
721 res
= syms
->getZodiacNames(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::ABBREVIATED
);
724 case UDAT_ZODIAC_NAMES_NARROW
:
725 res
= syms
->getZodiacNames(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::NARROW
);
728 case UADAT_CYCLIC_ZODIAC_NAMES
:
729 res
= syms
->getZodiacNames(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::ABBREVIATED
);
730 index
= (index
> 0)? (index
- 1) % 12: 0;
736 return res
[index
].extract(result
, resultLength
, *status
);
741 // TODO: also needs an errorCode.
742 U_CAPI
int32_t U_EXPORT2
743 udat_countSymbols( const UDateFormat
*fmt
,
744 UDateFormatSymbolType type
)
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();
760 syms
->getEras(count
);
764 syms
->getMonths(count
);
767 case UDAT_SHORT_MONTHS
:
768 syms
->getShortMonths(count
);
772 syms
->getWeekdays(count
);
775 case UDAT_SHORT_WEEKDAYS
:
776 syms
->getShortWeekdays(count
);
780 syms
->getAmPmStrings(count
);
783 case UDAT_LOCALIZED_CHARS
:
788 syms
->getEraNames(count
);
791 case UDAT_NARROW_MONTHS
:
792 syms
->getMonths(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::NARROW
);
795 case UDAT_SHORTER_WEEKDAYS
:
796 syms
->getWeekdays(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::SHORT
);
799 case UDAT_NARROW_WEEKDAYS
:
800 syms
->getWeekdays(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::NARROW
);
803 case UDAT_STANDALONE_MONTHS
:
804 syms
->getMonths(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::WIDE
);
807 case UDAT_STANDALONE_SHORT_MONTHS
:
808 syms
->getMonths(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::ABBREVIATED
);
811 case UDAT_STANDALONE_NARROW_MONTHS
:
812 syms
->getMonths(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::NARROW
);
815 case UDAT_STANDALONE_WEEKDAYS
:
816 syms
->getWeekdays(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::WIDE
);
819 case UDAT_STANDALONE_SHORT_WEEKDAYS
:
820 syms
->getWeekdays(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::ABBREVIATED
);
823 case UDAT_STANDALONE_SHORTER_WEEKDAYS
:
824 syms
->getWeekdays(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::SHORT
);
827 case UDAT_STANDALONE_NARROW_WEEKDAYS
:
828 syms
->getWeekdays(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::NARROW
);
832 syms
->getQuarters(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::WIDE
);
835 case UDAT_SHORT_QUARTERS
:
836 syms
->getQuarters(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::ABBREVIATED
);
839 case UDAT_STANDALONE_QUARTERS
:
840 syms
->getQuarters(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::WIDE
);
843 case UDAT_STANDALONE_SHORT_QUARTERS
:
844 syms
->getQuarters(count
, DateFormatSymbols::STANDALONE
, DateFormatSymbols::ABBREVIATED
);
847 case UDAT_CYCLIC_YEARS_WIDE
:
848 syms
->getYearNames(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::WIDE
);
851 case UDAT_CYCLIC_YEARS_ABBREVIATED
:
852 syms
->getYearNames(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::ABBREVIATED
);
855 case UDAT_CYCLIC_YEARS_NARROW
:
856 syms
->getYearNames(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::NARROW
);
859 case UDAT_ZODIAC_NAMES_WIDE
:
860 syms
->getZodiacNames(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::WIDE
);
863 case UDAT_ZODIAC_NAMES_ABBREVIATED
:
864 syms
->getZodiacNames(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::ABBREVIATED
);
867 case UDAT_ZODIAC_NAMES_NARROW
:
868 syms
->getZodiacNames(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::NARROW
);
871 case UADAT_CYCLIC_ZODIAC_NAMES
:
872 syms
->getZodiacNames(count
, DateFormatSymbols::FORMAT
, DateFormatSymbols::ABBREVIATED
);
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:
888 * res = syms->getMonths(count);
889 * array = new UnicodeString[count];
891 * *status = U_MEMORY_ALLOCATION_ERROR;
894 * uprv_arrayCopy(res, array, count);
896 * array[index] = val;
897 * syms->setMonths(array, count);
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.
906 class DateFormatSymbolsSingleSetter
/* not : public UObject because all methods are static */ {
909 setSymbol(UnicodeString
*array
, int32_t count
, int32_t index
,
910 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
914 errorCode
=U_INDEX_OUTOFBOUNDS_ERROR
;
915 } else if(value
==NULL
) {
916 errorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
918 array
[index
].setTo(value
, valueLength
);
924 setEra(DateFormatSymbols
*syms
, int32_t index
,
925 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
927 setSymbol(syms
->fEras
, syms
->fErasCount
, index
, value
, valueLength
, errorCode
);
931 setEraName(DateFormatSymbols
*syms
, int32_t index
,
932 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
934 setSymbol(syms
->fEraNames
, syms
->fEraNamesCount
, index
, value
, valueLength
, errorCode
);
938 setMonth(DateFormatSymbols
*syms
, int32_t index
,
939 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
941 setSymbol(syms
->fMonths
, syms
->fMonthsCount
, index
, value
, valueLength
, errorCode
);
945 setShortMonth(DateFormatSymbols
*syms
, int32_t index
,
946 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
948 setSymbol(syms
->fShortMonths
, syms
->fShortMonthsCount
, index
, value
, valueLength
, errorCode
);
952 setNarrowMonth(DateFormatSymbols
*syms
, int32_t index
,
953 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
955 setSymbol(syms
->fNarrowMonths
, syms
->fNarrowMonthsCount
, index
, value
, valueLength
, errorCode
);
959 setStandaloneMonth(DateFormatSymbols
*syms
, int32_t index
,
960 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
962 setSymbol(syms
->fStandaloneMonths
, syms
->fStandaloneMonthsCount
, index
, value
, valueLength
, errorCode
);
966 setStandaloneShortMonth(DateFormatSymbols
*syms
, int32_t index
,
967 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
969 setSymbol(syms
->fStandaloneShortMonths
, syms
->fStandaloneShortMonthsCount
, index
, value
, valueLength
, errorCode
);
973 setStandaloneNarrowMonth(DateFormatSymbols
*syms
, int32_t index
,
974 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
976 setSymbol(syms
->fStandaloneNarrowMonths
, syms
->fStandaloneNarrowMonthsCount
, index
, value
, valueLength
, errorCode
);
980 setWeekday(DateFormatSymbols
*syms
, int32_t index
,
981 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
983 setSymbol(syms
->fWeekdays
, syms
->fWeekdaysCount
, index
, value
, valueLength
, errorCode
);
987 setShortWeekday(DateFormatSymbols
*syms
, int32_t index
,
988 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
990 setSymbol(syms
->fShortWeekdays
, syms
->fShortWeekdaysCount
, index
, value
, valueLength
, errorCode
);
994 setShorterWeekday(DateFormatSymbols
*syms
, int32_t index
,
995 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
997 setSymbol(syms
->fShorterWeekdays
, syms
->fShorterWeekdaysCount
, index
, value
, valueLength
, errorCode
);
1001 setNarrowWeekday(DateFormatSymbols
*syms
, int32_t index
,
1002 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
1004 setSymbol(syms
->fNarrowWeekdays
, syms
->fNarrowWeekdaysCount
, index
, value
, valueLength
, errorCode
);
1008 setStandaloneWeekday(DateFormatSymbols
*syms
, int32_t index
,
1009 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
1011 setSymbol(syms
->fStandaloneWeekdays
, syms
->fStandaloneWeekdaysCount
, index
, value
, valueLength
, errorCode
);
1015 setStandaloneShortWeekday(DateFormatSymbols
*syms
, int32_t index
,
1016 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
1018 setSymbol(syms
->fStandaloneShortWeekdays
, syms
->fStandaloneShortWeekdaysCount
, index
, value
, valueLength
, errorCode
);
1022 setStandaloneShorterWeekday(DateFormatSymbols
*syms
, int32_t index
,
1023 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
1025 setSymbol(syms
->fStandaloneShorterWeekdays
, syms
->fStandaloneShorterWeekdaysCount
, index
, value
, valueLength
, errorCode
);
1029 setStandaloneNarrowWeekday(DateFormatSymbols
*syms
, int32_t index
,
1030 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
1032 setSymbol(syms
->fStandaloneNarrowWeekdays
, syms
->fStandaloneNarrowWeekdaysCount
, index
, value
, valueLength
, errorCode
);
1036 setQuarter(DateFormatSymbols
*syms
, int32_t index
,
1037 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
1039 setSymbol(syms
->fQuarters
, syms
->fQuartersCount
, index
, value
, valueLength
, errorCode
);
1043 setShortQuarter(DateFormatSymbols
*syms
, int32_t index
,
1044 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
1046 setSymbol(syms
->fShortQuarters
, syms
->fShortQuartersCount
, index
, value
, valueLength
, errorCode
);
1050 setStandaloneQuarter(DateFormatSymbols
*syms
, int32_t index
,
1051 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
1053 setSymbol(syms
->fStandaloneQuarters
, syms
->fStandaloneQuartersCount
, index
, value
, valueLength
, errorCode
);
1057 setStandaloneShortQuarter(DateFormatSymbols
*syms
, int32_t index
,
1058 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
1060 setSymbol(syms
->fStandaloneShortQuarters
, syms
->fStandaloneShortQuartersCount
, index
, value
, valueLength
, errorCode
);
1064 setShortYearNames(DateFormatSymbols
*syms
, int32_t index
,
1065 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
1067 setSymbol(syms
->fShortYearNames
, syms
->fShortYearNamesCount
, index
, value
, valueLength
, errorCode
);
1071 setShortZodiacNames(DateFormatSymbols
*syms
, int32_t index
,
1072 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
1074 setSymbol(syms
->fShortZodiacNames
, syms
->fShortZodiacNamesCount
, index
, value
, valueLength
, errorCode
);
1078 setAmPm(DateFormatSymbols
*syms
, int32_t index
,
1079 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
1081 setSymbol(syms
->fAmPms
, syms
->fAmPmsCount
, index
, value
, valueLength
, errorCode
);
1085 setLocalPatternChars(DateFormatSymbols
*syms
,
1086 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
1088 setSymbol(&syms
->fLocalPatternChars
, 1, 0, value
, valueLength
, errorCode
);
1094 U_CAPI
void U_EXPORT2
1095 udat_setSymbols( UDateFormat
*format
,
1096 UDateFormatSymbolType type
,
1099 int32_t valueLength
,
1102 verifyIsSimpleDateFormat(format
, status
);
1103 if(U_FAILURE(*status
)) return;
1105 DateFormatSymbols
*syms
= (DateFormatSymbols
*)((SimpleDateFormat
*)format
)->getDateFormatSymbols();
1109 DateFormatSymbolsSingleSetter::setEra(syms
, index
, value
, valueLength
, *status
);
1112 case UDAT_ERA_NAMES
:
1113 DateFormatSymbolsSingleSetter::setEraName(syms
, index
, value
, valueLength
, *status
);
1117 DateFormatSymbolsSingleSetter::setMonth(syms
, index
, value
, valueLength
, *status
);
1120 case UDAT_SHORT_MONTHS
:
1121 DateFormatSymbolsSingleSetter::setShortMonth(syms
, index
, value
, valueLength
, *status
);
1124 case UDAT_NARROW_MONTHS
:
1125 DateFormatSymbolsSingleSetter::setNarrowMonth(syms
, index
, value
, valueLength
, *status
);
1128 case UDAT_STANDALONE_MONTHS
:
1129 DateFormatSymbolsSingleSetter::setStandaloneMonth(syms
, index
, value
, valueLength
, *status
);
1132 case UDAT_STANDALONE_SHORT_MONTHS
:
1133 DateFormatSymbolsSingleSetter::setStandaloneShortMonth(syms
, index
, value
, valueLength
, *status
);
1136 case UDAT_STANDALONE_NARROW_MONTHS
:
1137 DateFormatSymbolsSingleSetter::setStandaloneNarrowMonth(syms
, index
, value
, valueLength
, *status
);
1141 DateFormatSymbolsSingleSetter::setWeekday(syms
, index
, value
, valueLength
, *status
);
1144 case UDAT_SHORT_WEEKDAYS
:
1145 DateFormatSymbolsSingleSetter::setShortWeekday(syms
, index
, value
, valueLength
, *status
);
1148 case UDAT_SHORTER_WEEKDAYS
:
1149 DateFormatSymbolsSingleSetter::setShorterWeekday(syms
, index
, value
, valueLength
, *status
);
1152 case UDAT_NARROW_WEEKDAYS
:
1153 DateFormatSymbolsSingleSetter::setNarrowWeekday(syms
, index
, value
, valueLength
, *status
);
1156 case UDAT_STANDALONE_WEEKDAYS
:
1157 DateFormatSymbolsSingleSetter::setStandaloneWeekday(syms
, index
, value
, valueLength
, *status
);
1160 case UDAT_STANDALONE_SHORT_WEEKDAYS
:
1161 DateFormatSymbolsSingleSetter::setStandaloneShortWeekday(syms
, index
, value
, valueLength
, *status
);
1164 case UDAT_STANDALONE_SHORTER_WEEKDAYS
:
1165 DateFormatSymbolsSingleSetter::setStandaloneShorterWeekday(syms
, index
, value
, valueLength
, *status
);
1168 case UDAT_STANDALONE_NARROW_WEEKDAYS
:
1169 DateFormatSymbolsSingleSetter::setStandaloneNarrowWeekday(syms
, index
, value
, valueLength
, *status
);
1173 DateFormatSymbolsSingleSetter::setQuarter(syms
, index
, value
, valueLength
, *status
);
1176 case UDAT_SHORT_QUARTERS
:
1177 DateFormatSymbolsSingleSetter::setShortQuarter(syms
, index
, value
, valueLength
, *status
);
1180 case UDAT_STANDALONE_QUARTERS
:
1181 DateFormatSymbolsSingleSetter::setStandaloneQuarter(syms
, index
, value
, valueLength
, *status
);
1184 case UDAT_STANDALONE_SHORT_QUARTERS
:
1185 DateFormatSymbolsSingleSetter::setStandaloneShortQuarter(syms
, index
, value
, valueLength
, *status
);
1188 case UDAT_CYCLIC_YEARS_ABBREVIATED
:
1189 DateFormatSymbolsSingleSetter::setShortYearNames(syms
, index
, value
, valueLength
, *status
);
1192 case UDAT_ZODIAC_NAMES_ABBREVIATED
:
1193 DateFormatSymbolsSingleSetter::setShortZodiacNames(syms
, index
, value
, valueLength
, *status
);
1197 DateFormatSymbolsSingleSetter::setAmPm(syms
, index
, value
, valueLength
, *status
);
1200 case UDAT_LOCALIZED_CHARS
:
1201 DateFormatSymbolsSingleSetter::setLocalPatternChars(syms
, value
, valueLength
, *status
);
1205 *status
= U_UNSUPPORTED_ERROR
;
1211 U_CAPI
const char* U_EXPORT2
1212 udat_getLocaleByType(const UDateFormat
*fmt
,
1213 ULocDataLocaleType type
,
1217 if (U_SUCCESS(*status
)) {
1218 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
1222 return ((Format
*)fmt
)->getLocaleID(type
, *status
);
1225 U_CAPI
void U_EXPORT2
1226 udat_setContext(UDateFormat
* fmt
, UDisplayContext value
, UErrorCode
* status
)
1228 if (U_FAILURE(*status
)) {
1231 ((DateFormat
*)fmt
)->setContext(value
, *status
);
1235 U_CAPI UDisplayContext U_EXPORT2
1236 udat_getContext(const UDateFormat
* fmt
, UDisplayContextType type
, UErrorCode
* status
)
1238 if (U_FAILURE(*status
)) {
1239 return (UDisplayContext
)0;
1241 return ((const DateFormat
*)fmt
)->getContext(type
, *status
);
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.
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
;
1258 U_CAPI
int32_t U_EXPORT2
1259 udat_toPatternRelativeDate(const UDateFormat
*fmt
,
1261 int32_t resultLength
,
1264 verifyIsRelativeDateFormat(fmt
, status
);
1265 if(U_FAILURE(*status
)) {
1268 if (result
== NULL
? resultLength
!= 0 : resultLength
< 0) {
1269 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
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
);
1279 ((RelativeDateFormat
*)fmt
)->toPatternDate(datePattern
, *status
);
1280 return datePattern
.extract(result
, resultLength
, *status
);
1283 U_CAPI
int32_t U_EXPORT2
1284 udat_toPatternRelativeTime(const UDateFormat
*fmt
,
1286 int32_t resultLength
,
1289 verifyIsRelativeDateFormat(fmt
, status
);
1290 if(U_FAILURE(*status
)) {
1293 if (result
== NULL
? resultLength
!= 0 : resultLength
< 0) {
1294 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
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
);
1304 ((RelativeDateFormat
*)fmt
)->toPatternTime(timePattern
, *status
);
1305 return timePattern
.extract(result
, resultLength
, *status
);
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
,
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
);
1323 #endif /* #if !UCONFIG_NO_FORMATTING */