2 *******************************************************************************
3 * Copyright (C) 1996-2006, International Business Machines
4 * Corporation and others. All Rights Reserved.
5 *******************************************************************************
8 #include "unicode/utypes.h"
10 #if !UCONFIG_NO_FORMATTING
12 #include "unicode/ucal.h"
13 #include "unicode/uloc.h"
14 #include "unicode/calendar.h"
15 #include "unicode/timezone.h"
16 #include "unicode/gregocal.h"
17 #include "unicode/simpletz.h"
18 #include "unicode/ustring.h"
19 #include "unicode/strenum.h"
26 _createTimeZone(const UChar
* zoneID
, int32_t len
, UErrorCode
* ec
) {
27 TimeZone
* zone
= NULL
;
28 if (ec
!=NULL
&& U_SUCCESS(*ec
)) {
29 // Note that if zoneID is invalid, we get back GMT. This odd
30 // behavior is by design and goes back to the JDK. The only
31 // failure we will see is a memory allocation failure.
32 int32_t l
= (len
<0 ? u_strlen(zoneID
) : len
);
33 UnicodeString zoneStrID
;
34 zoneStrID
.setTo((UBool
)(len
< 0), zoneID
, l
); /* temporary read-only alias */
35 zone
= TimeZone::createTimeZone(zoneStrID
);
37 *ec
= U_MEMORY_ALLOCATION_ERROR
;
43 U_CAPI UEnumeration
* U_EXPORT2
44 ucal_openTimeZones(UErrorCode
* ec
) {
45 return uenum_openStringEnumeration(TimeZone::createEnumeration(), ec
);
48 U_CAPI UEnumeration
* U_EXPORT2
49 ucal_openCountryTimeZones(const char* country
, UErrorCode
* ec
) {
50 return uenum_openStringEnumeration(TimeZone::createEnumeration(country
), ec
);
53 U_CAPI
int32_t U_EXPORT2
54 ucal_getDefaultTimeZone(UChar
* result
, int32_t resultCapacity
, UErrorCode
* ec
) {
56 if (ec
!=NULL
&& U_SUCCESS(*ec
)) {
57 TimeZone
* zone
= TimeZone::createDefault();
59 *ec
= U_MEMORY_ALLOCATION_ERROR
;
64 len
= id
.extract(result
, resultCapacity
, *ec
);
71 ucal_setDefaultTimeZone(const UChar
* zoneID
, UErrorCode
* ec
) {
72 TimeZone
* zone
= _createTimeZone(zoneID
, -1, ec
);
74 TimeZone::adoptDefault(zone
);
78 U_CAPI
int32_t U_EXPORT2
79 ucal_getDSTSavings(const UChar
* zoneID
, UErrorCode
* ec
) {
81 TimeZone
* zone
= _createTimeZone(zoneID
, -1, ec
);
83 if (zone
->getDynamicClassID() == SimpleTimeZone::getStaticClassID()) {
84 result
= ((SimpleTimeZone
*) zone
)->getDSTSavings();
86 // Since there is no getDSTSavings on TimeZone, we use a
87 // heuristic: Starting with the current time, march
88 // forwards for one year, looking for DST savings.
89 // Stepping by weeks is sufficient.
90 UDate d
= Calendar::getNow();
91 for (int32_t i
=0; i
<53; ++i
, d
+=U_MILLIS_PER_DAY
*7.0) {
93 zone
->getOffset(d
, FALSE
, raw
, dst
, *ec
);
96 } else if (dst
!= 0) {
107 #ifdef U_USE_UCAL_OBSOLETE_2_8
108 U_CAPI
const UChar
* U_EXPORT2
109 ucal_getAvailableTZIDs( int32_t rawOffset
,
114 if(U_FAILURE(*status
)) return 0;
117 const UChar
*retVal
= 0;
119 const UnicodeString
** tzs
= TimeZone::createAvailableIDs(rawOffset
,
123 *status
= U_MEMORY_ALLOCATION_ERROR
;
128 retVal
= tzs
[index
]->getBuffer();
130 *status
= U_INDEX_OUTOFBOUNDS_ERROR
;
136 U_CAPI
int32_t U_EXPORT2
137 ucal_countAvailableTZIDs(int32_t rawOffset
)
142 const UnicodeString
** tzs
= TimeZone::createAvailableIDs(rawOffset
,
146 // TBD: U_MEMORY_ALLOCATION_ERROR
155 U_CAPI UDate U_EXPORT2
159 return Calendar::getNow();
162 // ignore type until we add more subclasses
163 U_CAPI UCalendar
* U_EXPORT2
164 ucal_open( const UChar
* zoneID
,
167 UCalendarType
/*type*/,
171 if(U_FAILURE(*status
)) return 0;
173 TimeZone
* zone
= (zoneID
==NULL
) ? TimeZone::createDefault()
174 : _createTimeZone(zoneID
, len
, status
);
176 if (U_FAILURE(*status
)) {
180 return (UCalendar
*)Calendar::createInstance(zone
, Locale(locale
), *status
);
183 U_CAPI
void U_EXPORT2
184 ucal_close(UCalendar
*cal
)
187 delete (Calendar
*) cal
;
190 U_CAPI
void U_EXPORT2
191 ucal_setTimeZone( UCalendar
* cal
,
197 if(U_FAILURE(*status
))
200 TimeZone
* zone
= (zoneID
==NULL
) ? TimeZone::createDefault()
201 : _createTimeZone(zoneID
, len
, status
);
204 ((Calendar
*)cal
)->adoptTimeZone(zone
);
208 U_CAPI
int32_t U_EXPORT2
209 ucal_getTimeZoneDisplayName(const UCalendar
* cal
,
210 UCalendarDisplayNameType type
,
213 int32_t resultLength
,
217 if(U_FAILURE(*status
)) return -1;
219 const TimeZone
& tz
= ((Calendar
*)cal
)->getTimeZone();
221 if(!(result
==NULL
&& resultLength
==0)) {
222 // NULL destination for pure preflighting: empty dummy string
223 // otherwise, alias the destination buffer
224 id
.setTo(result
, 0, resultLength
);
229 tz
.getDisplayName(FALSE
, TimeZone::LONG
, Locale(locale
), id
);
232 case UCAL_SHORT_STANDARD
:
233 tz
.getDisplayName(FALSE
, TimeZone::SHORT
, Locale(locale
), id
);
237 tz
.getDisplayName(TRUE
, TimeZone::LONG
, Locale(locale
), id
);
241 tz
.getDisplayName(TRUE
, TimeZone::SHORT
, Locale(locale
), id
);
245 return id
.extract(result
, resultLength
, *status
);
248 U_CAPI UBool U_EXPORT2
249 ucal_inDaylightTime( const UCalendar
* cal
,
253 if(U_FAILURE(*status
)) return (UBool
) -1;
254 return ((Calendar
*)cal
)->inDaylightTime(*status
);
257 U_DRAFT
void U_EXPORT2
258 ucal_setGregorianChange(UCalendar
*cal
, UDate date
, UErrorCode
*pErrorCode
) {
259 if(U_FAILURE(*pErrorCode
)) {
262 Calendar
*cpp_cal
= (Calendar
*)cal
;
263 if(cpp_cal
->getDynamicClassID() != GregorianCalendar::getStaticClassID()) {
264 *pErrorCode
= U_UNSUPPORTED_ERROR
;
267 ((GregorianCalendar
*)cpp_cal
)->setGregorianChange(date
, *pErrorCode
);
270 U_DRAFT UDate U_EXPORT2
271 ucal_getGregorianChange(const UCalendar
*cal
, UErrorCode
*pErrorCode
) {
272 if(U_FAILURE(*pErrorCode
)) {
275 Calendar
*cpp_cal
= (Calendar
*)cal
;
276 if(cpp_cal
->getDynamicClassID() != GregorianCalendar::getStaticClassID()) {
277 *pErrorCode
= U_UNSUPPORTED_ERROR
;
280 return ((GregorianCalendar
*)cpp_cal
)->getGregorianChange();
283 U_CAPI
int32_t U_EXPORT2
284 ucal_getAttribute( const UCalendar
* cal
,
285 UCalendarAttribute attr
)
290 return ((Calendar
*)cal
)->isLenient();
292 case UCAL_FIRST_DAY_OF_WEEK
:
293 return ((Calendar
*)cal
)->getFirstDayOfWeek();
295 case UCAL_MINIMAL_DAYS_IN_FIRST_WEEK
:
296 return ((Calendar
*)cal
)->getMinimalDaysInFirstWeek();
304 U_CAPI
void U_EXPORT2
305 ucal_setAttribute( UCalendar
* cal
,
306 UCalendarAttribute attr
,
312 ((Calendar
*)cal
)->setLenient((UBool
)newValue
);
315 case UCAL_FIRST_DAY_OF_WEEK
:
316 ((Calendar
*)cal
)->setFirstDayOfWeek((UCalendarDaysOfWeek
)newValue
);
319 case UCAL_MINIMAL_DAYS_IN_FIRST_WEEK
:
320 ((Calendar
*)cal
)->setMinimalDaysInFirstWeek((uint8_t)newValue
);
325 U_CAPI
const char* U_EXPORT2
326 ucal_getAvailable(int32_t index
)
329 return uloc_getAvailable(index
);
332 U_CAPI
int32_t U_EXPORT2
333 ucal_countAvailable()
336 return uloc_countAvailable();
339 U_CAPI UDate U_EXPORT2
340 ucal_getMillis( const UCalendar
* cal
,
344 if(U_FAILURE(*status
)) return (UDate
) 0;
346 return ((Calendar
*)cal
)->getTime(*status
);
349 U_CAPI
void U_EXPORT2
350 ucal_setMillis( UCalendar
* cal
,
354 if(U_FAILURE(*status
)) return;
356 ((Calendar
*)cal
)->setTime(dateTime
, *status
);
359 // TBD: why does this take an UErrorCode?
360 U_CAPI
void U_EXPORT2
361 ucal_setDate( UCalendar
* cal
,
368 if(U_FAILURE(*status
)) return;
370 ((Calendar
*)cal
)->set(year
, month
, date
);
373 // TBD: why does this take an UErrorCode?
374 U_CAPI
void U_EXPORT2
375 ucal_setDateTime( UCalendar
* cal
,
384 if(U_FAILURE(*status
)) return;
386 ((Calendar
*)cal
)->set(year
, month
, date
, hour
, minute
, second
);
389 U_CAPI UBool U_EXPORT2
390 ucal_equivalentTo( const UCalendar
* cal1
,
391 const UCalendar
* cal2
)
394 return ((Calendar
*)cal1
)->isEquivalentTo(*((Calendar
*)cal2
));
397 U_CAPI
void U_EXPORT2
398 ucal_add( UCalendar
* cal
,
399 UCalendarDateFields field
,
404 if(U_FAILURE(*status
)) return;
406 ((Calendar
*)cal
)->add(field
, amount
, *status
);
409 U_CAPI
void U_EXPORT2
410 ucal_roll( UCalendar
* cal
,
411 UCalendarDateFields field
,
416 if(U_FAILURE(*status
)) return;
418 ((Calendar
*)cal
)->roll(field
, amount
, *status
);
421 U_CAPI
int32_t U_EXPORT2
422 ucal_get( const UCalendar
* cal
,
423 UCalendarDateFields field
,
427 if(U_FAILURE(*status
)) return -1;
429 return ((Calendar
*)cal
)->get(field
, *status
);
432 U_CAPI
void U_EXPORT2
433 ucal_set( UCalendar
* cal
,
434 UCalendarDateFields field
,
438 ((Calendar
*)cal
)->set(field
, value
);
441 U_CAPI UBool U_EXPORT2
442 ucal_isSet( const UCalendar
* cal
,
443 UCalendarDateFields field
)
446 return ((Calendar
*)cal
)->isSet(field
);
449 U_CAPI
void U_EXPORT2
450 ucal_clearField( UCalendar
* cal
,
451 UCalendarDateFields field
)
454 ((Calendar
*)cal
)->clear(field
);
457 U_CAPI
void U_EXPORT2
458 ucal_clear(UCalendar
* calendar
)
461 ((Calendar
*)calendar
)->clear();
464 U_CAPI
int32_t U_EXPORT2
465 ucal_getLimit( const UCalendar
* cal
,
466 UCalendarDateFields field
,
467 UCalendarLimitType type
,
471 if(status
==0 || U_FAILURE(*status
)) {
477 return ((Calendar
*)cal
)->getMinimum(field
);
480 return ((Calendar
*)cal
)->getMaximum(field
);
482 case UCAL_GREATEST_MINIMUM
:
483 return ((Calendar
*)cal
)->getGreatestMinimum(field
);
485 case UCAL_LEAST_MAXIMUM
:
486 return ((Calendar
*)cal
)->getLeastMaximum(field
);
488 case UCAL_ACTUAL_MINIMUM
:
489 return ((Calendar
*)cal
)->getActualMinimum(field
,
492 case UCAL_ACTUAL_MAXIMUM
:
493 return ((Calendar
*)cal
)->getActualMaximum(field
,
502 U_CAPI
const char * U_EXPORT2
503 ucal_getLocaleByType(const UCalendar
*cal
, ULocDataLocaleType type
, UErrorCode
* status
)
506 if (U_SUCCESS(*status
)) {
507 *status
= U_ILLEGAL_ARGUMENT_ERROR
;
511 return ((Calendar
*)cal
)->getLocaleID(type
, *status
);
514 #endif /* #if !UCONFIG_NO_FORMATTING */