]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/i18n/smpdtfmt.cpp
ICU-59117.0.1.tar.gz
[apple/icu.git] / icuSources / i18n / smpdtfmt.cpp
index 2bcb5920f15308600a75dba2e1ca5a459959ad8e..3393501a193b01e9ca4e9802ce2da4f6adca6fe1 100644 (file)
@@ -1,3 +1,5 @@
+// © 2016 and later: Unicode, Inc. and others.
+// License & terms of use: http://www.unicode.org/copyright.html
 /*
 *******************************************************************************
 * Copyright (C) 1997-2016, International Business Machines Corporation and    *
 #include "unicode/simpletz.h"
 #include "unicode/rbtz.h"
 #include "unicode/tzfmt.h"
+#include "unicode/ucasemap.h"
 #include "unicode/utf16.h"
 #include "unicode/vtzone.h"
 #include "unicode/udisplaycontext.h"
 #include "unicode/brkiter.h"
+#include "uresimp.h"
 #include "olsontz.h"
 #include "patternprops.h"
 #include "fphdlimp.h"
-#include "gregoimp.h"
 #include "hebrwcal.h"
 #include "cstring.h"
 #include "uassert.h"
@@ -62,6 +65,7 @@
 #include <float.h>
 #include "smpdtfst.h"
 #include "sharednumberformat.h"
+#include "ucasemap_imp.h"
 #include "ustr_imp.h"
 #include "charstr.h"
 #include "uvector.h"
@@ -164,9 +168,6 @@ static const UChar SUPPRESS_NEGATIVE_PREFIX[] = {0xAB00, 0};
  * These are the tags we expect to see in normal resource bundle files associated
  * with a locale.
  */
-static const char gDateTimePatternsTag[]="DateTimePatterns";
-
-//static const UChar gEtcUTC[] = {0x45, 0x74, 0x63, 0x2F, 0x55, 0x54, 0x43, 0x00}; // "Etc/UTC"
 static const UChar QUOTE = 0x27; // Single quote
 
 /*
@@ -755,20 +756,42 @@ void SimpleDateFormat::construct(EStyle timeStyle,
     initializeCalendar(NULL, locale, status);
     if (U_FAILURE(status)) return;
 
-    CalendarData calData(locale, fCalendar?fCalendar->getType():NULL, status);
-    UResourceBundle *dateTimePatterns = calData.getByKey(gDateTimePatternsTag, status);
-    UResourceBundle *currentBundle;
+    // Load date time patterns directly from resources.
+    const char* cType = fCalendar ? fCalendar->getType() : NULL;
+    LocalUResourceBundlePointer bundle(ures_open(NULL, locale.getBaseName(), &status));
+    if (U_FAILURE(status)) return;
+
+    UBool cTypeIsGregorian = TRUE;
+    LocalUResourceBundlePointer dateTimePatterns;
+    if (cType != NULL && uprv_strcmp(cType, "gregorian") != 0) {
+        CharString resourcePath("calendar/", status);
+        resourcePath.append(cType, status).append("/DateTimePatterns", status);
+        dateTimePatterns.adoptInstead(
+            ures_getByKeyWithFallback(bundle.getAlias(), resourcePath.data(),
+                                      (UResourceBundle*)NULL, &status));
+        cTypeIsGregorian = FALSE;
+    }
 
+    // Check for "gregorian" fallback.
+    if (cTypeIsGregorian || status == U_MISSING_RESOURCE_ERROR) {
+        status = U_ZERO_ERROR;
+        dateTimePatterns.adoptInstead(
+            ures_getByKeyWithFallback(bundle.getAlias(),
+                                      "calendar/gregorian/DateTimePatterns",
+                                      (UResourceBundle*)NULL, &status));
+    }
     if (U_FAILURE(status)) return;
 
-    if (ures_getSize(dateTimePatterns) <= kDateTime)
+    LocalUResourceBundlePointer currentBundle;
+
+    if (ures_getSize(dateTimePatterns.getAlias()) <= kDateTime)
     {
         status = U_INVALID_FORMAT_ERROR;
         return;
     }
 
-    setLocaleIDs(ures_getLocaleByType(dateTimePatterns, ULOC_VALID_LOCALE, &status),
-                 ures_getLocaleByType(dateTimePatterns, ULOC_ACTUAL_LOCALE, &status));
+    setLocaleIDs(ures_getLocaleByType(dateTimePatterns.getAlias(), ULOC_VALID_LOCALE, &status),
+                 ures_getLocaleByType(dateTimePatterns.getAlias(), ULOC_ACTUAL_LOCALE, &status));
 
     // create a symbols object from the locale
     fSymbols = DateFormatSymbols::createForLocale(locale, status);
@@ -789,66 +812,64 @@ void SimpleDateFormat::construct(EStyle timeStyle,
     // and time pattern strings.
     if ((timeStyle != kNone) && (dateStyle != kNone))
     {
-        currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)timeStyle, NULL, &status);
+        currentBundle.adoptInstead(
+                ures_getByIndex(dateTimePatterns.getAlias(), (int32_t)timeStyle, NULL, &status));
         if (U_FAILURE(status)) {
            status = U_INVALID_FORMAT_ERROR;
            return;
         }
-        switch (ures_getType(currentBundle)) {
+        switch (ures_getType(currentBundle.getAlias())) {
             case URES_STRING: {
-               resStr = ures_getString(currentBundle, &resStrLen, &status);
+               resStr = ures_getString(currentBundle.getAlias(), &resStrLen, &status);
                break;
             }
             case URES_ARRAY: {
-               resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status);
-               ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status);
+               resStr = ures_getStringByIndex(currentBundle.getAlias(), 0, &resStrLen, &status);
+               ovrStr = ures_getStringByIndex(currentBundle.getAlias(), 1, &ovrStrLen, &status);
                fTimeOverride.setTo(TRUE, ovrStr, ovrStrLen);
                break;
             }
             default: {
                status = U_INVALID_FORMAT_ERROR;
-               ures_close(currentBundle);
                return;
             }
         }
-        ures_close(currentBundle);
 
         UnicodeString tempus1(TRUE, resStr, resStrLen);
 
-        currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)dateStyle, NULL, &status);
+        currentBundle.adoptInstead(
+                ures_getByIndex(dateTimePatterns.getAlias(), (int32_t)dateStyle, NULL, &status));
         if (U_FAILURE(status)) {
            status = U_INVALID_FORMAT_ERROR;
            return;
         }
-        switch (ures_getType(currentBundle)) {
+        switch (ures_getType(currentBundle.getAlias())) {
             case URES_STRING: {
-               resStr = ures_getString(currentBundle, &resStrLen, &status);
+               resStr = ures_getString(currentBundle.getAlias(), &resStrLen, &status);
                break;
             }
             case URES_ARRAY: {
-               resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status);
-               ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status);
+               resStr = ures_getStringByIndex(currentBundle.getAlias(), 0, &resStrLen, &status);
+               ovrStr = ures_getStringByIndex(currentBundle.getAlias(), 1, &ovrStrLen, &status);
                fDateOverride.setTo(TRUE, ovrStr, ovrStrLen);
                break;
             }
             default: {
                status = U_INVALID_FORMAT_ERROR;
-               ures_close(currentBundle);
                return;
             }
         }
-        ures_close(currentBundle);
 
         UnicodeString tempus2(TRUE, resStr, resStrLen);
 
         int32_t glueIndex = kDateTime;
-        int32_t patternsSize = ures_getSize(dateTimePatterns);
+        int32_t patternsSize = ures_getSize(dateTimePatterns.getAlias());
         if (patternsSize >= (kDateTimeOffset + kShort + 1)) {
             // Get proper date time format
             glueIndex = (int32_t)(kDateTimeOffset + (dateStyle - kDateOffset));
         }
 
-        resStr = ures_getStringByIndex(dateTimePatterns, glueIndex, &resStrLen, &status);
+        resStr = ures_getStringByIndex(dateTimePatterns.getAlias(), glueIndex, &resStrLen, &status);
         SimpleFormatter(UnicodeString(TRUE, resStr, resStrLen), 2, 2, status).
                 format(tempus1, tempus2, fPattern, status);
     }
@@ -856,56 +877,54 @@ void SimpleDateFormat::construct(EStyle timeStyle,
     // pattern string from the resources
     // setTo() - see DateFormatSymbols::assignArray comments
     else if (timeStyle != kNone) {
-        currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)timeStyle, NULL, &status);
+        currentBundle.adoptInstead(
+                ures_getByIndex(dateTimePatterns.getAlias(), (int32_t)timeStyle, NULL, &status));
         if (U_FAILURE(status)) {
            status = U_INVALID_FORMAT_ERROR;
            return;
         }
-        switch (ures_getType(currentBundle)) {
+        switch (ures_getType(currentBundle.getAlias())) {
             case URES_STRING: {
-               resStr = ures_getString(currentBundle, &resStrLen, &status);
+               resStr = ures_getString(currentBundle.getAlias(), &resStrLen, &status);
                break;
             }
             case URES_ARRAY: {
-               resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status);
-               ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status);
+               resStr = ures_getStringByIndex(currentBundle.getAlias(), 0, &resStrLen, &status);
+               ovrStr = ures_getStringByIndex(currentBundle.getAlias(), 1, &ovrStrLen, &status);
                fDateOverride.setTo(TRUE, ovrStr, ovrStrLen);
                break;
             }
             default: {
                status = U_INVALID_FORMAT_ERROR;
-                ures_close(currentBundle);
                return;
             }
         }
         fPattern.setTo(TRUE, resStr, resStrLen);
-        ures_close(currentBundle);
     }
     else if (dateStyle != kNone) {
-        currentBundle = ures_getByIndex(dateTimePatterns, (int32_t)dateStyle, NULL, &status);
+        currentBundle.adoptInstead(
+                ures_getByIndex(dateTimePatterns.getAlias(), (int32_t)dateStyle, NULL, &status));
         if (U_FAILURE(status)) {
            status = U_INVALID_FORMAT_ERROR;
            return;
         }
-        switch (ures_getType(currentBundle)) {
+        switch (ures_getType(currentBundle.getAlias())) {
             case URES_STRING: {
-               resStr = ures_getString(currentBundle, &resStrLen, &status);
+               resStr = ures_getString(currentBundle.getAlias(), &resStrLen, &status);
                break;
             }
             case URES_ARRAY: {
-               resStr = ures_getStringByIndex(currentBundle, 0, &resStrLen, &status);
-               ovrStr = ures_getStringByIndex(currentBundle, 1, &ovrStrLen, &status);
+               resStr = ures_getStringByIndex(currentBundle.getAlias(), 0, &resStrLen, &status);
+               ovrStr = ures_getStringByIndex(currentBundle.getAlias(), 1, &ovrStrLen, &status);
                fDateOverride.setTo(TRUE, ovrStr, ovrStrLen);
                break;
             }
             default: {
                status = U_INVALID_FORMAT_ERROR;
-               ures_close(currentBundle);
                return;
             }
         }
         fPattern.setTo(TRUE, resStr, resStrLen);
-        ures_close(currentBundle);
     }
 
     // and if it includes _neither_, that's an error
@@ -1621,7 +1640,7 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
             } else if (count == 2) {
                 value /= 10;
             }
-            FieldPosition p(0);
+            FieldPosition p(FieldPosition::DONT_CARE);
             currentNumberFormat->format(value, appendTo, p);
             if (count > 3) {
                 currentNumberFormat->setMinimumIntegerDigits(count - 3);
@@ -2108,7 +2127,7 @@ SimpleDateFormat::zeroPaddingNumber(
         int32_t value, int32_t minDigits, int32_t maxDigits) const
 {
     if (currentNumberFormat!=NULL) {
-        FieldPosition pos(0);
+        FieldPosition pos(FieldPosition::DONT_CARE);
 
         currentNumberFormat->setMinimumIntegerDigits(minDigits);
         currentNumberFormat->setMaximumIntegerDigits(maxDigits);