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