]> git.saurik.com Git - apple/icu.git/blame - icuSources/i18n/ucal.cpp
ICU-6.2.4.tar.gz
[apple/icu.git] / icuSources / i18n / ucal.cpp
CommitLineData
b75a7d8f
A
1/*
2*******************************************************************************
374ca955 3* Copyright (C) 1996-2004, 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"
16#include "unicode/simpletz.h"
17#include "unicode/ustring.h"
18#include "unicode/strenum.h"
19#include "cmemory.h"
20#include "ustrenum.h"
21
22U_NAMESPACE_USE
23
24static 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);
374ca955
A
32 UnicodeString zoneStrID;
33 zoneStrID.setTo((UBool)(len < 0), zoneID, l); /* temporary read-only alias */
34 zone = TimeZone::createTimeZone(zoneStrID);
b75a7d8f
A
35 if (zone == NULL) {
36 *ec = U_MEMORY_ALLOCATION_ERROR;
37 }
38 }
39 return zone;
40}
41
42U_CAPI UEnumeration* U_EXPORT2
43ucal_openTimeZones(UErrorCode* ec) {
44 return uenum_openStringEnumeration(TimeZone::createEnumeration(), ec);
45}
46
47U_CAPI UEnumeration* U_EXPORT2
48ucal_openCountryTimeZones(const char* country, UErrorCode* ec) {
49 return uenum_openStringEnumeration(TimeZone::createEnumeration(country), ec);
50}
51
52U_CAPI int32_t U_EXPORT2
53ucal_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
69U_CAPI void U_EXPORT2
70ucal_setDefaultTimeZone(const UChar* zoneID, UErrorCode* ec) {
71 TimeZone* zone = _createTimeZone(zoneID, -1, ec);
72 if (zone != NULL) {
73 TimeZone::adoptDefault(zone);
74 }
75}
76
77U_CAPI int32_t U_EXPORT2
78ucal_getDSTSavings(const UChar* zoneID, UErrorCode* ec) {
79 int32_t result = 0;
80 TimeZone* zone = _createTimeZone(zoneID, -1, ec);
374ca955
A
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 }
b75a7d8f
A
101 }
102 delete zone;
103 return result;
104}
105
374ca955 106#ifdef U_USE_UCAL_OBSOLETE_2_8
b75a7d8f
A
107U_CAPI const UChar* U_EXPORT2
108ucal_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
135U_CAPI int32_t U_EXPORT2
136ucal_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}
374ca955 152#endif
b75a7d8f
A
153
154U_CAPI UDate U_EXPORT2
155ucal_getNow()
156{
157
158 return Calendar::getNow();
159}
160
161// ignore type until we add more subclasses
162U_CAPI UCalendar* U_EXPORT2
163ucal_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
182U_CAPI void U_EXPORT2
183ucal_close(UCalendar *cal)
184{
185
186 delete (Calendar*) cal;
187}
188
189U_CAPI void U_EXPORT2
190ucal_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
207U_CAPI int32_t U_EXPORT2
208ucal_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
247U_CAPI UBool U_EXPORT2
248ucal_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
256U_CAPI int32_t U_EXPORT2
257ucal_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
277U_CAPI void U_EXPORT2
278ucal_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
298U_CAPI const char* U_EXPORT2
299ucal_getAvailable(int32_t index)
300{
301
302 return uloc_getAvailable(index);
303}
304
305U_CAPI int32_t U_EXPORT2
306ucal_countAvailable()
307{
308
309 return uloc_countAvailable();
310}
311
312U_CAPI UDate U_EXPORT2
313ucal_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
322U_CAPI void U_EXPORT2
323ucal_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?
333U_CAPI void U_EXPORT2
334ucal_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?
347U_CAPI void U_EXPORT2
348ucal_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
362U_CAPI UBool U_EXPORT2
363ucal_equivalentTo( const UCalendar* cal1,
364 const UCalendar* cal2)
365{
366
367 return ((Calendar*)cal1)->isEquivalentTo(*((Calendar*)cal2));
368}
369
370U_CAPI void U_EXPORT2
371ucal_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
382U_CAPI void U_EXPORT2
383ucal_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
394U_CAPI int32_t U_EXPORT2
395ucal_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
405U_CAPI void U_EXPORT2
406ucal_set( UCalendar* cal,
407 UCalendarDateFields field,
408 int32_t value)
409{
410
411 ((Calendar*)cal)->set(field, value);
412}
413
414U_CAPI UBool U_EXPORT2
415ucal_isSet( const UCalendar* cal,
416 UCalendarDateFields field)
417{
418
419 return ((Calendar*)cal)->isSet(field);
420}
421
422U_CAPI void U_EXPORT2
423ucal_clearField( UCalendar* cal,
424 UCalendarDateFields field)
425{
426
427 ((Calendar*)cal)->clear(field);
428}
429
430U_CAPI void U_EXPORT2
431ucal_clear(UCalendar* calendar)
432{
433
434 ((Calendar*)calendar)->clear();
435}
436
437U_CAPI int32_t U_EXPORT2
438ucal_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
374ca955
A
475U_CAPI const char * U_EXPORT2
476ucal_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
b75a7d8f 487#endif /* #if !UCONFIG_NO_FORMATTING */