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