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