]> git.saurik.com Git - apple/icu.git/blob - icuSources/i18n/udat.cpp
ICU-400.42.tar.gz
[apple/icu.git] / icuSources / i18n / udat.cpp
1 /*
2 *******************************************************************************
3 * Copyright (C) 1996-2009, 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 "cpputils.h"
25 #include "reldtfmt.h"
26
27 U_NAMESPACE_USE
28
29 /**
30 * Verify that fmt is a SimpleDateFormat. Invalid error if not.
31 * @param fmt the UDateFormat, definitely a DateFormat, maybe something else
32 * @param status error code, will be set to failure if there is a familure or the fmt is NULL.
33 */
34 static void verifyIsSimpleDateFormat(const UDateFormat* fmt, UErrorCode *status) {
35 if(!U_FAILURE(*status) &&
36 ((DateFormat*)fmt)->getDynamicClassID()!=SimpleDateFormat::getStaticClassID()) {
37 *status = U_ILLEGAL_ARGUMENT_ERROR;
38 }
39 }
40
41 U_CAPI UDateFormat* U_EXPORT2
42 udat_open(UDateFormatStyle timeStyle,
43 UDateFormatStyle dateStyle,
44 const char *locale,
45 const UChar *tzID,
46 int32_t tzIDLength,
47 const UChar *pattern,
48 int32_t patternLength,
49 UErrorCode *status)
50 {
51 DateFormat *fmt;
52 if(U_FAILURE(*status)) {
53 return 0;
54 }
55 if(timeStyle != UDAT_IGNORE) {
56 if(locale == 0) {
57 fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
58 (DateFormat::EStyle)timeStyle);
59 }
60 else {
61 fmt = DateFormat::createDateTimeInstance((DateFormat::EStyle)dateStyle,
62 (DateFormat::EStyle)timeStyle,
63 Locale(locale));
64 }
65 }
66 else {
67 UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength);
68
69 if(locale == 0) {
70 fmt = new SimpleDateFormat(pat, *status);
71 }
72 else {
73 fmt = new SimpleDateFormat(pat, Locale(locale), *status);
74 }
75 }
76
77 if(fmt == 0) {
78 *status = U_MEMORY_ALLOCATION_ERROR;
79 return 0;
80 }
81
82 if(tzID != 0) {
83 TimeZone *zone = TimeZone::createTimeZone(UnicodeString((UBool)(tzIDLength == -1), tzID, tzIDLength));
84 if(zone == 0) {
85 *status = U_MEMORY_ALLOCATION_ERROR;
86 delete fmt;
87 return 0;
88 }
89 fmt->adoptTimeZone(zone);
90 }
91
92 return (UDateFormat*)fmt;
93 }
94
95
96 U_CAPI void U_EXPORT2
97 udat_close(UDateFormat* format)
98 {
99 delete (DateFormat*)format;
100 }
101
102 U_CAPI UDateFormat* U_EXPORT2
103 udat_clone(const UDateFormat *fmt,
104 UErrorCode *status)
105 {
106 if(U_FAILURE(*status)) return 0;
107
108 /* clone is defined for DateFormat and implemented for all subclasses */
109 Format *res = ((DateFormat*)fmt)->clone();
110
111 if(res == 0) {
112 *status = U_MEMORY_ALLOCATION_ERROR;
113 return 0;
114 }
115
116 return (UDateFormat*) res;
117 }
118
119 U_CAPI int32_t U_EXPORT2
120 udat_format( const UDateFormat* format,
121 UDate dateToFormat,
122 UChar* result,
123 int32_t resultLength,
124 UFieldPosition* position,
125 UErrorCode* status)
126 {
127 if(U_FAILURE(*status)) return -1;
128
129 UnicodeString res;
130 if(!(result==NULL && resultLength==0)) {
131 // NULL destination for pure preflighting: empty dummy string
132 // otherwise, alias the destination buffer
133 res.setTo(result, 0, resultLength);
134 }
135
136 FieldPosition fp;
137
138 if(position != 0)
139 fp.setField(position->field);
140
141 ((DateFormat*)format)->format(dateToFormat, res, fp);
142
143 if(position != 0) {
144 position->beginIndex = fp.getBeginIndex();
145 position->endIndex = fp.getEndIndex();
146 }
147
148 return res.extract(result, resultLength, *status);
149 }
150
151 U_CAPI UDate U_EXPORT2
152 udat_parse( const UDateFormat* format,
153 const UChar* text,
154 int32_t textLength,
155 int32_t *parsePos,
156 UErrorCode *status)
157 {
158 if(U_FAILURE(*status)) return (UDate)0;
159
160 const UnicodeString src((UBool)(textLength == -1), text, textLength);
161 ParsePosition pp;
162 int32_t stackParsePos = 0;
163 UDate res;
164
165 if(parsePos == NULL) {
166 parsePos = &stackParsePos;
167 }
168
169 pp.setIndex(*parsePos);
170
171 res = ((DateFormat*)format)->parse(src, pp);
172
173 if(pp.getErrorIndex() == -1)
174 *parsePos = pp.getIndex();
175 else {
176 *parsePos = pp.getErrorIndex();
177 *status = U_PARSE_ERROR;
178 }
179
180 return res;
181 }
182
183 U_CAPI void U_EXPORT2
184 udat_parseCalendar(const UDateFormat* format,
185 UCalendar* calendar,
186 const UChar* text,
187 int32_t textLength,
188 int32_t *parsePos,
189 UErrorCode *status)
190 {
191 if(U_FAILURE(*status)) return;
192
193 const UnicodeString src((UBool)(textLength == -1), text, textLength);
194 ParsePosition pp;
195
196 if(parsePos != 0)
197 pp.setIndex(*parsePos);
198
199 ((DateFormat*)format)->parse(src, *(Calendar*)calendar, pp);
200
201 if(parsePos != 0) {
202 if(pp.getErrorIndex() == -1)
203 *parsePos = pp.getIndex();
204 else {
205 *parsePos = pp.getErrorIndex();
206 *status = U_PARSE_ERROR;
207 }
208 }
209 }
210
211 U_CAPI UBool U_EXPORT2
212 udat_isLenient(const UDateFormat* fmt)
213 {
214 return ((DateFormat*)fmt)->isLenient();
215 }
216
217 U_CAPI void U_EXPORT2
218 udat_setLenient( UDateFormat* fmt,
219 UBool isLenient)
220 {
221 ((DateFormat*)fmt)->setLenient(isLenient);
222 }
223
224 U_CAPI const UCalendar* U_EXPORT2
225 udat_getCalendar(const UDateFormat* fmt)
226 {
227 return (const UCalendar*) ((DateFormat*)fmt)->getCalendar();
228 }
229
230 U_CAPI void U_EXPORT2
231 udat_setCalendar(UDateFormat* fmt,
232 const UCalendar* calendarToSet)
233 {
234 ((DateFormat*)fmt)->setCalendar(*((Calendar*)calendarToSet));
235 }
236
237 U_CAPI const UNumberFormat* U_EXPORT2
238 udat_getNumberFormat(const UDateFormat* fmt)
239 {
240 return (const UNumberFormat*) ((DateFormat*)fmt)->getNumberFormat();
241 }
242
243 U_CAPI void U_EXPORT2
244 udat_setNumberFormat(UDateFormat* fmt,
245 const UNumberFormat* numberFormatToSet)
246 {
247 ((DateFormat*)fmt)->setNumberFormat(*((NumberFormat*)numberFormatToSet));
248 }
249
250 U_CAPI const char* U_EXPORT2
251 udat_getAvailable(int32_t index)
252 {
253 return uloc_getAvailable(index);
254 }
255
256 U_CAPI int32_t U_EXPORT2
257 udat_countAvailable()
258 {
259 return uloc_countAvailable();
260 }
261
262 U_CAPI UDate U_EXPORT2
263 udat_get2DigitYearStart( const UDateFormat *fmt,
264 UErrorCode *status)
265 {
266 verifyIsSimpleDateFormat(fmt, status);
267 if(U_FAILURE(*status)) return (UDate)0;
268 return ((SimpleDateFormat*)fmt)->get2DigitYearStart(*status);
269 }
270
271 U_CAPI void U_EXPORT2
272 udat_set2DigitYearStart( UDateFormat *fmt,
273 UDate d,
274 UErrorCode *status)
275 {
276 verifyIsSimpleDateFormat(fmt, status);
277 if(U_FAILURE(*status)) return;
278 ((SimpleDateFormat*)fmt)->set2DigitYearStart(d, *status);
279 }
280
281 U_CAPI int32_t U_EXPORT2
282 udat_toPattern( const UDateFormat *fmt,
283 UBool localized,
284 UChar *result,
285 int32_t resultLength,
286 UErrorCode *status)
287 {
288 if(U_FAILURE(*status)) return -1;
289
290 UnicodeString res;
291 if(!(result==NULL && resultLength==0)) {
292 // NULL destination for pure preflighting: empty dummy string
293 // otherwise, alias the destination buffer
294 res.setTo(result, 0, resultLength);
295 }
296
297 if ( ((DateFormat*)fmt)->getDynamicClassID()==SimpleDateFormat::getStaticClassID() ) {
298 if(localized)
299 ((SimpleDateFormat*)fmt)->toLocalizedPattern(res, *status);
300 else
301 ((SimpleDateFormat*)fmt)->toPattern(res);
302 } else if ( !localized && ((DateFormat*)fmt)->getDynamicClassID()==RelativeDateFormat::getStaticClassID() ) {
303 ((RelativeDateFormat*)fmt)->toPattern(res, *status);
304 } else {
305 *status = U_ILLEGAL_ARGUMENT_ERROR;
306 return -1;
307 }
308
309 return res.extract(result, resultLength, *status);
310 }
311
312 // TBD: should this take an UErrorCode?
313 U_CAPI void U_EXPORT2
314 udat_applyPattern( UDateFormat *format,
315 UBool localized,
316 const UChar *pattern,
317 int32_t patternLength)
318 {
319 UErrorCode status = U_ZERO_ERROR;
320 verifyIsSimpleDateFormat(format, &status);
321 if(U_FAILURE(status)) {
322 return;
323 }
324 const UnicodeString pat((UBool)(patternLength == -1), pattern, patternLength);
325
326 if(localized)
327 ((SimpleDateFormat*)format)->applyLocalizedPattern(pat, status);
328 else
329 ((SimpleDateFormat*)format)->applyPattern(pat);
330 }
331
332 U_CAPI int32_t U_EXPORT2
333 udat_getSymbols(const UDateFormat *fmt,
334 UDateFormatSymbolType type,
335 int32_t index,
336 UChar *result,
337 int32_t resultLength,
338 UErrorCode *status)
339 {
340 verifyIsSimpleDateFormat(fmt, status);
341 if(U_FAILURE(*status)) return -1;
342
343 const DateFormatSymbols *syms =
344 ((SimpleDateFormat*)fmt)->getDateFormatSymbols();
345 int32_t count;
346 const UnicodeString *res = NULL;
347
348 switch(type) {
349 case UDAT_ERAS:
350 res = syms->getEras(count);
351 break;
352
353 case UDAT_ERA_NAMES:
354 res = syms->getEraNames(count);
355 break;
356
357 case UDAT_MONTHS:
358 res = syms->getMonths(count);
359 break;
360
361 case UDAT_SHORT_MONTHS:
362 res = syms->getShortMonths(count);
363 break;
364
365 case UDAT_WEEKDAYS:
366 res = syms->getWeekdays(count);
367 break;
368
369 case UDAT_SHORT_WEEKDAYS:
370 res = syms->getShortWeekdays(count);
371 break;
372
373 case UDAT_AM_PMS:
374 res = syms->getAmPmStrings(count);
375 break;
376
377 case UDAT_LOCALIZED_CHARS:
378 {
379 UnicodeString res1;
380 if(!(result==NULL && resultLength==0)) {
381 // NULL destination for pure preflighting: empty dummy string
382 // otherwise, alias the destination buffer
383 res1.setTo(result, 0, resultLength);
384 }
385 syms->getLocalPatternChars(res1);
386 return res1.extract(result, resultLength, *status);
387 }
388
389 case UDAT_NARROW_MONTHS:
390 res = syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
391 break;
392
393 case UDAT_NARROW_WEEKDAYS:
394 res = syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
395 break;
396
397 case UDAT_STANDALONE_MONTHS:
398 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
399 break;
400
401 case UDAT_STANDALONE_SHORT_MONTHS:
402 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
403 break;
404
405 case UDAT_STANDALONE_NARROW_MONTHS:
406 res = syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
407 break;
408
409 case UDAT_STANDALONE_WEEKDAYS:
410 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
411 break;
412
413 case UDAT_STANDALONE_SHORT_WEEKDAYS:
414 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
415 break;
416
417 case UDAT_STANDALONE_NARROW_WEEKDAYS:
418 res = syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
419 break;
420
421 case UDAT_QUARTERS:
422 res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
423 break;
424
425 case UDAT_SHORT_QUARTERS:
426 res = syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
427 break;
428
429 case UDAT_STANDALONE_QUARTERS:
430 res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
431 break;
432
433 case UDAT_STANDALONE_SHORT_QUARTERS:
434 res = syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
435 break;
436
437 }
438
439 if(index < count) {
440 return res[index].extract(result, resultLength, *status);
441 }
442 return 0;
443 }
444
445 U_CAPI int32_t U_EXPORT2
446 udat_countSymbols( const UDateFormat *fmt,
447 UDateFormatSymbolType type)
448 {
449 UErrorCode status = U_ZERO_ERROR;
450 verifyIsSimpleDateFormat(fmt, &status);
451 if(U_FAILURE(status)) {
452 return 0;
453 }
454
455 const DateFormatSymbols *syms =
456 ((SimpleDateFormat*)fmt)->getDateFormatSymbols();
457 int32_t count = 0;
458
459 switch(type) {
460 case UDAT_ERAS:
461 syms->getEras(count);
462 break;
463
464 case UDAT_MONTHS:
465 syms->getMonths(count);
466 break;
467
468 case UDAT_SHORT_MONTHS:
469 syms->getShortMonths(count);
470 break;
471
472 case UDAT_WEEKDAYS:
473 syms->getWeekdays(count);
474 break;
475
476 case UDAT_SHORT_WEEKDAYS:
477 syms->getShortWeekdays(count);
478 break;
479
480 case UDAT_AM_PMS:
481 syms->getAmPmStrings(count);
482 break;
483
484 case UDAT_LOCALIZED_CHARS:
485 count = 1;
486 break;
487
488 case UDAT_ERA_NAMES:
489 syms->getEraNames(count);
490 break;
491
492 case UDAT_NARROW_MONTHS:
493 syms->getMonths(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
494 break;
495
496 case UDAT_NARROW_WEEKDAYS:
497 syms->getWeekdays(count, DateFormatSymbols::FORMAT, DateFormatSymbols::NARROW);
498 break;
499
500 case UDAT_STANDALONE_MONTHS:
501 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
502 break;
503
504 case UDAT_STANDALONE_SHORT_MONTHS:
505 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
506 break;
507
508 case UDAT_STANDALONE_NARROW_MONTHS:
509 syms->getMonths(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
510 break;
511
512 case UDAT_STANDALONE_WEEKDAYS:
513 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
514 break;
515
516 case UDAT_STANDALONE_SHORT_WEEKDAYS:
517 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
518 break;
519
520 case UDAT_STANDALONE_NARROW_WEEKDAYS:
521 syms->getWeekdays(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::NARROW);
522 break;
523
524 case UDAT_QUARTERS:
525 syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::WIDE);
526 break;
527
528 case UDAT_SHORT_QUARTERS:
529 syms->getQuarters(count, DateFormatSymbols::FORMAT, DateFormatSymbols::ABBREVIATED);
530 break;
531
532 case UDAT_STANDALONE_QUARTERS:
533 syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::WIDE);
534 break;
535
536 case UDAT_STANDALONE_SHORT_QUARTERS:
537 syms->getQuarters(count, DateFormatSymbols::STANDALONE, DateFormatSymbols::ABBREVIATED);
538 break;
539
540 }
541
542 return count;
543 }
544
545 U_NAMESPACE_BEGIN
546
547 /*
548 * This DateFormatSymbolsSingleSetter class is a friend of DateFormatSymbols
549 * solely for the purpose of avoiding to clone the array of strings
550 * just to modify one of them and then setting all of them back.
551 * For example, the old code looked like this:
552 * case UDAT_MONTHS:
553 * res = syms->getMonths(count);
554 * array = new UnicodeString[count];
555 * if(array == 0) {
556 * *status = U_MEMORY_ALLOCATION_ERROR;
557 * return;
558 * }
559 * uprv_arrayCopy(res, array, count);
560 * if(index < count)
561 * array[index] = val;
562 * syms->setMonths(array, count);
563 * break;
564 *
565 * Even worse, the old code actually cloned the entire DateFormatSymbols object,
566 * cloned one value array, changed one value, and then made the SimpleDateFormat
567 * replace its DateFormatSymbols object with the new one.
568 *
569 * markus 2002-oct-14
570 */
571 class DateFormatSymbolsSingleSetter /* not : public UObject because all methods are static */ {
572 public:
573 static void
574 setSymbol(UnicodeString *array, int32_t count, int32_t index,
575 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
576 {
577 if(array!=NULL) {
578 if(index>=count) {
579 errorCode=U_INDEX_OUTOFBOUNDS_ERROR;
580 } else if(value==NULL) {
581 errorCode=U_ILLEGAL_ARGUMENT_ERROR;
582 } else {
583 array[index].setTo(value, valueLength);
584 }
585 }
586 }
587
588 static void
589 setEra(DateFormatSymbols *syms, int32_t index,
590 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
591 {
592 setSymbol(syms->fEras, syms->fErasCount, index, value, valueLength, errorCode);
593 }
594
595 static void
596 setEraName(DateFormatSymbols *syms, int32_t index,
597 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
598 {
599 setSymbol(syms->fEraNames, syms->fEraNamesCount, index, value, valueLength, errorCode);
600 }
601
602 static void
603 setMonth(DateFormatSymbols *syms, int32_t index,
604 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
605 {
606 setSymbol(syms->fMonths, syms->fMonthsCount, index, value, valueLength, errorCode);
607 }
608
609 static void
610 setShortMonth(DateFormatSymbols *syms, int32_t index,
611 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
612 {
613 setSymbol(syms->fShortMonths, syms->fShortMonthsCount, index, value, valueLength, errorCode);
614 }
615
616 static void
617 setNarrowMonth(DateFormatSymbols *syms, int32_t index,
618 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
619 {
620 setSymbol(syms->fNarrowMonths, syms->fNarrowMonthsCount, index, value, valueLength, errorCode);
621 }
622
623 static void
624 setStandaloneMonth(DateFormatSymbols *syms, int32_t index,
625 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
626 {
627 setSymbol(syms->fStandaloneMonths, syms->fStandaloneMonthsCount, index, value, valueLength, errorCode);
628 }
629
630 static void
631 setStandaloneShortMonth(DateFormatSymbols *syms, int32_t index,
632 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
633 {
634 setSymbol(syms->fStandaloneShortMonths, syms->fStandaloneShortMonthsCount, index, value, valueLength, errorCode);
635 }
636
637 static void
638 setStandaloneNarrowMonth(DateFormatSymbols *syms, int32_t index,
639 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
640 {
641 setSymbol(syms->fStandaloneNarrowMonths, syms->fStandaloneNarrowMonthsCount, index, value, valueLength, errorCode);
642 }
643
644 static void
645 setWeekday(DateFormatSymbols *syms, int32_t index,
646 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
647 {
648 setSymbol(syms->fWeekdays, syms->fWeekdaysCount, index, value, valueLength, errorCode);
649 }
650
651 static void
652 setShortWeekday(DateFormatSymbols *syms, int32_t index,
653 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
654 {
655 setSymbol(syms->fShortWeekdays, syms->fShortWeekdaysCount, index, value, valueLength, errorCode);
656 }
657
658 static void
659 setNarrowWeekday(DateFormatSymbols *syms, int32_t index,
660 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
661 {
662 setSymbol(syms->fNarrowWeekdays, syms->fNarrowWeekdaysCount, index, value, valueLength, errorCode);
663 }
664
665 static void
666 setStandaloneWeekday(DateFormatSymbols *syms, int32_t index,
667 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
668 {
669 setSymbol(syms->fStandaloneWeekdays, syms->fStandaloneWeekdaysCount, index, value, valueLength, errorCode);
670 }
671
672 static void
673 setStandaloneShortWeekday(DateFormatSymbols *syms, int32_t index,
674 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
675 {
676 setSymbol(syms->fStandaloneShortWeekdays, syms->fStandaloneShortWeekdaysCount, index, value, valueLength, errorCode);
677 }
678
679 static void
680 setStandaloneNarrowWeekday(DateFormatSymbols *syms, int32_t index,
681 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
682 {
683 setSymbol(syms->fStandaloneNarrowWeekdays, syms->fStandaloneNarrowWeekdaysCount, index, value, valueLength, errorCode);
684 }
685
686 static void
687 setQuarter(DateFormatSymbols *syms, int32_t index,
688 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
689 {
690 setSymbol(syms->fQuarters, syms->fQuartersCount, index, value, valueLength, errorCode);
691 }
692
693 static void
694 setShortQuarter(DateFormatSymbols *syms, int32_t index,
695 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
696 {
697 setSymbol(syms->fShortQuarters, syms->fShortQuartersCount, index, value, valueLength, errorCode);
698 }
699
700 static void
701 setStandaloneQuarter(DateFormatSymbols *syms, int32_t index,
702 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
703 {
704 setSymbol(syms->fStandaloneQuarters, syms->fStandaloneQuartersCount, index, value, valueLength, errorCode);
705 }
706
707 static void
708 setStandaloneShortQuarter(DateFormatSymbols *syms, int32_t index,
709 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
710 {
711 setSymbol(syms->fStandaloneShortQuarters, syms->fStandaloneShortQuartersCount, index, value, valueLength, errorCode);
712 }
713
714 static void
715 setAmPm(DateFormatSymbols *syms, int32_t index,
716 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
717 {
718 setSymbol(syms->fAmPms, syms->fAmPmsCount, index, value, valueLength, errorCode);
719 }
720
721 static void
722 setLocalPatternChars(DateFormatSymbols *syms,
723 const UChar *value, int32_t valueLength, UErrorCode &errorCode)
724 {
725 setSymbol(&syms->fLocalPatternChars, 1, 0, value, valueLength, errorCode);
726 }
727 };
728
729 U_NAMESPACE_END
730
731 U_CAPI void U_EXPORT2
732 udat_setSymbols( UDateFormat *format,
733 UDateFormatSymbolType type,
734 int32_t index,
735 UChar *value,
736 int32_t valueLength,
737 UErrorCode *status)
738 {
739 verifyIsSimpleDateFormat(format, status);
740 if(U_FAILURE(*status)) return;
741
742 DateFormatSymbols *syms = (DateFormatSymbols *)((SimpleDateFormat *)format)->getDateFormatSymbols();
743
744 switch(type) {
745 case UDAT_ERAS:
746 DateFormatSymbolsSingleSetter::setEra(syms, index, value, valueLength, *status);
747 break;
748
749 case UDAT_ERA_NAMES:
750 DateFormatSymbolsSingleSetter::setEraName(syms, index, value, valueLength, *status);
751 break;
752
753 case UDAT_MONTHS:
754 DateFormatSymbolsSingleSetter::setMonth(syms, index, value, valueLength, *status);
755 break;
756
757 case UDAT_SHORT_MONTHS:
758 DateFormatSymbolsSingleSetter::setShortMonth(syms, index, value, valueLength, *status);
759 break;
760
761 case UDAT_NARROW_MONTHS:
762 DateFormatSymbolsSingleSetter::setNarrowMonth(syms, index, value, valueLength, *status);
763 break;
764
765 case UDAT_STANDALONE_MONTHS:
766 DateFormatSymbolsSingleSetter::setStandaloneMonth(syms, index, value, valueLength, *status);
767 break;
768
769 case UDAT_STANDALONE_SHORT_MONTHS:
770 DateFormatSymbolsSingleSetter::setStandaloneShortMonth(syms, index, value, valueLength, *status);
771 break;
772
773 case UDAT_STANDALONE_NARROW_MONTHS:
774 DateFormatSymbolsSingleSetter::setStandaloneNarrowMonth(syms, index, value, valueLength, *status);
775 break;
776
777 case UDAT_WEEKDAYS:
778 DateFormatSymbolsSingleSetter::setWeekday(syms, index, value, valueLength, *status);
779 break;
780
781 case UDAT_SHORT_WEEKDAYS:
782 DateFormatSymbolsSingleSetter::setShortWeekday(syms, index, value, valueLength, *status);
783 break;
784
785 case UDAT_NARROW_WEEKDAYS:
786 DateFormatSymbolsSingleSetter::setNarrowWeekday(syms, index, value, valueLength, *status);
787 break;
788
789 case UDAT_STANDALONE_WEEKDAYS:
790 DateFormatSymbolsSingleSetter::setStandaloneWeekday(syms, index, value, valueLength, *status);
791 break;
792
793 case UDAT_STANDALONE_SHORT_WEEKDAYS:
794 DateFormatSymbolsSingleSetter::setStandaloneShortWeekday(syms, index, value, valueLength, *status);
795 break;
796
797 case UDAT_STANDALONE_NARROW_WEEKDAYS:
798 DateFormatSymbolsSingleSetter::setStandaloneNarrowWeekday(syms, index, value, valueLength, *status);
799 break;
800
801 case UDAT_QUARTERS:
802 DateFormatSymbolsSingleSetter::setQuarter(syms, index, value, valueLength, *status);
803 break;
804
805 case UDAT_SHORT_QUARTERS:
806 DateFormatSymbolsSingleSetter::setShortQuarter(syms, index, value, valueLength, *status);
807 break;
808
809 case UDAT_STANDALONE_QUARTERS:
810 DateFormatSymbolsSingleSetter::setStandaloneQuarter(syms, index, value, valueLength, *status);
811 break;
812
813 case UDAT_STANDALONE_SHORT_QUARTERS:
814 DateFormatSymbolsSingleSetter::setStandaloneShortQuarter(syms, index, value, valueLength, *status);
815 break;
816
817 case UDAT_AM_PMS:
818 DateFormatSymbolsSingleSetter::setAmPm(syms, index, value, valueLength, *status);
819 break;
820
821 case UDAT_LOCALIZED_CHARS:
822 DateFormatSymbolsSingleSetter::setLocalPatternChars(syms, value, valueLength, *status);
823 break;
824
825 default:
826 *status = U_UNSUPPORTED_ERROR;
827 break;
828
829 }
830 }
831
832 U_CAPI const char* U_EXPORT2
833 udat_getLocaleByType(const UDateFormat *fmt,
834 ULocDataLocaleType type,
835 UErrorCode* status)
836 {
837 if (fmt == NULL) {
838 if (U_SUCCESS(*status)) {
839 *status = U_ILLEGAL_ARGUMENT_ERROR;
840 }
841 return NULL;
842 }
843 return ((Format*)fmt)->getLocaleID(type, *status);
844 }
845
846 /**
847 * Verify that fmt is a RelativeDateFormat. Invalid error if not.
848 * @param fmt the UDateFormat, definitely a DateFormat, maybe something else
849 * @param status error code, will be set to failure if there is a familure or the fmt is NULL.
850 */
851 static void verifyIsRelativeDateFormat(const UDateFormat* fmt, UErrorCode *status) {
852 if(!U_FAILURE(*status) &&
853 ((DateFormat*)fmt)->getDynamicClassID()!=RelativeDateFormat::getStaticClassID()) {
854 *status = U_ILLEGAL_ARGUMENT_ERROR;
855 }
856 }
857
858
859 U_CAPI int32_t U_EXPORT2
860 udat_toPatternRelativeDate(const UDateFormat *fmt,
861 UChar *result,
862 int32_t resultLength,
863 UErrorCode *status)
864 {
865 verifyIsRelativeDateFormat(fmt, status);
866 if(U_FAILURE(*status)) return -1;
867
868 UnicodeString datePattern;
869 if(!(result==NULL && resultLength==0)) {
870 // NULL destination for pure preflighting: empty dummy string
871 // otherwise, alias the destination buffer
872 datePattern.setTo(result, 0, resultLength);
873 }
874 ((RelativeDateFormat*)fmt)->toPatternDate(datePattern, *status);
875 return datePattern.extract(result, resultLength, *status);
876 }
877
878 U_CAPI int32_t U_EXPORT2
879 udat_toPatternRelativeTime(const UDateFormat *fmt,
880 UChar *result,
881 int32_t resultLength,
882 UErrorCode *status)
883 {
884 verifyIsRelativeDateFormat(fmt, status);
885 if(U_FAILURE(*status)) return -1;
886
887 UnicodeString timePattern;
888 if(!(result==NULL && resultLength==0)) {
889 // NULL destination for pure preflighting: empty dummy string
890 // otherwise, alias the destination buffer
891 timePattern.setTo(result, 0, resultLength);
892 }
893 ((RelativeDateFormat*)fmt)->toPatternTime(timePattern, *status);
894 return timePattern.extract(result, resultLength, *status);
895 }
896
897 U_CAPI void U_EXPORT2
898 udat_applyPatternRelative(UDateFormat *format,
899 const UChar *datePattern,
900 int32_t datePatternLength,
901 const UChar *timePattern,
902 int32_t timePatternLength,
903 UErrorCode *status)
904 {
905 verifyIsRelativeDateFormat(format, status);
906 if(U_FAILURE(*status)) return;
907 const UnicodeString datePat((UBool)(datePatternLength == -1), datePattern, datePatternLength);
908 const UnicodeString timePat((UBool)(timePatternLength == -1), timePattern, timePatternLength);
909 ((RelativeDateFormat*)format)->applyPatterns(datePat, timePat, *status);
910 }
911
912 #endif /* #if !UCONFIG_NO_FORMATTING */