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