1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/intl/icu/source/i18n/ucal.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,814 @@ 1.4 +/* 1.5 +******************************************************************************* 1.6 +* Copyright (C) 1996-2013, International Business Machines 1.7 +* Corporation and others. All Rights Reserved. 1.8 +******************************************************************************* 1.9 +*/ 1.10 + 1.11 +#include "utypeinfo.h" // for 'typeid' to work 1.12 + 1.13 +#include "unicode/utypes.h" 1.14 + 1.15 +#if !UCONFIG_NO_FORMATTING 1.16 + 1.17 +#include "unicode/ucal.h" 1.18 +#include "unicode/uloc.h" 1.19 +#include "unicode/calendar.h" 1.20 +#include "unicode/timezone.h" 1.21 +#include "unicode/gregocal.h" 1.22 +#include "unicode/simpletz.h" 1.23 +#include "unicode/ustring.h" 1.24 +#include "unicode/strenum.h" 1.25 +#include "unicode/localpointer.h" 1.26 +#include "cmemory.h" 1.27 +#include "cstring.h" 1.28 +#include "ustrenum.h" 1.29 +#include "uenumimp.h" 1.30 +#include "ulist.h" 1.31 + 1.32 +U_NAMESPACE_USE 1.33 + 1.34 +static TimeZone* 1.35 +_createTimeZone(const UChar* zoneID, int32_t len, UErrorCode* ec) { 1.36 + TimeZone* zone = NULL; 1.37 + if (ec!=NULL && U_SUCCESS(*ec)) { 1.38 + // Note that if zoneID is invalid, we get back GMT. This odd 1.39 + // behavior is by design and goes back to the JDK. The only 1.40 + // failure we will see is a memory allocation failure. 1.41 + int32_t l = (len<0 ? u_strlen(zoneID) : len); 1.42 + UnicodeString zoneStrID; 1.43 + zoneStrID.setTo((UBool)(len < 0), zoneID, l); /* temporary read-only alias */ 1.44 + zone = TimeZone::createTimeZone(zoneStrID); 1.45 + if (zone == NULL) { 1.46 + *ec = U_MEMORY_ALLOCATION_ERROR; 1.47 + } 1.48 + } 1.49 + return zone; 1.50 +} 1.51 + 1.52 +U_CAPI UEnumeration* U_EXPORT2 1.53 +ucal_openTimeZoneIDEnumeration(USystemTimeZoneType zoneType, const char* region, 1.54 + const int32_t* rawOffset, UErrorCode* ec) { 1.55 + return uenum_openFromStringEnumeration(TimeZone::createTimeZoneIDEnumeration( 1.56 + zoneType, region, rawOffset, *ec), ec); 1.57 +} 1.58 + 1.59 +U_CAPI UEnumeration* U_EXPORT2 1.60 +ucal_openTimeZones(UErrorCode* ec) { 1.61 + return uenum_openFromStringEnumeration(TimeZone::createEnumeration(), ec); 1.62 +} 1.63 + 1.64 +U_CAPI UEnumeration* U_EXPORT2 1.65 +ucal_openCountryTimeZones(const char* country, UErrorCode* ec) { 1.66 + return uenum_openFromStringEnumeration(TimeZone::createEnumeration(country), ec); 1.67 +} 1.68 + 1.69 +U_CAPI int32_t U_EXPORT2 1.70 +ucal_getDefaultTimeZone(UChar* result, int32_t resultCapacity, UErrorCode* ec) { 1.71 + int32_t len = 0; 1.72 + if (ec!=NULL && U_SUCCESS(*ec)) { 1.73 + TimeZone* zone = TimeZone::createDefault(); 1.74 + if (zone == NULL) { 1.75 + *ec = U_MEMORY_ALLOCATION_ERROR; 1.76 + } else { 1.77 + UnicodeString id; 1.78 + zone->getID(id); 1.79 + delete zone; 1.80 + len = id.extract(result, resultCapacity, *ec); 1.81 + } 1.82 + } 1.83 + return len; 1.84 +} 1.85 + 1.86 +U_CAPI void U_EXPORT2 1.87 +ucal_setDefaultTimeZone(const UChar* zoneID, UErrorCode* ec) { 1.88 + TimeZone* zone = _createTimeZone(zoneID, -1, ec); 1.89 + if (zone != NULL) { 1.90 + TimeZone::adoptDefault(zone); 1.91 + } 1.92 +} 1.93 + 1.94 +U_CAPI int32_t U_EXPORT2 1.95 +ucal_getDSTSavings(const UChar* zoneID, UErrorCode* ec) { 1.96 + int32_t result = 0; 1.97 + TimeZone* zone = _createTimeZone(zoneID, -1, ec); 1.98 + if (U_SUCCESS(*ec)) { 1.99 + SimpleTimeZone* stz = dynamic_cast<SimpleTimeZone*>(zone); 1.100 + if (stz != NULL) { 1.101 + result = stz->getDSTSavings(); 1.102 + } else { 1.103 + // Since there is no getDSTSavings on TimeZone, we use a 1.104 + // heuristic: Starting with the current time, march 1.105 + // forwards for one year, looking for DST savings. 1.106 + // Stepping by weeks is sufficient. 1.107 + UDate d = Calendar::getNow(); 1.108 + for (int32_t i=0; i<53; ++i, d+=U_MILLIS_PER_DAY*7.0) { 1.109 + int32_t raw, dst; 1.110 + zone->getOffset(d, FALSE, raw, dst, *ec); 1.111 + if (U_FAILURE(*ec)) { 1.112 + break; 1.113 + } else if (dst != 0) { 1.114 + result = dst; 1.115 + break; 1.116 + } 1.117 + } 1.118 + } 1.119 + } 1.120 + delete zone; 1.121 + return result; 1.122 +} 1.123 + 1.124 +U_CAPI UDate U_EXPORT2 1.125 +ucal_getNow() 1.126 +{ 1.127 + 1.128 + return Calendar::getNow(); 1.129 +} 1.130 + 1.131 +#define ULOC_LOCALE_IDENTIFIER_CAPACITY (ULOC_FULLNAME_CAPACITY + 1 + ULOC_KEYWORD_AND_VALUES_CAPACITY) 1.132 + 1.133 +U_CAPI UCalendar* U_EXPORT2 1.134 +ucal_open( const UChar* zoneID, 1.135 + int32_t len, 1.136 + const char* locale, 1.137 + UCalendarType caltype, 1.138 + UErrorCode* status) 1.139 +{ 1.140 + 1.141 + if(U_FAILURE(*status)) return 0; 1.142 + 1.143 + TimeZone* zone = (zoneID==NULL) ? TimeZone::createDefault() 1.144 + : _createTimeZone(zoneID, len, status); 1.145 + 1.146 + if (U_FAILURE(*status)) { 1.147 + return NULL; 1.148 + } 1.149 + 1.150 + if ( caltype == UCAL_GREGORIAN ) { 1.151 + char localeBuf[ULOC_LOCALE_IDENTIFIER_CAPACITY]; 1.152 + if ( locale == NULL ) { 1.153 + locale = uloc_getDefault(); 1.154 + } 1.155 + uprv_strncpy(localeBuf, locale, ULOC_LOCALE_IDENTIFIER_CAPACITY); 1.156 + uloc_setKeywordValue("calendar", "gregorian", localeBuf, ULOC_LOCALE_IDENTIFIER_CAPACITY, status); 1.157 + if (U_FAILURE(*status)) { 1.158 + return NULL; 1.159 + } 1.160 + return (UCalendar*)Calendar::createInstance(zone, Locale(localeBuf), *status); 1.161 + } 1.162 + return (UCalendar*)Calendar::createInstance(zone, Locale(locale), *status); 1.163 +} 1.164 + 1.165 +U_CAPI void U_EXPORT2 1.166 +ucal_close(UCalendar *cal) 1.167 +{ 1.168 + 1.169 + delete (Calendar*) cal; 1.170 +} 1.171 + 1.172 +U_CAPI UCalendar* U_EXPORT2 1.173 +ucal_clone(const UCalendar* cal, 1.174 + UErrorCode* status) 1.175 +{ 1.176 + if(U_FAILURE(*status)) return 0; 1.177 + 1.178 + Calendar* res = ((Calendar*)cal)->clone(); 1.179 + 1.180 + if(res == 0) { 1.181 + *status = U_MEMORY_ALLOCATION_ERROR; 1.182 + return 0; 1.183 + } 1.184 + 1.185 + return (UCalendar*) res; 1.186 +} 1.187 + 1.188 +U_CAPI void U_EXPORT2 1.189 +ucal_setTimeZone( UCalendar* cal, 1.190 + const UChar* zoneID, 1.191 + int32_t len, 1.192 + UErrorCode *status) 1.193 +{ 1.194 + 1.195 + if(U_FAILURE(*status)) 1.196 + return; 1.197 + 1.198 + TimeZone* zone = (zoneID==NULL) ? TimeZone::createDefault() 1.199 + : _createTimeZone(zoneID, len, status); 1.200 + 1.201 + if (zone != NULL) { 1.202 + ((Calendar*)cal)->adoptTimeZone(zone); 1.203 + } 1.204 +} 1.205 + 1.206 +U_CAPI int32_t U_EXPORT2 1.207 +ucal_getTimeZoneID(const UCalendar *cal, 1.208 + UChar *result, 1.209 + int32_t resultLength, 1.210 + UErrorCode *status) 1.211 +{ 1.212 + if (U_FAILURE(*status)) { 1.213 + return 0; 1.214 + } 1.215 + const TimeZone& tz = ((Calendar*)cal)->getTimeZone(); 1.216 + UnicodeString id; 1.217 + tz.getID(id); 1.218 + return id.extract(result, resultLength, *status); 1.219 +} 1.220 + 1.221 +U_CAPI int32_t U_EXPORT2 1.222 +ucal_getTimeZoneDisplayName(const UCalendar* cal, 1.223 + UCalendarDisplayNameType type, 1.224 + const char *locale, 1.225 + UChar* result, 1.226 + int32_t resultLength, 1.227 + UErrorCode* status) 1.228 +{ 1.229 + 1.230 + if(U_FAILURE(*status)) return -1; 1.231 + 1.232 + const TimeZone& tz = ((Calendar*)cal)->getTimeZone(); 1.233 + UnicodeString id; 1.234 + if(!(result==NULL && resultLength==0)) { 1.235 + // NULL destination for pure preflighting: empty dummy string 1.236 + // otherwise, alias the destination buffer 1.237 + id.setTo(result, 0, resultLength); 1.238 + } 1.239 + 1.240 + switch(type) { 1.241 + case UCAL_STANDARD: 1.242 + tz.getDisplayName(FALSE, TimeZone::LONG, Locale(locale), id); 1.243 + break; 1.244 + 1.245 + case UCAL_SHORT_STANDARD: 1.246 + tz.getDisplayName(FALSE, TimeZone::SHORT, Locale(locale), id); 1.247 + break; 1.248 + 1.249 + case UCAL_DST: 1.250 + tz.getDisplayName(TRUE, TimeZone::LONG, Locale(locale), id); 1.251 + break; 1.252 + 1.253 + case UCAL_SHORT_DST: 1.254 + tz.getDisplayName(TRUE, TimeZone::SHORT, Locale(locale), id); 1.255 + break; 1.256 + } 1.257 + 1.258 + return id.extract(result, resultLength, *status); 1.259 +} 1.260 + 1.261 +U_CAPI UBool U_EXPORT2 1.262 +ucal_inDaylightTime( const UCalendar* cal, 1.263 + UErrorCode* status ) 1.264 +{ 1.265 + 1.266 + if(U_FAILURE(*status)) return (UBool) -1; 1.267 + return ((Calendar*)cal)->inDaylightTime(*status); 1.268 +} 1.269 + 1.270 +U_CAPI void U_EXPORT2 1.271 +ucal_setGregorianChange(UCalendar *cal, UDate date, UErrorCode *pErrorCode) { 1.272 + if(U_FAILURE(*pErrorCode)) { 1.273 + return; 1.274 + } 1.275 + Calendar *cpp_cal = (Calendar *)cal; 1.276 + GregorianCalendar *gregocal = dynamic_cast<GregorianCalendar *>(cpp_cal); 1.277 + // Not if(gregocal == NULL) { 1.278 + // because we really want to work only with a GregorianCalendar, not with 1.279 + // its subclasses like BuddhistCalendar. 1.280 + if (cpp_cal == NULL) { 1.281 + // We normally don't check "this" pointers for NULL, but this here avoids 1.282 + // compiler-generated exception-throwing code in case cal == NULL. 1.283 + *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; 1.284 + return; 1.285 + } 1.286 + if(typeid(*cpp_cal) != typeid(GregorianCalendar)) { 1.287 + *pErrorCode = U_UNSUPPORTED_ERROR; 1.288 + return; 1.289 + } 1.290 + gregocal->setGregorianChange(date, *pErrorCode); 1.291 +} 1.292 + 1.293 +U_CAPI UDate U_EXPORT2 1.294 +ucal_getGregorianChange(const UCalendar *cal, UErrorCode *pErrorCode) { 1.295 + if(U_FAILURE(*pErrorCode)) { 1.296 + return (UDate)0; 1.297 + } 1.298 + const Calendar *cpp_cal = (const Calendar *)cal; 1.299 + const GregorianCalendar *gregocal = dynamic_cast<const GregorianCalendar *>(cpp_cal); 1.300 + // Not if(gregocal == NULL) { 1.301 + // see comments in ucal_setGregorianChange(). 1.302 + if (cpp_cal == NULL) { 1.303 + // We normally don't check "this" pointers for NULL, but this here avoids 1.304 + // compiler-generated exception-throwing code in case cal == NULL. 1.305 + *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR; 1.306 + return (UDate)0; 1.307 + } 1.308 + if(typeid(*cpp_cal) != typeid(GregorianCalendar)) { 1.309 + *pErrorCode = U_UNSUPPORTED_ERROR; 1.310 + return (UDate)0; 1.311 + } 1.312 + return gregocal->getGregorianChange(); 1.313 +} 1.314 + 1.315 +U_CAPI int32_t U_EXPORT2 1.316 +ucal_getAttribute( const UCalendar* cal, 1.317 + UCalendarAttribute attr) 1.318 +{ 1.319 + 1.320 + switch(attr) { 1.321 + case UCAL_LENIENT: 1.322 + return ((Calendar*)cal)->isLenient(); 1.323 + 1.324 + case UCAL_FIRST_DAY_OF_WEEK: 1.325 + return ((Calendar*)cal)->getFirstDayOfWeek(); 1.326 + 1.327 + case UCAL_MINIMAL_DAYS_IN_FIRST_WEEK: 1.328 + return ((Calendar*)cal)->getMinimalDaysInFirstWeek(); 1.329 + 1.330 + case UCAL_REPEATED_WALL_TIME: 1.331 + return ((Calendar*)cal)->getRepeatedWallTimeOption(); 1.332 + 1.333 + case UCAL_SKIPPED_WALL_TIME: 1.334 + return ((Calendar*)cal)->getSkippedWallTimeOption(); 1.335 + 1.336 + default: 1.337 + break; 1.338 + } 1.339 + return -1; 1.340 +} 1.341 + 1.342 +U_CAPI void U_EXPORT2 1.343 +ucal_setAttribute( UCalendar* cal, 1.344 + UCalendarAttribute attr, 1.345 + int32_t newValue) 1.346 +{ 1.347 + 1.348 + switch(attr) { 1.349 + case UCAL_LENIENT: 1.350 + ((Calendar*)cal)->setLenient((UBool)newValue); 1.351 + break; 1.352 + 1.353 + case UCAL_FIRST_DAY_OF_WEEK: 1.354 + ((Calendar*)cal)->setFirstDayOfWeek((UCalendarDaysOfWeek)newValue); 1.355 + break; 1.356 + 1.357 + case UCAL_MINIMAL_DAYS_IN_FIRST_WEEK: 1.358 + ((Calendar*)cal)->setMinimalDaysInFirstWeek((uint8_t)newValue); 1.359 + break; 1.360 + 1.361 + case UCAL_REPEATED_WALL_TIME: 1.362 + ((Calendar*)cal)->setRepeatedWallTimeOption((UCalendarWallTimeOption)newValue); 1.363 + break; 1.364 + 1.365 + case UCAL_SKIPPED_WALL_TIME: 1.366 + ((Calendar*)cal)->setSkippedWallTimeOption((UCalendarWallTimeOption)newValue); 1.367 + break; 1.368 + } 1.369 +} 1.370 + 1.371 +U_CAPI const char* U_EXPORT2 1.372 +ucal_getAvailable(int32_t index) 1.373 +{ 1.374 + 1.375 + return uloc_getAvailable(index); 1.376 +} 1.377 + 1.378 +U_CAPI int32_t U_EXPORT2 1.379 +ucal_countAvailable() 1.380 +{ 1.381 + 1.382 + return uloc_countAvailable(); 1.383 +} 1.384 + 1.385 +U_CAPI UDate U_EXPORT2 1.386 +ucal_getMillis( const UCalendar* cal, 1.387 + UErrorCode* status) 1.388 +{ 1.389 + 1.390 + if(U_FAILURE(*status)) return (UDate) 0; 1.391 + 1.392 + return ((Calendar*)cal)->getTime(*status); 1.393 +} 1.394 + 1.395 +U_CAPI void U_EXPORT2 1.396 +ucal_setMillis( UCalendar* cal, 1.397 + UDate dateTime, 1.398 + UErrorCode* status ) 1.399 +{ 1.400 + if(U_FAILURE(*status)) return; 1.401 + 1.402 + ((Calendar*)cal)->setTime(dateTime, *status); 1.403 +} 1.404 + 1.405 +// TBD: why does this take an UErrorCode? 1.406 +U_CAPI void U_EXPORT2 1.407 +ucal_setDate( UCalendar* cal, 1.408 + int32_t year, 1.409 + int32_t month, 1.410 + int32_t date, 1.411 + UErrorCode *status) 1.412 +{ 1.413 + 1.414 + if(U_FAILURE(*status)) return; 1.415 + 1.416 + ((Calendar*)cal)->set(year, month, date); 1.417 +} 1.418 + 1.419 +// TBD: why does this take an UErrorCode? 1.420 +U_CAPI void U_EXPORT2 1.421 +ucal_setDateTime( UCalendar* cal, 1.422 + int32_t year, 1.423 + int32_t month, 1.424 + int32_t date, 1.425 + int32_t hour, 1.426 + int32_t minute, 1.427 + int32_t second, 1.428 + UErrorCode *status) 1.429 +{ 1.430 + if(U_FAILURE(*status)) return; 1.431 + 1.432 + ((Calendar*)cal)->set(year, month, date, hour, minute, second); 1.433 +} 1.434 + 1.435 +U_CAPI UBool U_EXPORT2 1.436 +ucal_equivalentTo( const UCalendar* cal1, 1.437 + const UCalendar* cal2) 1.438 +{ 1.439 + 1.440 + return ((Calendar*)cal1)->isEquivalentTo(*((Calendar*)cal2)); 1.441 +} 1.442 + 1.443 +U_CAPI void U_EXPORT2 1.444 +ucal_add( UCalendar* cal, 1.445 + UCalendarDateFields field, 1.446 + int32_t amount, 1.447 + UErrorCode* status) 1.448 +{ 1.449 + 1.450 + if(U_FAILURE(*status)) return; 1.451 + 1.452 + ((Calendar*)cal)->add(field, amount, *status); 1.453 +} 1.454 + 1.455 +U_CAPI void U_EXPORT2 1.456 +ucal_roll( UCalendar* cal, 1.457 + UCalendarDateFields field, 1.458 + int32_t amount, 1.459 + UErrorCode* status) 1.460 +{ 1.461 + 1.462 + if(U_FAILURE(*status)) return; 1.463 + 1.464 + ((Calendar*)cal)->roll(field, amount, *status); 1.465 +} 1.466 + 1.467 +U_CAPI int32_t U_EXPORT2 1.468 +ucal_get( const UCalendar* cal, 1.469 + UCalendarDateFields field, 1.470 + UErrorCode* status ) 1.471 +{ 1.472 + 1.473 + if(U_FAILURE(*status)) return -1; 1.474 + 1.475 + return ((Calendar*)cal)->get(field, *status); 1.476 +} 1.477 + 1.478 +U_CAPI void U_EXPORT2 1.479 +ucal_set( UCalendar* cal, 1.480 + UCalendarDateFields field, 1.481 + int32_t value) 1.482 +{ 1.483 + 1.484 + ((Calendar*)cal)->set(field, value); 1.485 +} 1.486 + 1.487 +U_CAPI UBool U_EXPORT2 1.488 +ucal_isSet( const UCalendar* cal, 1.489 + UCalendarDateFields field) 1.490 +{ 1.491 + 1.492 + return ((Calendar*)cal)->isSet(field); 1.493 +} 1.494 + 1.495 +U_CAPI void U_EXPORT2 1.496 +ucal_clearField( UCalendar* cal, 1.497 + UCalendarDateFields field) 1.498 +{ 1.499 + 1.500 + ((Calendar*)cal)->clear(field); 1.501 +} 1.502 + 1.503 +U_CAPI void U_EXPORT2 1.504 +ucal_clear(UCalendar* calendar) 1.505 +{ 1.506 + 1.507 + ((Calendar*)calendar)->clear(); 1.508 +} 1.509 + 1.510 +U_CAPI int32_t U_EXPORT2 1.511 +ucal_getLimit( const UCalendar* cal, 1.512 + UCalendarDateFields field, 1.513 + UCalendarLimitType type, 1.514 + UErrorCode *status) 1.515 +{ 1.516 + 1.517 + if(status==0 || U_FAILURE(*status)) { 1.518 + return -1; 1.519 + } 1.520 + 1.521 + switch(type) { 1.522 + case UCAL_MINIMUM: 1.523 + return ((Calendar*)cal)->getMinimum(field); 1.524 + 1.525 + case UCAL_MAXIMUM: 1.526 + return ((Calendar*)cal)->getMaximum(field); 1.527 + 1.528 + case UCAL_GREATEST_MINIMUM: 1.529 + return ((Calendar*)cal)->getGreatestMinimum(field); 1.530 + 1.531 + case UCAL_LEAST_MAXIMUM: 1.532 + return ((Calendar*)cal)->getLeastMaximum(field); 1.533 + 1.534 + case UCAL_ACTUAL_MINIMUM: 1.535 + return ((Calendar*)cal)->getActualMinimum(field, 1.536 + *status); 1.537 + 1.538 + case UCAL_ACTUAL_MAXIMUM: 1.539 + return ((Calendar*)cal)->getActualMaximum(field, 1.540 + *status); 1.541 + 1.542 + default: 1.543 + break; 1.544 + } 1.545 + return -1; 1.546 +} 1.547 + 1.548 +U_CAPI const char * U_EXPORT2 1.549 +ucal_getLocaleByType(const UCalendar *cal, ULocDataLocaleType type, UErrorCode* status) 1.550 +{ 1.551 + if (cal == NULL) { 1.552 + if (U_SUCCESS(*status)) { 1.553 + *status = U_ILLEGAL_ARGUMENT_ERROR; 1.554 + } 1.555 + return NULL; 1.556 + } 1.557 + return ((Calendar*)cal)->getLocaleID(type, *status); 1.558 +} 1.559 + 1.560 +U_CAPI const char * U_EXPORT2 1.561 +ucal_getTZDataVersion(UErrorCode* status) 1.562 +{ 1.563 + return TimeZone::getTZDataVersion(*status); 1.564 +} 1.565 + 1.566 +U_CAPI int32_t U_EXPORT2 1.567 +ucal_getCanonicalTimeZoneID(const UChar* id, int32_t len, 1.568 + UChar* result, int32_t resultCapacity, UBool *isSystemID, UErrorCode* status) { 1.569 + if(status == 0 || U_FAILURE(*status)) { 1.570 + return 0; 1.571 + } 1.572 + if (isSystemID) { 1.573 + *isSystemID = FALSE; 1.574 + } 1.575 + if (id == 0 || len == 0 || result == 0 || resultCapacity <= 0) { 1.576 + *status = U_ILLEGAL_ARGUMENT_ERROR; 1.577 + return 0; 1.578 + } 1.579 + int32_t reslen = 0; 1.580 + UnicodeString canonical; 1.581 + UBool systemID = FALSE; 1.582 + TimeZone::getCanonicalID(UnicodeString(id, len), canonical, systemID, *status); 1.583 + if (U_SUCCESS(*status)) { 1.584 + if (isSystemID) { 1.585 + *isSystemID = systemID; 1.586 + } 1.587 + reslen = canonical.extract(result, resultCapacity, *status); 1.588 + } 1.589 + return reslen; 1.590 +} 1.591 + 1.592 +U_CAPI const char * U_EXPORT2 1.593 +ucal_getType(const UCalendar *cal, UErrorCode* status) 1.594 +{ 1.595 + if (U_FAILURE(*status)) { 1.596 + return NULL; 1.597 + } 1.598 + return ((Calendar*)cal)->getType(); 1.599 +} 1.600 + 1.601 +U_CAPI UCalendarWeekdayType U_EXPORT2 1.602 +ucal_getDayOfWeekType(const UCalendar *cal, UCalendarDaysOfWeek dayOfWeek, UErrorCode* status) 1.603 +{ 1.604 + if (U_FAILURE(*status)) { 1.605 + return UCAL_WEEKDAY; 1.606 + } 1.607 + return ((Calendar*)cal)->getDayOfWeekType(dayOfWeek, *status); 1.608 +} 1.609 + 1.610 +U_CAPI int32_t U_EXPORT2 1.611 +ucal_getWeekendTransition(const UCalendar *cal, UCalendarDaysOfWeek dayOfWeek, UErrorCode *status) 1.612 +{ 1.613 + if (U_FAILURE(*status)) { 1.614 + return 0; 1.615 + } 1.616 + return ((Calendar*)cal)->getWeekendTransition(dayOfWeek, *status); 1.617 +} 1.618 + 1.619 +U_CAPI UBool U_EXPORT2 1.620 +ucal_isWeekend(const UCalendar *cal, UDate date, UErrorCode *status) 1.621 +{ 1.622 + if (U_FAILURE(*status)) { 1.623 + return FALSE; 1.624 + } 1.625 + return ((Calendar*)cal)->isWeekend(date, *status); 1.626 +} 1.627 + 1.628 +U_CAPI int32_t U_EXPORT2 1.629 +ucal_getFieldDifference(UCalendar* cal, UDate target, 1.630 + UCalendarDateFields field, 1.631 + UErrorCode* status ) 1.632 +{ 1.633 + if (U_FAILURE(*status)) { 1.634 + return 0; 1.635 + } 1.636 + return ((Calendar*)cal)->fieldDifference(target, field, *status); 1.637 +} 1.638 + 1.639 + 1.640 +static const UEnumeration defaultKeywordValues = { 1.641 + NULL, 1.642 + NULL, 1.643 + ulist_close_keyword_values_iterator, 1.644 + ulist_count_keyword_values, 1.645 + uenum_unextDefault, 1.646 + ulist_next_keyword_value, 1.647 + ulist_reset_keyword_values_iterator 1.648 +}; 1.649 + 1.650 +static const char * const CAL_TYPES[] = { 1.651 + "gregorian", 1.652 + "japanese", 1.653 + "buddhist", 1.654 + "roc", 1.655 + "persian", 1.656 + "islamic-civil", 1.657 + "islamic", 1.658 + "hebrew", 1.659 + "chinese", 1.660 + "indian", 1.661 + "coptic", 1.662 + "ethiopic", 1.663 + "ethiopic-amete-alem", 1.664 + "iso8601", 1.665 + "dangi", 1.666 + "islamic-umalqura", 1.667 + "islamic-tbla", 1.668 + "islamic-rgsa", 1.669 + NULL 1.670 +}; 1.671 + 1.672 +U_CAPI UEnumeration* U_EXPORT2 1.673 +ucal_getKeywordValuesForLocale(const char * /* key */, const char* locale, UBool commonlyUsed, UErrorCode *status) { 1.674 + // Resolve region 1.675 + char prefRegion[ULOC_FULLNAME_CAPACITY] = ""; 1.676 + int32_t prefRegionLength = 0; 1.677 + prefRegionLength = uloc_getCountry(locale, prefRegion, sizeof(prefRegion), status); 1.678 + if (prefRegionLength == 0) { 1.679 + char loc[ULOC_FULLNAME_CAPACITY] = ""; 1.680 + uloc_addLikelySubtags(locale, loc, sizeof(loc), status); 1.681 + 1.682 + prefRegionLength = uloc_getCountry(loc, prefRegion, sizeof(prefRegion), status); 1.683 + } 1.684 + 1.685 + // Read preferred calendar values from supplementalData calendarPreference 1.686 + UResourceBundle *rb = ures_openDirect(NULL, "supplementalData", status); 1.687 + ures_getByKey(rb, "calendarPreferenceData", rb, status); 1.688 + UResourceBundle *order = ures_getByKey(rb, prefRegion, NULL, status); 1.689 + if (*status == U_MISSING_RESOURCE_ERROR && rb != NULL) { 1.690 + *status = U_ZERO_ERROR; 1.691 + order = ures_getByKey(rb, "001", NULL, status); 1.692 + } 1.693 + 1.694 + // Create a list of calendar type strings 1.695 + UList *values = NULL; 1.696 + if (U_SUCCESS(*status)) { 1.697 + values = ulist_createEmptyList(status); 1.698 + if (U_SUCCESS(*status)) { 1.699 + for (int i = 0; i < ures_getSize(order); i++) { 1.700 + int32_t len; 1.701 + const UChar *type = ures_getStringByIndex(order, i, &len, status); 1.702 + char *caltype = (char*)uprv_malloc(len + 1); 1.703 + if (caltype == NULL) { 1.704 + *status = U_MEMORY_ALLOCATION_ERROR; 1.705 + break; 1.706 + } 1.707 + u_UCharsToChars(type, caltype, len); 1.708 + *(caltype + len) = 0; 1.709 + 1.710 + ulist_addItemEndList(values, caltype, TRUE, status); 1.711 + if (U_FAILURE(*status)) { 1.712 + break; 1.713 + } 1.714 + } 1.715 + 1.716 + if (U_SUCCESS(*status) && !commonlyUsed) { 1.717 + // If not commonlyUsed, add other available values 1.718 + for (int32_t i = 0; CAL_TYPES[i] != NULL; i++) { 1.719 + if (!ulist_containsString(values, CAL_TYPES[i], (int32_t)uprv_strlen(CAL_TYPES[i]))) { 1.720 + ulist_addItemEndList(values, CAL_TYPES[i], FALSE, status); 1.721 + if (U_FAILURE(*status)) { 1.722 + break; 1.723 + } 1.724 + } 1.725 + } 1.726 + } 1.727 + if (U_FAILURE(*status)) { 1.728 + ulist_deleteList(values); 1.729 + values = NULL; 1.730 + } 1.731 + } 1.732 + } 1.733 + 1.734 + ures_close(order); 1.735 + ures_close(rb); 1.736 + 1.737 + if (U_FAILURE(*status) || values == NULL) { 1.738 + return NULL; 1.739 + } 1.740 + 1.741 + // Create string enumeration 1.742 + UEnumeration *en = (UEnumeration*)uprv_malloc(sizeof(UEnumeration)); 1.743 + if (en == NULL) { 1.744 + *status = U_MEMORY_ALLOCATION_ERROR; 1.745 + ulist_deleteList(values); 1.746 + return NULL; 1.747 + } 1.748 + ulist_resetList(values); 1.749 + memcpy(en, &defaultKeywordValues, sizeof(UEnumeration)); 1.750 + en->context = values; 1.751 + return en; 1.752 +} 1.753 + 1.754 +U_CAPI UBool U_EXPORT2 1.755 +ucal_getTimeZoneTransitionDate(const UCalendar* cal, UTimeZoneTransitionType type, 1.756 + UDate* transition, UErrorCode* status) 1.757 +{ 1.758 + if (U_FAILURE(*status)) { 1.759 + return FALSE; 1.760 + } 1.761 + UDate base = ((Calendar*)cal)->getTime(*status); 1.762 + const TimeZone& tz = ((Calendar*)cal)->getTimeZone(); 1.763 + const BasicTimeZone * btz = dynamic_cast<const BasicTimeZone *>(&tz); 1.764 + if (btz != NULL && U_SUCCESS(*status)) { 1.765 + TimeZoneTransition tzt; 1.766 + UBool inclusive = (type == UCAL_TZ_TRANSITION_NEXT_INCLUSIVE || type == UCAL_TZ_TRANSITION_PREVIOUS_INCLUSIVE); 1.767 + UBool result = (type == UCAL_TZ_TRANSITION_NEXT || type == UCAL_TZ_TRANSITION_NEXT_INCLUSIVE)? 1.768 + btz->getNextTransition(base, inclusive, tzt): 1.769 + btz->getPreviousTransition(base, inclusive, tzt); 1.770 + if (result) { 1.771 + *transition = tzt.getTime(); 1.772 + return TRUE; 1.773 + } 1.774 + } 1.775 + return FALSE; 1.776 +} 1.777 + 1.778 +#ifndef U_HIDE_DRAFT_API 1.779 +U_CAPI int32_t U_EXPORT2 1.780 +ucal_getWindowsTimeZoneID(const UChar* id, int32_t len, UChar* winid, int32_t winidCapacity, UErrorCode* status) { 1.781 + if (U_FAILURE(*status)) { 1.782 + return 0; 1.783 + } 1.784 + 1.785 + int32_t resultLen = 0; 1.786 + UnicodeString resultWinID; 1.787 + 1.788 + TimeZone::getWindowsID(UnicodeString(id, len), resultWinID, *status); 1.789 + if (U_SUCCESS(*status) && resultWinID.length() > 0) { 1.790 + resultLen = resultWinID.length(); 1.791 + resultWinID.extract(winid, winidCapacity, *status); 1.792 + } 1.793 + 1.794 + return resultLen; 1.795 +} 1.796 + 1.797 +U_CAPI int32_t U_EXPORT2 1.798 +ucal_getTimeZoneIDForWindowsID(const UChar* winid, int32_t len, const char* region, UChar* id, int32_t idCapacity, UErrorCode* status) { 1.799 + if (U_FAILURE(*status)) { 1.800 + return 0; 1.801 + } 1.802 + 1.803 + int32_t resultLen = 0; 1.804 + UnicodeString resultID; 1.805 + 1.806 + TimeZone::getIDForWindowsID(UnicodeString(winid, len), region, resultID, *status); 1.807 + if (U_SUCCESS(*status) && resultID.length() > 0) { 1.808 + resultLen = resultID.length(); 1.809 + resultID.extract(id, idCapacity, *status); 1.810 + } 1.811 + 1.812 + return resultLen; 1.813 +} 1.814 + 1.815 +#endif /* U_HIDE_DRAFT_API */ 1.816 + 1.817 +#endif /* #if !UCONFIG_NO_FORMATTING */