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