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 failure 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_NARROW_QUARTERS:
708 res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
709 break;
710
711 case UDAT_STANDALONE_QUARTERS:
712 res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
713 break;
714
715 case UDAT_STANDALONE_SHORT_QUARTERS:
716 res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
717 break;
718
719 case UDAT_STANDALONE_NARROW_QUARTERS:
720 res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
721 break;
722
723 case UDAT_CYCLIC_YEARS_WIDE:
724 res = syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
725 break;
726
727 case UDAT_CYCLIC_YEARS_ABBREVIATED:
728 res = syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
729 break;
730
731 case UDAT_CYCLIC_YEARS_NARROW:
732 res = syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
733 break;
734
735 case UDAT_ZODIAC_NAMES_WIDE:
736 res = syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
737 break;
738
739 case UDAT_ZODIAC_NAMES_ABBREVIATED:
740 res = syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
741 break;
742
743 case UDAT_ZODIAC_NAMES_NARROW:
744 res = syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
745 break;
746
747 }
748
749 if(index < count) {
750 return res[index].extract(result, resultLength, *status);
751 }
752 return 0;
753 }
754
755 // TODO: also needs an errorCode.
756 U_CAPI int32_t U_EXPORT2
udat_countSymbols(const UDateFormat * fmt,UDateFormatSymbolType type)757 udat_countSymbols( const UDateFormat *fmt,
758 UDateFormatSymbolType type)
759 {
760 const DateFormatSymbols *syms;
761 const SimpleDateFormat* sdtfmt;
762 const RelativeDateFormat* rdtfmt;
763 if ((sdtfmt = dynamic_cast<const SimpleDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
764 syms = sdtfmt->getDateFormatSymbols();
765 } else if ((rdtfmt = dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))) != NULL) {
766 syms = rdtfmt->getDateFormatSymbols();
767 } else {
768 return 0;
769 }
770 int32_t count = 0;
771
772 switch(type) {
773 case UDAT_ERAS:
774 syms->getEras(count);
775 break;
776
777 case UDAT_MONTHS:
778 syms->getMonths(count);
779 break;
780
781 case UDAT_SHORT_MONTHS:
782 syms->getShortMonths(count);
783 break;
784
785 case UDAT_WEEKDAYS:
786 syms->getWeekdays(count);
787 break;
788
789 case UDAT_SHORT_WEEKDAYS:
790 syms->getShortWeekdays(count);
791 break;
792
793 case UDAT_AM_PMS:
794 syms->getAmPmStrings(count);
795 break;
796
797 case UDAT_LOCALIZED_CHARS:
798 count = 1;
799 break;
800
801 case UDAT_ERA_NAMES:
802 syms->getEraNames(count);
803 break;
804
805 case UDAT_NARROW_MONTHS:
806 syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
807 break;
808
809 case UDAT_SHORTER_WEEKDAYS:
810 syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::SHORT);
811 break;
812
813 case UDAT_NARROW_WEEKDAYS:
814 syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
815 break;
816
817 case UDAT_STANDALONE_MONTHS:
818 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
819 break;
820
821 case UDAT_STANDALONE_SHORT_MONTHS:
822 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
823 break;
824
825 case UDAT_STANDALONE_NARROW_MONTHS:
826 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
827 break;
828
829 case UDAT_STANDALONE_WEEKDAYS:
830 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
831 break;
832
833 case UDAT_STANDALONE_SHORT_WEEKDAYS:
834 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
835 break;
836
837 case UDAT_STANDALONE_SHORTER_WEEKDAYS:
838 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::SHORT);
839 break;
840
841 case UDAT_STANDALONE_NARROW_WEEKDAYS:
842 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
843 break;
844
845 case UDAT_QUARTERS:
846 syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
847 break;
848
849 case UDAT_SHORT_QUARTERS:
850 syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
851 break;
852
853 case UDAT_NARROW_QUARTERS:
854 syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
855 break;
856
857 case UDAT_STANDALONE_QUARTERS:
858 syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
859 break;
860
861 case UDAT_STANDALONE_SHORT_QUARTERS:
862 syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
863 break;
864
865 case UDAT_STANDALONE_NARROW_QUARTERS:
866 syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
867 break;
868
869 case UDAT_CYCLIC_YEARS_WIDE:
870 syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
871 break;
872
873 case UDAT_CYCLIC_YEARS_ABBREVIATED:
874 syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
875 break;
876
877 case UDAT_CYCLIC_YEARS_NARROW:
878 syms->getYearNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
879 break;
880
881 case UDAT_ZODIAC_NAMES_WIDE:
882 syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
883 break;
884
885 case UDAT_ZODIAC_NAMES_ABBREVIATED:
886 syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
887 break;
888
889 case UDAT_ZODIAC_NAMES_NARROW:
890 syms->getZodiacNames(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
891 break;
892
893 }
894
895 return count;
896 }
897
898 U_NAMESPACE_BEGIN
899
900 /*
901 * This DateFormatSymbolsSingleSetter class is a friend of DateFormatSymbols
902 * solely for the purpose of avoiding to clone the array of strings
903 * just to modify one of them and then setting all of them back.
904 * For example, the old code looked like this:
905 * case UDAT_MONTHS:
906 * res = syms->getMonths(count);
907 * array = new UnicodeString[count];
908 * if(array == 0) {
909 * *status = U_MEMORY_ALLOCATION_ERROR;
910 * return;
911 * }
912 * uprv_arrayCopy(res, array, count);
913 * if(index < count)
914 * array[index] = val;
915 * syms->setMonths(array, count);
916 * break;
917 *
918 * Even worse, the old code actually cloned the entire DateFormatSymbols object,
919 * cloned one value array, changed one value, and then made the SimpleDateFormat
920 * replace its DateFormatSymbols object with the new one.
921 *
922 * markus 2002-oct-14
923 */
924 class DateFormatSymbolsSingleSetter /* not : public UObject because all methods are static */ {
925 public:
926 static void
setSymbol(UnicodeString * array,int32_t count,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)927 setSymbol(UnicodeString *array, int32_t count, int32_t index,
928 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
929 {
930 if(array!=NULL) {
931 if(index>=count) {
932 errorCode=U_INDEX_OUTOFBOUNDS_ERROR;
933 } else if(value==NULL) {
934 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
935 } else {
936 array[index].setTo(value, valueLength);
937 }
938 }
939 }
940
941 static void
setEra(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)942 setEra(DateFormatSymbols *syms, int32_t index,
943 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
944 {
945 setSymbol(syms->fEras, syms->fErasCount, index, value, valueLength, errorCode);
946 }
947
948 static void
setEraName(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)949 setEraName(DateFormatSymbols *syms, int32_t index,
950 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
951 {
952 setSymbol(syms->fEraNames, syms->fEraNamesCount, index, value, valueLength, errorCode);
953 }
954
955 static void
setMonth(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)956 setMonth(DateFormatSymbols *syms, int32_t index,
957 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
958 {
959 setSymbol(syms->fMonths, syms->fMonthsCount, index, value, valueLength, errorCode);
960 }
961
962 static void
setShortMonth(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)963 setShortMonth(DateFormatSymbols *syms, int32_t index,
964 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
965 {
966 setSymbol(syms->fShortMonths, syms->fShortMonthsCount, index, value, valueLength, errorCode);
967 }
968
969 static void
setNarrowMonth(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)970 setNarrowMonth(DateFormatSymbols *syms, int32_t index,
971 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
972 {
973 setSymbol(syms->fNarrowMonths, syms->fNarrowMonthsCount, index, value, valueLength, errorCode);
974 }
975
976 static void
setStandaloneMonth(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)977 setStandaloneMonth(DateFormatSymbols *syms, int32_t index,
978 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
979 {
980 setSymbol(syms->fStandaloneMonths, syms->fStandaloneMonthsCount, index, value, valueLength, errorCode);
981 }
982
983 static void
setStandaloneShortMonth(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)984 setStandaloneShortMonth(DateFormatSymbols *syms, int32_t index,
985 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
986 {
987 setSymbol(syms->fStandaloneShortMonths, syms->fStandaloneShortMonthsCount, index, value, valueLength, errorCode);
988 }
989
990 static void
setStandaloneNarrowMonth(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)991 setStandaloneNarrowMonth(DateFormatSymbols *syms, int32_t index,
992 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
993 {
994 setSymbol(syms->fStandaloneNarrowMonths, syms->fStandaloneNarrowMonthsCount, index, value, valueLength, errorCode);
995 }
996
997 static void
setWeekday(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)998 setWeekday(DateFormatSymbols *syms, int32_t index,
999 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1000 {
1001 setSymbol(syms->fWeekdays, syms->fWeekdaysCount, index, value, valueLength, errorCode);
1002 }
1003
1004 static void
setShortWeekday(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1005 setShortWeekday(DateFormatSymbols *syms, int32_t index,
1006 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1007 {
1008 setSymbol(syms->fShortWeekdays, syms->fShortWeekdaysCount, index, value, valueLength, errorCode);
1009 }
1010
1011 static void
setShorterWeekday(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1012 setShorterWeekday(DateFormatSymbols *syms, int32_t index,
1013 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1014 {
1015 setSymbol(syms->fShorterWeekdays, syms->fShorterWeekdaysCount, index, value, valueLength, errorCode);
1016 }
1017
1018 static void
setNarrowWeekday(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1019 setNarrowWeekday(DateFormatSymbols *syms, int32_t index,
1020 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1021 {
1022 setSymbol(syms->fNarrowWeekdays, syms->fNarrowWeekdaysCount, index, value, valueLength, errorCode);
1023 }
1024
1025 static void
setStandaloneWeekday(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1026 setStandaloneWeekday(DateFormatSymbols *syms, int32_t index,
1027 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1028 {
1029 setSymbol(syms->fStandaloneWeekdays, syms->fStandaloneWeekdaysCount, index, value, valueLength, errorCode);
1030 }
1031
1032 static void
setStandaloneShortWeekday(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1033 setStandaloneShortWeekday(DateFormatSymbols *syms, int32_t index,
1034 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1035 {
1036 setSymbol(syms->fStandaloneShortWeekdays, syms->fStandaloneShortWeekdaysCount, index, value, valueLength, errorCode);
1037 }
1038
1039 static void
setStandaloneShorterWeekday(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1040 setStandaloneShorterWeekday(DateFormatSymbols *syms, int32_t index,
1041 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1042 {
1043 setSymbol(syms->fStandaloneShorterWeekdays, syms->fStandaloneShorterWeekdaysCount, index, value, valueLength, errorCode);
1044 }
1045
1046 static void
setStandaloneNarrowWeekday(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1047 setStandaloneNarrowWeekday(DateFormatSymbols *syms, int32_t index,
1048 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1049 {
1050 setSymbol(syms->fStandaloneNarrowWeekdays, syms->fStandaloneNarrowWeekdaysCount, index, value, valueLength, errorCode);
1051 }
1052
1053 static void
setQuarter(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1054 setQuarter(DateFormatSymbols *syms, int32_t index,
1055 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1056 {
1057 setSymbol(syms->fQuarters, syms->fQuartersCount, index, value, valueLength, errorCode);
1058 }
1059
1060 static void
setShortQuarter(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1061 setShortQuarter(DateFormatSymbols *syms, int32_t index,
1062 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1063 {
1064 setSymbol(syms->fShortQuarters, syms->fShortQuartersCount, index, value, valueLength, errorCode);
1065 }
1066
1067 static void
setNarrowQuarter(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1068 setNarrowQuarter(DateFormatSymbols *syms, int32_t index,
1069 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1070 {
1071 setSymbol(syms->fNarrowQuarters, syms->fNarrowQuartersCount, index, value, valueLength, errorCode);
1072 }
1073
1074 static void
setStandaloneQuarter(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1075 setStandaloneQuarter(DateFormatSymbols *syms, int32_t index,
1076 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1077 {
1078 setSymbol(syms->fStandaloneQuarters, syms->fStandaloneQuartersCount, index, value, valueLength, errorCode);
1079 }
1080
1081 static void
setStandaloneShortQuarter(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1082 setStandaloneShortQuarter(DateFormatSymbols *syms, int32_t index,
1083 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1084 {
1085 setSymbol(syms->fStandaloneShortQuarters, syms->fStandaloneShortQuartersCount, index, value, valueLength, errorCode);
1086 }
1087
1088 static void
setStandaloneNarrowQuarter(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1089 setStandaloneNarrowQuarter(DateFormatSymbols *syms, int32_t index,
1090 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1091 {
1092 setSymbol(syms->fStandaloneNarrowQuarters, syms->fStandaloneNarrowQuartersCount, index, value, valueLength, errorCode);
1093 }
1094
1095 static void
setShortYearNames(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1096 setShortYearNames(DateFormatSymbols *syms, int32_t index,
1097 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1098 {
1099 setSymbol(syms->fShortYearNames, syms->fShortYearNamesCount, index, value, valueLength, errorCode);
1100 }
1101
1102 static void
setShortZodiacNames(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1103 setShortZodiacNames(DateFormatSymbols *syms, int32_t index,
1104 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1105 {
1106 setSymbol(syms->fShortZodiacNames, syms->fShortZodiacNamesCount, index, value, valueLength, errorCode);
1107 }
1108
1109 static void
setAmPm(DateFormatSymbols * syms,int32_t index,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1110 setAmPm(DateFormatSymbols *syms, int32_t index,
1111 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1112 {
1113 setSymbol(syms->fAmPms, syms->fAmPmsCount, index, value, valueLength, errorCode);
1114 }
1115
1116 static void
setLocalPatternChars(DateFormatSymbols * syms,const UChar * value,int32_t valueLength,UErrorCode & errorCode)1117 setLocalPatternChars(DateFormatSymbols *syms,
1118 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
1119 {
1120 setSymbol(&syms->fLocalPatternChars, 1, 0, value, valueLength, errorCode);
1121 }
1122 };
1123
1124 U_NAMESPACE_END
1125
1126 U_CAPI void U_EXPORT2
udat_setSymbols(UDateFormat * format,UDateFormatSymbolType type,int32_t index,UChar * value,int32_t valueLength,UErrorCode * status)1127 udat_setSymbols( UDateFormat *format,
1128 UDateFormatSymbolType type,
1129 int32_t index,
1130 UChar *value,
1131 int32_t valueLength,
1132 UErrorCode *status)
1133 {
1134 verifyIsSimpleDateFormat(format, status);
1135 if(U_FAILURE(*status)) return;
1136
1137 DateFormatSymbols *syms = (DateFormatSymbols *)((SimpleDateFormat *)format)->getDateFormatSymbols();
1138
1139 switch(type) {
1140 case UDAT_ERAS:
1141 DateFormatSymbolsSingleSetter::setEra(syms, index, value, valueLength, *status);
1142 break;
1143
1144 case UDAT_ERA_NAMES:
1145 DateFormatSymbolsSingleSetter::setEraName(syms, index, value, valueLength, *status);
1146 break;
1147
1148 case UDAT_MONTHS:
1149 DateFormatSymbolsSingleSetter::setMonth(syms, index, value, valueLength, *status);
1150 break;
1151
1152 case UDAT_SHORT_MONTHS:
1153 DateFormatSymbolsSingleSetter::setShortMonth(syms, index, value, valueLength, *status);
1154 break;
1155
1156 case UDAT_NARROW_MONTHS:
1157 DateFormatSymbolsSingleSetter::setNarrowMonth(syms, index, value, valueLength, *status);
1158 break;
1159
1160 case UDAT_STANDALONE_MONTHS:
1161 DateFormatSymbolsSingleSetter::setStandaloneMonth(syms, index, value, valueLength, *status);
1162 break;
1163
1164 case UDAT_STANDALONE_SHORT_MONTHS:
1165 DateFormatSymbolsSingleSetter::setStandaloneShortMonth(syms, index, value, valueLength, *status);
1166 break;
1167
1168 case UDAT_STANDALONE_NARROW_MONTHS:
1169 DateFormatSymbolsSingleSetter::setStandaloneNarrowMonth(syms, index, value, valueLength, *status);
1170 break;
1171
1172 case UDAT_WEEKDAYS:
1173 DateFormatSymbolsSingleSetter::setWeekday(syms, index, value, valueLength, *status);
1174 break;
1175
1176 case UDAT_SHORT_WEEKDAYS:
1177 DateFormatSymbolsSingleSetter::setShortWeekday(syms, index, value, valueLength, *status);
1178 break;
1179
1180 case UDAT_SHORTER_WEEKDAYS:
1181 DateFormatSymbolsSingleSetter::setShorterWeekday(syms, index, value, valueLength, *status);
1182 break;
1183
1184 case UDAT_NARROW_WEEKDAYS:
1185 DateFormatSymbolsSingleSetter::setNarrowWeekday(syms, index, value, valueLength, *status);
1186 break;
1187
1188 case UDAT_STANDALONE_WEEKDAYS:
1189 DateFormatSymbolsSingleSetter::setStandaloneWeekday(syms, index, value, valueLength, *status);
1190 break;
1191
1192 case UDAT_STANDALONE_SHORT_WEEKDAYS:
1193 DateFormatSymbolsSingleSetter::setStandaloneShortWeekday(syms, index, value, valueLength, *status);
1194 break;
1195
1196 case UDAT_STANDALONE_SHORTER_WEEKDAYS:
1197 DateFormatSymbolsSingleSetter::setStandaloneShorterWeekday(syms, index, value, valueLength, *status);
1198 break;
1199
1200 case UDAT_STANDALONE_NARROW_WEEKDAYS:
1201 DateFormatSymbolsSingleSetter::setStandaloneNarrowWeekday(syms, index, value, valueLength, *status);
1202 break;
1203
1204 case UDAT_QUARTERS:
1205 DateFormatSymbolsSingleSetter::setQuarter(syms, index, value, valueLength, *status);
1206 break;
1207
1208 case UDAT_SHORT_QUARTERS:
1209 DateFormatSymbolsSingleSetter::setShortQuarter(syms, index, value, valueLength, *status);
1210 break;
1211
1212 case UDAT_NARROW_QUARTERS:
1213 DateFormatSymbolsSingleSetter::setNarrowQuarter(syms, index, value, valueLength, *status);
1214 break;
1215
1216 case UDAT_STANDALONE_QUARTERS:
1217 DateFormatSymbolsSingleSetter::setStandaloneQuarter(syms, index, value, valueLength, *status);
1218 break;
1219
1220 case UDAT_STANDALONE_SHORT_QUARTERS:
1221 DateFormatSymbolsSingleSetter::setStandaloneShortQuarter(syms, index, value, valueLength, *status);
1222 break;
1223
1224 case UDAT_STANDALONE_NARROW_QUARTERS:
1225 DateFormatSymbolsSingleSetter::setStandaloneNarrowQuarter(syms, index, value, valueLength, *status);
1226 break;
1227
1228 case UDAT_CYCLIC_YEARS_ABBREVIATED:
1229 DateFormatSymbolsSingleSetter::setShortYearNames(syms, index, value, valueLength, *status);
1230 break;
1231
1232 case UDAT_ZODIAC_NAMES_ABBREVIATED:
1233 DateFormatSymbolsSingleSetter::setShortZodiacNames(syms, index, value, valueLength, *status);
1234 break;
1235
1236 case UDAT_AM_PMS:
1237 DateFormatSymbolsSingleSetter::setAmPm(syms, index, value, valueLength, *status);
1238 break;
1239
1240 case UDAT_LOCALIZED_CHARS:
1241 DateFormatSymbolsSingleSetter::setLocalPatternChars(syms, value, valueLength, *status);
1242 break;
1243
1244 default:
1245 *status = U_UNSUPPORTED_ERROR;
1246 break;
1247
1248 }
1249 }
1250
1251 U_CAPI const char* U_EXPORT2
udat_getLocaleByType(const UDateFormat * fmt,ULocDataLocaleType type,UErrorCode * status)1252 udat_getLocaleByType(const UDateFormat *fmt,
1253 ULocDataLocaleType type,
1254 UErrorCode* status)
1255 {
1256 if (fmt == NULL) {
1257 if (U_SUCCESS(*status)) {
1258 *status = U_ILLEGAL_ARGUMENT_ERROR;
1259 }
1260 return NULL;
1261 }
1262 return ((Format*)fmt)->getLocaleID(type, *status);
1263 }
1264
1265 U_CAPI void U_EXPORT2
udat_setContext(UDateFormat * fmt,UDisplayContext value,UErrorCode * status)1266 udat_setContext(UDateFormat* fmt, UDisplayContext value, UErrorCode* status)
1267 {
1268 if (U_FAILURE(*status)) {
1269 return;
1270 }
1271 ((DateFormat*)fmt)->setContext(value, *status);
1272 return;
1273 }
1274
1275 U_CAPI UDisplayContext U_EXPORT2
udat_getContext(const UDateFormat * fmt,UDisplayContextType type,UErrorCode * status)1276 udat_getContext(const UDateFormat* fmt, UDisplayContextType type, UErrorCode* status)
1277 {
1278 if (U_FAILURE(*status)) {
1279 return (UDisplayContext)0;
1280 }
1281 return ((const DateFormat*)fmt)->getContext(type, *status);
1282 }
1283
1284
1285 /**
1286 * Verify that fmt is a RelativeDateFormat. Invalid error if not.
1287 * @param fmt the UDateFormat, definitely a DateFormat, maybe something else
1288 * @param status error code, will be set to failure if there is a failure or the fmt is NULL.
1289 */
verifyIsRelativeDateFormat(const UDateFormat * fmt,UErrorCode * status)1290 static void verifyIsRelativeDateFormat(const UDateFormat* fmt, UErrorCode *status) {
1291 if(U_SUCCESS(*status) &&
1292 dynamic_cast<const RelativeDateFormat*>(reinterpret_cast<const DateFormat*>(fmt))==NULL) {
1293 *status = U_ILLEGAL_ARGUMENT_ERROR;
1294 }
1295 }
1296
1297
1298 U_CAPI int32_t U_EXPORT2
udat_toPatternRelativeDate(const UDateFormat * fmt,UChar * result,int32_t resultLength,UErrorCode * status)1299 udat_toPatternRelativeDate(const UDateFormat *fmt,
1300 UChar *result,
1301 int32_t resultLength,
1302 UErrorCode *status)
1303 {
1304 verifyIsRelativeDateFormat(fmt, status);
1305 if(U_FAILURE(*status)) {
1306 return -1;
1307 }
1308 if (result == NULL ? resultLength != 0 : resultLength < 0) {
1309 *status = U_ILLEGAL_ARGUMENT_ERROR;
1310 return -1;
1311 }
1312
1313 UnicodeString datePattern;
1314 if (result != NULL) {
1315 // NULL destination for pure preflighting: empty dummy string
1316 // otherwise, alias the destination buffer
1317 datePattern.setTo(result, 0, resultLength);
1318 }
1319 ((RelativeDateFormat*)fmt)->toPatternDate(datePattern, *status);
1320 return datePattern.extract(result, resultLength, *status);
1321 }
1322
1323 U_CAPI int32_t U_EXPORT2
udat_toPatternRelativeTime(const UDateFormat * fmt,UChar * result,int32_t resultLength,UErrorCode * status)1324 udat_toPatternRelativeTime(const UDateFormat *fmt,
1325 UChar *result,
1326 int32_t resultLength,
1327 UErrorCode *status)
1328 {
1329 verifyIsRelativeDateFormat(fmt, status);
1330 if(U_FAILURE(*status)) {
1331 return -1;
1332 }
1333 if (result == NULL ? resultLength != 0 : resultLength < 0) {
1334 *status = U_ILLEGAL_ARGUMENT_ERROR;
1335 return -1;
1336 }
1337
1338 UnicodeString timePattern;
1339 if (result != NULL) {
1340 // NULL destination for pure preflighting: empty dummy string
1341 // otherwise, alias the destination buffer
1342 timePattern.setTo(result, 0, resultLength);
1343 }
1344 ((RelativeDateFormat*)fmt)->toPatternTime(timePattern, *status);
1345 return timePattern.extract(result, resultLength, *status);
1346 }
1347
1348 U_CAPI void U_EXPORT2
udat_applyPatternRelative(UDateFormat * format,const UChar * datePattern,int32_t datePatternLength,const UChar * timePattern,int32_t timePatternLength,UErrorCode * status)1349 udat_applyPatternRelative(UDateFormat *format,
1350 const UChar *datePattern,
1351 int32_t datePatternLength,
1352 const UChar *timePattern,
1353 int32_t timePatternLength,
1354 UErrorCode *status)
1355 {
1356 verifyIsRelativeDateFormat(format, status);
1357 if(U_FAILURE(*status)) return;
1358 const UnicodeString datePat((UBool)(datePatternLength == -1), datePattern, datePatternLength);
1359 const UnicodeString timePat((UBool)(timePatternLength == -1), timePattern, timePatternLength);
1360 ((RelativeDateFormat*)format)->applyPatterns(datePat, timePat, *status);
1361 }
1362
1363 #endif /* #if !UCONFIG_NO_FORMATTING */
1364