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