Coverage Report

Created: 2025-06-24 06:43

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