]>
Commit | Line | Data |
---|---|---|
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 | ||
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); | |
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 | ||
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); | |
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 |
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 | } | |
374ca955 | 152 | #endif |
b75a7d8f A |
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 | ||
374ca955 A |
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 | ||
b75a7d8f | 487 | #endif /* #if !UCONFIG_NO_FORMATTING */ |