2 *******************************************************************************
3 * Copyright (C) 1996-2004, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 *******************************************************************************
8 #include "unicode/utypes.h"
10 #if !UCONFIG_NO_FORMATTING
12 #include "unicode/udat.h"
14 #include "unicode/uloc.h"
15 #include "unicode/datefmt.h"
16 #include "unicode/timezone.h"
17 #include "unicode/smpdtfmt.h"
18 #include "unicode/fieldpos.h"
19 #include "unicode/parsepos.h"
20 #include "unicode/calendar.h"
21 #include "unicode/numfmt.h"
22 #include "unicode/dtfmtsym.h"
23 #include "unicode/ustring.h"
28 U_CAPI UDateFormat
* U_EXPORT2
29 udat_open(UDateFormatStyle timeStyle
,
30 UDateFormatStyle dateStyle
,
35 int32_t patternLength
,
38 if(U_FAILURE(*status
))
42 if(timeStyle
!= UDAT_IGNORE
)
46 fmt
= DateFormat::createDateTimeInstance((DateFormat::EStyle
)dateStyle
,
47 (DateFormat::EStyle
)timeStyle
);
49 fmt
= DateFormat::createDateTimeInstance((DateFormat::EStyle
)dateStyle
,
50 (DateFormat::EStyle
)timeStyle
,
54 *status
= U_MEMORY_ALLOCATION_ERROR
;
59 TimeZone
*zone
= TimeZone::createTimeZone(UnicodeString((UBool
)(tzIDLength
== -1), tzID
, tzIDLength
));
61 *status
= U_MEMORY_ALLOCATION_ERROR
;
65 fmt
->adoptTimeZone(zone
);
68 return (UDateFormat
*)fmt
;
72 const UnicodeString pat
= UnicodeString((UBool
)(patternLength
== -1), pattern
, patternLength
);
73 UDateFormat
*retVal
= 0;
76 retVal
= (UDateFormat
*)new SimpleDateFormat(pat
, *status
);
78 retVal
= (UDateFormat
*)new SimpleDateFormat(pat
, Locale(locale
), *status
);
81 *status
= U_MEMORY_ALLOCATION_ERROR
;
90 udat_close(UDateFormat
* format
)
92 delete (DateFormat
*)format
;
95 U_CAPI UDateFormat
* U_EXPORT2
96 udat_clone(const UDateFormat
*fmt
,
99 if(U_FAILURE(*status
)) return 0;
101 Format
*res
= ((SimpleDateFormat
*)fmt
)->clone();
104 *status
= U_MEMORY_ALLOCATION_ERROR
;
108 return (UDateFormat
*) res
;
111 U_CAPI
int32_t U_EXPORT2
112 udat_format( const UDateFormat
* format
,
115 int32_t resultLength
,
116 UFieldPosition
* position
,
119 if(U_FAILURE(*status
)) return -1;
122 if(!(result
==NULL
&& resultLength
==0)) {
123 // NULL destination for pure preflighting: empty dummy string
124 // otherwise, alias the destination buffer
125 res
.setTo(result
, 0, resultLength
);
131 fp
.setField(position
->field
);
133 ((DateFormat
*)format
)->format(dateToFormat
, res
, fp
);
136 position
->beginIndex
= fp
.getBeginIndex();
137 position
->endIndex
= fp
.getEndIndex();
140 return res
.extract(result
, resultLength
, *status
);
143 U_CAPI UDate U_EXPORT2
144 udat_parse( const UDateFormat
* format
,
150 if(U_FAILURE(*status
)) return (UDate
)0;
152 const UnicodeString
src((UBool
)(textLength
== -1), text
, textLength
);
154 int32_t stackParsePos
= 0;
157 if(parsePos
== NULL
) {
158 parsePos
= &stackParsePos
;
161 pp
.setIndex(*parsePos
);
163 res
= ((DateFormat
*)format
)->parse(src
, pp
);
165 if(pp
.getErrorIndex() == -1)
166 *parsePos
= pp
.getIndex();
168 *parsePos
= pp
.getErrorIndex();
169 *status
= U_PARSE_ERROR
;
175 U_CAPI
void U_EXPORT2
176 udat_parseCalendar(const UDateFormat
* format
,
183 if(U_FAILURE(*status
)) return;
185 const UnicodeString
src((UBool
)(textLength
== -1), text
, textLength
);
189 pp
.setIndex(*parsePos
);
191 ((DateFormat
*)format
)->parse(src
, *(Calendar
*)calendar
, pp
);
194 if(pp
.getErrorIndex() == -1)
195 *parsePos
= pp
.getIndex();
197 *parsePos
= pp
.getErrorIndex();
198 *status
= U_PARSE_ERROR
;
203 U_CAPI UBool U_EXPORT2
204 udat_isLenient(const UDateFormat
* fmt
)
206 return ((DateFormat
*)fmt
)->isLenient();
209 U_CAPI
void U_EXPORT2
210 udat_setLenient( UDateFormat
* fmt
,
213 ((DateFormat
*)fmt
)->setLenient(isLenient
);
216 U_CAPI
const UCalendar
* U_EXPORT2
217 udat_getCalendar(const UDateFormat
* fmt
)
219 return (const UCalendar
*) ((DateFormat
*)fmt
)->getCalendar();
222 U_CAPI
void U_EXPORT2
223 udat_setCalendar(UDateFormat
* fmt
,
224 const UCalendar
* calendarToSet
)
226 ((DateFormat
*)fmt
)->setCalendar(*((Calendar
*)calendarToSet
));
229 U_CAPI
const UNumberFormat
* U_EXPORT2
230 udat_getNumberFormat(const UDateFormat
* fmt
)
232 return (const UNumberFormat
*) ((DateFormat
*)fmt
)->getNumberFormat();
235 U_CAPI
void U_EXPORT2
236 udat_setNumberFormat(UDateFormat
* fmt
,
237 const UNumberFormat
* numberFormatToSet
)
239 ((DateFormat
*)fmt
)->setNumberFormat(*((NumberFormat
*)numberFormatToSet
));
242 U_CAPI
const char* U_EXPORT2
243 udat_getAvailable(int32_t index
)
245 return uloc_getAvailable(index
);
248 U_CAPI
int32_t U_EXPORT2
249 udat_countAvailable()
251 return uloc_countAvailable();
254 U_CAPI UDate U_EXPORT2
255 udat_get2DigitYearStart( const UDateFormat
*fmt
,
258 if(U_FAILURE(*status
)) return (UDate
)0;
259 return ((SimpleDateFormat
*)fmt
)->get2DigitYearStart(*status
);
262 U_CAPI
void U_EXPORT2
263 udat_set2DigitYearStart( UDateFormat
*fmt
,
267 if(U_FAILURE(*status
)) return;
268 ((SimpleDateFormat
*)fmt
)->set2DigitYearStart(d
, *status
);
271 U_CAPI
int32_t U_EXPORT2
272 udat_toPattern( const UDateFormat
*fmt
,
275 int32_t resultLength
,
278 if(U_FAILURE(*status
)) return -1;
281 if(!(result
==NULL
&& resultLength
==0)) {
282 // NULL destination for pure preflighting: empty dummy string
283 // otherwise, alias the destination buffer
284 res
.setTo(result
, 0, resultLength
);
288 ((SimpleDateFormat
*)fmt
)->toLocalizedPattern(res
, *status
);
290 ((SimpleDateFormat
*)fmt
)->toPattern(res
);
292 return res
.extract(result
, resultLength
, *status
);
295 // TBD: should this take an UErrorCode?
296 U_CAPI
void U_EXPORT2
297 udat_applyPattern( UDateFormat
*format
,
299 const UChar
*pattern
,
300 int32_t patternLength
)
302 const UnicodeString
pat((UBool
)(patternLength
== -1), pattern
, patternLength
);
303 UErrorCode status
= U_ZERO_ERROR
;
306 ((SimpleDateFormat
*)format
)->applyLocalizedPattern(pat
, status
);
308 ((SimpleDateFormat
*)format
)->applyPattern(pat
);
311 U_CAPI
int32_t U_EXPORT2
312 udat_getSymbols(const UDateFormat
*fmt
,
313 UDateFormatSymbolType type
,
316 int32_t resultLength
,
319 if(U_FAILURE(*status
)) return -1;
321 const DateFormatSymbols
*syms
=
322 ((SimpleDateFormat
*)fmt
)->getDateFormatSymbols();
324 const UnicodeString
*res
;
328 res
= syms
->getEras(count
);
330 return res
[index
].extract(result
, resultLength
, *status
);
335 res
= syms
->getMonths(count
);
337 return res
[index
].extract(result
, resultLength
, *status
);
341 case UDAT_SHORT_MONTHS
:
342 res
= syms
->getShortMonths(count
);
344 return res
[index
].extract(result
, resultLength
, *status
);
349 res
= syms
->getWeekdays(count
);
351 return res
[index
].extract(result
, resultLength
, *status
);
355 case UDAT_SHORT_WEEKDAYS
:
356 res
= syms
->getShortWeekdays(count
);
358 return res
[index
].extract(result
, resultLength
, *status
);
363 res
= syms
->getAmPmStrings(count
);
365 return res
[index
].extract(result
, resultLength
, *status
);
369 case UDAT_LOCALIZED_CHARS
:
372 if(!(result
==NULL
&& resultLength
==0)) {
373 // NULL destination for pure preflighting: empty dummy string
374 // otherwise, alias the destination buffer
375 res1
.setTo(result
, 0, resultLength
);
377 syms
->getLocalPatternChars(res1
);
378 return res1
.extract(result
, resultLength
, *status
);
385 U_CAPI
int32_t U_EXPORT2
386 udat_countSymbols( const UDateFormat
*fmt
,
387 UDateFormatSymbolType type
)
389 const DateFormatSymbols
*syms
=
390 ((SimpleDateFormat
*)fmt
)->getDateFormatSymbols();
395 syms
->getEras(count
);
399 syms
->getMonths(count
);
402 case UDAT_SHORT_MONTHS
:
403 syms
->getShortMonths(count
);
407 syms
->getWeekdays(count
);
410 case UDAT_SHORT_WEEKDAYS
:
411 syms
->getShortWeekdays(count
);
415 syms
->getAmPmStrings(count
);
418 case UDAT_LOCALIZED_CHARS
:
429 * This DateFormatSymbolsSingleSetter class is a friend of DateFormatSymbols
430 * solely for the purpose of avoiding to clone the array of strings
431 * just to modify one of them and then setting all of them back.
432 * For example, the old code looked like this:
434 * res = syms->getMonths(count);
435 * array = new UnicodeString[count];
437 * *status = U_MEMORY_ALLOCATION_ERROR;
440 * uprv_arrayCopy(res, array, count);
442 * array[index] = val;
443 * syms->setMonths(array, count);
446 * Even worse, the old code actually cloned the entire DateFormatSymbols object,
447 * cloned one value array, changed one value, and then made the SimpleDateFormat
448 * replace its DateFormatSymbols object with the new one.
452 class DateFormatSymbolsSingleSetter
/* not : public UObject because all methods are static */ {
455 setSymbol(UnicodeString
*array
, int32_t count
, int32_t index
,
456 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
460 errorCode
=U_INDEX_OUTOFBOUNDS_ERROR
;
461 } else if(value
==NULL
) {
462 errorCode
=U_ILLEGAL_ARGUMENT_ERROR
;
464 array
[index
].setTo(value
, valueLength
);
470 setEra(DateFormatSymbols
*syms
, int32_t index
,
471 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
473 setSymbol(syms
->fEras
, syms
->fErasCount
, index
, value
, valueLength
, errorCode
);
477 setMonth(DateFormatSymbols
*syms
, int32_t index
,
478 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
480 setSymbol(syms
->fMonths
, syms
->fMonthsCount
, index
, value
, valueLength
, errorCode
);
484 setShortMonth(DateFormatSymbols
*syms
, int32_t index
,
485 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
487 setSymbol(syms
->fShortMonths
, syms
->fShortMonthsCount
, index
, value
, valueLength
, errorCode
);
491 setWeekday(DateFormatSymbols
*syms
, int32_t index
,
492 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
494 setSymbol(syms
->fWeekdays
, syms
->fWeekdaysCount
, index
, value
, valueLength
, errorCode
);
498 setShortWeekday(DateFormatSymbols
*syms
, int32_t index
,
499 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
501 setSymbol(syms
->fShortWeekdays
, syms
->fShortWeekdaysCount
, index
, value
, valueLength
, errorCode
);
505 setAmPm(DateFormatSymbols
*syms
, int32_t index
,
506 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
508 setSymbol(syms
->fAmPms
, syms
->fAmPmsCount
, index
, value
, valueLength
, errorCode
);
512 setLocalPatternChars(DateFormatSymbols
*syms
,
513 const UChar
*value
, int32_t valueLength
, UErrorCode
&errorCode
)
515 setSymbol(&syms
->fLocalPatternChars
, 1, 0, value
, valueLength
, errorCode
);
521 U_CAPI
void U_EXPORT2
522 udat_setSymbols( UDateFormat
*format
,
523 UDateFormatSymbolType type
,
529 if(U_FAILURE(*status
)) return;
531 DateFormatSymbols
*syms
= (DateFormatSymbols
*)((SimpleDateFormat
*)format
)->getDateFormatSymbols();
535 DateFormatSymbolsSingleSetter::setEra(syms
, index
, value
, valueLength
, *status
);
539 DateFormatSymbolsSingleSetter::setMonth(syms
, index
, value
, valueLength
, *status
);
542 case UDAT_SHORT_MONTHS
:
543 DateFormatSymbolsSingleSetter::setShortMonth(syms
, index
, value
, valueLength
, *status
);
547 DateFormatSymbolsSingleSetter::setWeekday(syms
, index
, value
, valueLength
, *status
);
550 case UDAT_SHORT_WEEKDAYS
:
551 DateFormatSymbolsSingleSetter::setShortWeekday(syms
, index
, value
, valueLength
, *status
);
555 DateFormatSymbolsSingleSetter::setAmPm(syms
, index
, value
, valueLength
, *status
);
558 case UDAT_LOCALIZED_CHARS
:
559 DateFormatSymbolsSingleSetter::setLocalPatternChars(syms
, value
, valueLength
, *status
);
564 U_CAPI
const char* U_EXPORT2
565 udat_getLocaleByType(const UDateFormat
*fmt
,
566 ULocDataLocaleType type
,
570 if (U_SUCCESS(*status
)) {
571 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
575 return ((Format
*)fmt
)->getLocaleID(type
, *status
);
577 #endif /* #if !UCONFIG_NO_FORMATTING */