]> git.saurik.com Git - apple/icu.git/blame - icuSources/i18n/ucal.cpp
ICU-8.11.4.tar.gz
[apple/icu.git] / icuSources / i18n / ucal.cpp
CommitLineData
b75a7d8f
A
1/*
2*******************************************************************************
73c04bcf 3* Copyright (C) 1996-2006, International Business Machines
b75a7d8f
A
4* Corporation and others. All Rights Reserved.
5*******************************************************************************
6*/
7
8#include "unicode/utypes.h"
9
10#if !UCONFIG_NO_FORMATTING
11
12#include "unicode/ucal.h"
13#include "unicode/uloc.h"
14#include "unicode/calendar.h"
15#include "unicode/timezone.h"
73c04bcf 16#include "unicode/gregocal.h"
b75a7d8f
A
17#include "unicode/simpletz.h"
18#include "unicode/ustring.h"
19#include "unicode/strenum.h"
20#include "cmemory.h"
21#include "ustrenum.h"
22
23U_NAMESPACE_USE
24
25static TimeZone*
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);
374ca955
A
33 UnicodeString zoneStrID;
34 zoneStrID.setTo((UBool)(len < 0), zoneID, l); /* temporary read-only alias */
35 zone = TimeZone::createTimeZone(zoneStrID);
b75a7d8f
A
36 if (zone == NULL) {
37 *ec = U_MEMORY_ALLOCATION_ERROR;
38 }
39 }
40 return zone;
41}
42
43U_CAPI UEnumeration* U_EXPORT2
44ucal_openTimeZones(UErrorCode* ec) {
45 return uenum_openStringEnumeration(TimeZone::createEnumeration(), ec);
46}
47
48U_CAPI UEnumeration* U_EXPORT2
49ucal_openCountryTimeZones(const char* country, UErrorCode* ec) {
50 return uenum_openStringEnumeration(TimeZone::createEnumeration(country), ec);
51}
52
53U_CAPI int32_t U_EXPORT2
54ucal_getDefaultTimeZone(UChar* result, int32_t resultCapacity, UErrorCode* ec) {
55 int32_t len = 0;
56 if (ec!=NULL && U_SUCCESS(*ec)) {
57 TimeZone* zone = TimeZone::createDefault();
58 if (zone == NULL) {
59 *ec = U_MEMORY_ALLOCATION_ERROR;
60 } else {
61 UnicodeString id;
62 zone->getID(id);
63 delete zone;
64 len = id.extract(result, resultCapacity, *ec);
65 }
66 }
67 return len;
68}
69
70U_CAPI void U_EXPORT2
71ucal_setDefaultTimeZone(const UChar* zoneID, UErrorCode* ec) {
72 TimeZone* zone = _createTimeZone(zoneID, -1, ec);
73 if (zone != NULL) {
74 TimeZone::adoptDefault(zone);
75 }
76}
77
78U_CAPI int32_t U_EXPORT2
79ucal_getDSTSavings(const UChar* zoneID, UErrorCode* ec) {
80 int32_t result = 0;
81 TimeZone* zone = _createTimeZone(zoneID, -1, ec);
374ca955
A
82 if (U_SUCCESS(*ec)) {
83 if (zone->getDynamicClassID() == SimpleTimeZone::getStaticClassID()) {
84 result = ((SimpleTimeZone*) zone)->getDSTSavings();
85 } else {
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) {
92 int32_t raw, dst;
93 zone->getOffset(d, FALSE, raw, dst, *ec);
94 if (U_FAILURE(*ec)) {
95 break;
96 } else if (dst != 0) {
97 result = dst;
98 break;
99 }
100 }
101 }
b75a7d8f
A
102 }
103 delete zone;
104 return result;
105}
106
374ca955 107#ifdef U_USE_UCAL_OBSOLETE_2_8
b75a7d8f
A
108U_CAPI const UChar* U_EXPORT2
109ucal_getAvailableTZIDs( int32_t rawOffset,
110 int32_t index,
111 UErrorCode* status)
112{
113
114 if(U_FAILURE(*status)) return 0;
115
116 int32_t count = 0;
117 const UChar *retVal = 0;
118
119 const UnicodeString** tzs = TimeZone::createAvailableIDs(rawOffset,
120 count);
121
122 if(tzs == 0) {
123 *status = U_MEMORY_ALLOCATION_ERROR;
124 return 0;
125 }
126
127 if(index < count)
128 retVal = tzs[index]->getBuffer();
129 else
130 *status = U_INDEX_OUTOFBOUNDS_ERROR;
131
132 uprv_free(tzs);
133 return retVal;
134}
135
136U_CAPI int32_t U_EXPORT2
137ucal_countAvailableTZIDs(int32_t rawOffset)
138{
139
140 int32_t count = 0;
141
142 const UnicodeString** tzs = TimeZone::createAvailableIDs(rawOffset,
143 count);
144
145 if(tzs == 0) {
146 // TBD: U_MEMORY_ALLOCATION_ERROR
147 return 0;
148 }
149
150 uprv_free(tzs);
151 return count;
152}
374ca955 153#endif
b75a7d8f
A
154
155U_CAPI UDate U_EXPORT2
156ucal_getNow()
157{
158
159 return Calendar::getNow();
160}
161
162// ignore type until we add more subclasses
163U_CAPI UCalendar* U_EXPORT2
164ucal_open( const UChar* zoneID,
165 int32_t len,
166 const char* locale,
167 UCalendarType /*type*/,
168 UErrorCode* status)
169{
170
171 if(U_FAILURE(*status)) return 0;
172
173 TimeZone* zone = (zoneID==NULL) ? TimeZone::createDefault()
174 : _createTimeZone(zoneID, len, status);
175
176 if (U_FAILURE(*status)) {
177 return NULL;
178 }
179
180 return (UCalendar*)Calendar::createInstance(zone, Locale(locale), *status);
181}
182
183U_CAPI void U_EXPORT2
184ucal_close(UCalendar *cal)
185{
186
187 delete (Calendar*) cal;
188}
189
190U_CAPI void U_EXPORT2
191ucal_setTimeZone( UCalendar* cal,
192 const UChar* zoneID,
193 int32_t len,
194 UErrorCode *status)
195{
196
197 if(U_FAILURE(*status))
198 return;
199
200 TimeZone* zone = (zoneID==NULL) ? TimeZone::createDefault()
201 : _createTimeZone(zoneID, len, status);
202
203 if (zone != NULL) {
204 ((Calendar*)cal)->adoptTimeZone(zone);
205 }
206}
207
208U_CAPI int32_t U_EXPORT2
209ucal_getTimeZoneDisplayName(const UCalendar* cal,
210 UCalendarDisplayNameType type,
211 const char *locale,
212 UChar* result,
213 int32_t resultLength,
214 UErrorCode* status)
215{
216
217 if(U_FAILURE(*status)) return -1;
218
219 const TimeZone& tz = ((Calendar*)cal)->getTimeZone();
220 UnicodeString id;
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);
225 }
226
227 switch(type) {
228 case UCAL_STANDARD:
229 tz.getDisplayName(FALSE, TimeZone::LONG, Locale(locale), id);
230 break;
231
232 case UCAL_SHORT_STANDARD:
233 tz.getDisplayName(FALSE, TimeZone::SHORT, Locale(locale), id);
234 break;
235
236 case UCAL_DST:
237 tz.getDisplayName(TRUE, TimeZone::LONG, Locale(locale), id);
238 break;
239
240 case UCAL_SHORT_DST:
241 tz.getDisplayName(TRUE, TimeZone::SHORT, Locale(locale), id);
242 break;
243 }
244
245 return id.extract(result, resultLength, *status);
246}
247
248U_CAPI UBool U_EXPORT2
249ucal_inDaylightTime( const UCalendar* cal,
250 UErrorCode* status )
251{
252
253 if(U_FAILURE(*status)) return (UBool) -1;
254 return ((Calendar*)cal)->inDaylightTime(*status);
255}
256
73c04bcf
A
257U_DRAFT void U_EXPORT2
258ucal_setGregorianChange(UCalendar *cal, UDate date, UErrorCode *pErrorCode) {
259 if(U_FAILURE(*pErrorCode)) {
260 return;
261 }
262 Calendar *cpp_cal = (Calendar *)cal;
263 if(cpp_cal->getDynamicClassID() != GregorianCalendar::getStaticClassID()) {
264 *pErrorCode = U_UNSUPPORTED_ERROR;
265 return;
266 }
267 ((GregorianCalendar *)cpp_cal)->setGregorianChange(date, *pErrorCode);
268}
269
270U_DRAFT UDate U_EXPORT2
271ucal_getGregorianChange(const UCalendar *cal, UErrorCode *pErrorCode) {
272 if(U_FAILURE(*pErrorCode)) {
273 return (UDate)0;
274 }
275 Calendar *cpp_cal = (Calendar *)cal;
276 if(cpp_cal->getDynamicClassID() != GregorianCalendar::getStaticClassID()) {
277 *pErrorCode = U_UNSUPPORTED_ERROR;
278 return (UDate)0;
279 }
280 return ((GregorianCalendar *)cpp_cal)->getGregorianChange();
281}
282
b75a7d8f
A
283U_CAPI int32_t U_EXPORT2
284ucal_getAttribute( const UCalendar* cal,
285 UCalendarAttribute attr)
286{
287
288 switch(attr) {
289 case UCAL_LENIENT:
290 return ((Calendar*)cal)->isLenient();
291
292 case UCAL_FIRST_DAY_OF_WEEK:
293 return ((Calendar*)cal)->getFirstDayOfWeek();
294
295 case UCAL_MINIMAL_DAYS_IN_FIRST_WEEK:
296 return ((Calendar*)cal)->getMinimalDaysInFirstWeek();
297
298 default:
299 break;
300 }
301 return -1;
302}
303
304U_CAPI void U_EXPORT2
305ucal_setAttribute( UCalendar* cal,
306 UCalendarAttribute attr,
307 int32_t newValue)
308{
309
310 switch(attr) {
311 case UCAL_LENIENT:
312 ((Calendar*)cal)->setLenient((UBool)newValue);
313 break;
314
315 case UCAL_FIRST_DAY_OF_WEEK:
316 ((Calendar*)cal)->setFirstDayOfWeek((UCalendarDaysOfWeek)newValue);
317 break;
318
319 case UCAL_MINIMAL_DAYS_IN_FIRST_WEEK:
320 ((Calendar*)cal)->setMinimalDaysInFirstWeek((uint8_t)newValue);
321 break;
322 }
323}
324
325U_CAPI const char* U_EXPORT2
326ucal_getAvailable(int32_t index)
327{
328
329 return uloc_getAvailable(index);
330}
331
332U_CAPI int32_t U_EXPORT2
333ucal_countAvailable()
334{
335
336 return uloc_countAvailable();
337}
338
339U_CAPI UDate U_EXPORT2
340ucal_getMillis( const UCalendar* cal,
341 UErrorCode* status)
342{
343
344 if(U_FAILURE(*status)) return (UDate) 0;
345
346 return ((Calendar*)cal)->getTime(*status);
347}
348
349U_CAPI void U_EXPORT2
350ucal_setMillis( UCalendar* cal,
351 UDate dateTime,
352 UErrorCode* status )
353{
354 if(U_FAILURE(*status)) return;
355
356 ((Calendar*)cal)->setTime(dateTime, *status);
357}
358
359// TBD: why does this take an UErrorCode?
360U_CAPI void U_EXPORT2
361ucal_setDate( UCalendar* cal,
362 int32_t year,
363 int32_t month,
364 int32_t date,
365 UErrorCode *status)
366{
367
368 if(U_FAILURE(*status)) return;
369
370 ((Calendar*)cal)->set(year, month, date);
371}
372
373// TBD: why does this take an UErrorCode?
374U_CAPI void U_EXPORT2
375ucal_setDateTime( UCalendar* cal,
376 int32_t year,
377 int32_t month,
378 int32_t date,
379 int32_t hour,
380 int32_t minute,
381 int32_t second,
382 UErrorCode *status)
383{
384 if(U_FAILURE(*status)) return;
385
386 ((Calendar*)cal)->set(year, month, date, hour, minute, second);
387}
388
389U_CAPI UBool U_EXPORT2
390ucal_equivalentTo( const UCalendar* cal1,
391 const UCalendar* cal2)
392{
393
394 return ((Calendar*)cal1)->isEquivalentTo(*((Calendar*)cal2));
395}
396
397U_CAPI void U_EXPORT2
398ucal_add( UCalendar* cal,
399 UCalendarDateFields field,
400 int32_t amount,
401 UErrorCode* status)
402{
403
404 if(U_FAILURE(*status)) return;
405
406 ((Calendar*)cal)->add(field, amount, *status);
407}
408
409U_CAPI void U_EXPORT2
410ucal_roll( UCalendar* cal,
411 UCalendarDateFields field,
412 int32_t amount,
413 UErrorCode* status)
414{
415
416 if(U_FAILURE(*status)) return;
417
418 ((Calendar*)cal)->roll(field, amount, *status);
419}
420
421U_CAPI int32_t U_EXPORT2
422ucal_get( const UCalendar* cal,
423 UCalendarDateFields field,
424 UErrorCode* status )
425{
426
427 if(U_FAILURE(*status)) return -1;
428
429 return ((Calendar*)cal)->get(field, *status);
430}
431
432U_CAPI void U_EXPORT2
433ucal_set( UCalendar* cal,
434 UCalendarDateFields field,
435 int32_t value)
436{
437
438 ((Calendar*)cal)->set(field, value);
439}
440
441U_CAPI UBool U_EXPORT2
442ucal_isSet( const UCalendar* cal,
443 UCalendarDateFields field)
444{
445
446 return ((Calendar*)cal)->isSet(field);
447}
448
449U_CAPI void U_EXPORT2
450ucal_clearField( UCalendar* cal,
451 UCalendarDateFields field)
452{
453
454 ((Calendar*)cal)->clear(field);
455}
456
457U_CAPI void U_EXPORT2
458ucal_clear(UCalendar* calendar)
459{
460
461 ((Calendar*)calendar)->clear();
462}
463
464U_CAPI int32_t U_EXPORT2
465ucal_getLimit( const UCalendar* cal,
466 UCalendarDateFields field,
467 UCalendarLimitType type,
468 UErrorCode *status)
469{
470
471 if(status==0 || U_FAILURE(*status)) {
472 return -1;
473 }
474
475 switch(type) {
476 case UCAL_MINIMUM:
477 return ((Calendar*)cal)->getMinimum(field);
478
479 case UCAL_MAXIMUM:
480 return ((Calendar*)cal)->getMaximum(field);
481
482 case UCAL_GREATEST_MINIMUM:
483 return ((Calendar*)cal)->getGreatestMinimum(field);
484
485 case UCAL_LEAST_MAXIMUM:
486 return ((Calendar*)cal)->getLeastMaximum(field);
487
488 case UCAL_ACTUAL_MINIMUM:
489 return ((Calendar*)cal)->getActualMinimum(field,
490 *status);
491
492 case UCAL_ACTUAL_MAXIMUM:
493 return ((Calendar*)cal)->getActualMaximum(field,
494 *status);
495
496 default:
497 break;
498 }
499 return -1;
500}
501
374ca955
A
502U_CAPI const char * U_EXPORT2
503ucal_getLocaleByType(const UCalendar *cal, ULocDataLocaleType type, UErrorCode* status)
504{
505 if (cal == NULL) {
506 if (U_SUCCESS(*status)) {
507 *status = U_ILLEGAL_ARGUMENT_ERROR;
508 }
509 return NULL;
510 }
511 return ((Calendar*)cal)->getLocaleID(type, *status);
512}
513
b75a7d8f 514#endif /* #if !UCONFIG_NO_FORMATTING */