]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/ucal.cpp
ICU-511.34.tar.gz
[apple/icu.git] / icuSources / i18n / ucal.cpp
index cb060ab28aec6cc2ebe3a116256066cba036a7cf..ff231eedf03cb12a51c14a3648f3f0c611b091f5 100644 (file)
@@ -1,11 +1,11 @@
 /*
 *******************************************************************************
-*   Copyright (C) 1996-2011, International Business Machines
+*   Copyright (C) 1996-2013, International Business Machines
 *   Corporation and others.  All Rights Reserved.
 *******************************************************************************
 */
 
-#include <typeinfo>  // for 'typeid' to work
+#include "utypeinfo.h"  // for 'typeid' to work
 
 #include "unicode/utypes.h"
 
@@ -19,6 +19,7 @@
 #include "unicode/simpletz.h"
 #include "unicode/ustring.h"
 #include "unicode/strenum.h"
+#include "unicode/localpointer.h"
 #include "cmemory.h"
 #include "cstring.h"
 #include "ustrenum.h"
@@ -45,6 +46,13 @@ _createTimeZone(const UChar* zoneID, int32_t len, UErrorCode* ec) {
     return zone;
 }
 
+U_CAPI UEnumeration* U_EXPORT2
+ucal_openTimeZoneIDEnumeration(USystemTimeZoneType zoneType, const char* region,
+                                const int32_t* rawOffset, UErrorCode* ec) {
+    return uenum_openFromStringEnumeration(TimeZone::createTimeZoneIDEnumeration(
+        zoneType, region, rawOffset, *ec), ec);
+}
+
 U_CAPI UEnumeration* U_EXPORT2
 ucal_openTimeZones(UErrorCode* ec) {
     return uenum_openFromStringEnumeration(TimeZone::createEnumeration(), ec);
@@ -192,6 +200,21 @@ ucal_setTimeZone(    UCalendar*      cal,
   }
 }
 
+U_CAPI int32_t U_EXPORT2
+ucal_getTimeZoneID(const UCalendar *cal,
+                   UChar *result,
+                   int32_t resultLength,
+                   UErrorCode *status)
+{
+    if (U_FAILURE(*status)) {
+        return 0;
+    }
+    const TimeZone& tz = ((Calendar*)cal)->getTimeZone();
+    UnicodeString id;
+    tz.getID(id);
+    return id.extract(result, resultLength, *status);
+}
+
 U_CAPI int32_t U_EXPORT2
 ucal_getTimeZoneDisplayName(const     UCalendar*                 cal,
                     UCalendarDisplayNameType     type,
@@ -251,6 +274,12 @@ ucal_setGregorianChange(UCalendar *cal, UDate date, UErrorCode *pErrorCode) {
     // Not if(gregocal == NULL) {
     // because we really want to work only with a GregorianCalendar, not with
     // its subclasses like BuddhistCalendar.
+    if (cpp_cal == NULL) {
+        // We normally don't check "this" pointers for NULL, but this here avoids
+        // compiler-generated exception-throwing code in case cal == NULL.
+        *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return;
+    }
     if(typeid(*cpp_cal) != typeid(GregorianCalendar)) {
         *pErrorCode = U_UNSUPPORTED_ERROR;
         return;
@@ -267,6 +296,12 @@ ucal_getGregorianChange(const UCalendar *cal, UErrorCode *pErrorCode) {
     const GregorianCalendar *gregocal = dynamic_cast<const GregorianCalendar *>(cpp_cal);
     // Not if(gregocal == NULL) {
     // see comments in ucal_setGregorianChange().
+    if (cpp_cal == NULL) {
+        // We normally don't check "this" pointers for NULL, but this here avoids
+        // compiler-generated exception-throwing code in case cal == NULL.
+        *pErrorCode = U_ILLEGAL_ARGUMENT_ERROR;
+        return (UDate)0;
+    }
     if(typeid(*cpp_cal) != typeid(GregorianCalendar)) {
         *pErrorCode = U_UNSUPPORTED_ERROR;
         return (UDate)0;
@@ -289,6 +324,12 @@ ucal_getAttribute(    const    UCalendar*              cal,
   case UCAL_MINIMAL_DAYS_IN_FIRST_WEEK:
       return ((Calendar*)cal)->getMinimalDaysInFirstWeek();
 
+  case UCAL_REPEATED_WALL_TIME:
+      return ((Calendar*)cal)->getRepeatedWallTimeOption();
+
+  case UCAL_SKIPPED_WALL_TIME:
+      return ((Calendar*)cal)->getSkippedWallTimeOption();
+
   default:
       break;
     }
@@ -313,6 +354,14 @@ ucal_setAttribute(      UCalendar*              cal,
   case UCAL_MINIMAL_DAYS_IN_FIRST_WEEK:
       ((Calendar*)cal)->setMinimalDaysInFirstWeek((uint8_t)newValue);
       break;
+
+  case UCAL_REPEATED_WALL_TIME:
+      ((Calendar*)cal)->setRepeatedWallTimeOption((UCalendarWallTimeOption)newValue);
+      break;
+
+  case UCAL_SKIPPED_WALL_TIME:
+      ((Calendar*)cal)->setSkippedWallTimeOption((UCalendarWallTimeOption)newValue);
+      break;
     }
 }
 
@@ -620,8 +669,7 @@ ucal_getKeywordValuesForLocale(const char * /* key */, const char* locale, UBool
     prefRegionLength = uloc_getCountry(locale, prefRegion, sizeof(prefRegion), status);
     if (prefRegionLength == 0) {
         char loc[ULOC_FULLNAME_CAPACITY] = "";
-        int32_t locLength = 0;
-        locLength = uloc_addLikelySubtags(locale, loc, sizeof(loc), status);
+        uloc_addLikelySubtags(locale, loc, sizeof(loc), status);
         
         prefRegionLength = uloc_getCountry(loc, prefRegion, sizeof(prefRegion), status);
     }
@@ -695,4 +743,28 @@ ucal_getKeywordValuesForLocale(const char * /* key */, const char* locale, UBool
     return en;
 }
 
+U_CAPI UBool U_EXPORT2 
+ucal_getTimeZoneTransitionDate(const UCalendar* cal, UTimeZoneTransitionType type,
+                               UDate* transition, UErrorCode* status)
+{
+    if (U_FAILURE(*status)) {
+        return FALSE;
+    }
+    UDate base = ((Calendar*)cal)->getTime(*status);
+    const TimeZone& tz = ((Calendar*)cal)->getTimeZone();
+    const BasicTimeZone * btz = dynamic_cast<const BasicTimeZone *>(&tz);
+    if (btz != NULL && U_SUCCESS(*status)) {
+        TimeZoneTransition tzt;
+        UBool inclusive = (type == UCAL_TZ_TRANSITION_NEXT_INCLUSIVE || type == UCAL_TZ_TRANSITION_PREVIOUS_INCLUSIVE);
+        UBool result = (type == UCAL_TZ_TRANSITION_NEXT || type == UCAL_TZ_TRANSITION_NEXT_INCLUSIVE)?
+                        btz->getNextTransition(base, inclusive, tzt):
+                        btz->getPreviousTransition(base, inclusive, tzt);
+        if (result) {
+            *transition = tzt.getTime();
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
 #endif /* #if !UCONFIG_NO_FORMATTING */