]> granicus.if.org Git - icu/commitdiff
ICU-11510 C: Support narrow AM/PM "aaaaa" for date format and parse
authorPeter Edberg <pedberg@unicode.org>
Wed, 4 Mar 2015 05:43:28 +0000 (05:43 +0000)
committerPeter Edberg <pedberg@unicode.org>
Wed, 4 Mar 2015 05:43:28 +0000 (05:43 +0000)
X-SVN-Rev: 37124

icu4c/source/i18n/dtfmtsym.cpp
icu4c/source/i18n/smpdtfmt.cpp
icu4c/source/i18n/unicode/dtfmtsym.h
icu4c/source/test/intltest/dtfmttst.cpp

index e03384e3a9defdd8b9516a72d430ad86a0f5dc61..3f7f3663f19a26749a09d9b9a96de31d9ad9eb2f 100644 (file)
@@ -1,6 +1,6 @@
 /*
 *******************************************************************************
-* Copyright (C) 1997-2014, International Business Machines Corporation and    *
+* Copyright (C) 1997-2015, International Business Machines Corporation and    *
 * others. All Rights Reserved.                                                *
 *******************************************************************************
 *
@@ -202,6 +202,7 @@ static const char gNamesFormatTag[]="format";
 static const char gNamesStandaloneTag[]="stand-alone";
 static const char gNamesNumericTag[]="numeric";
 static const char gAmPmMarkersTag[]="AmPmMarkers";
+static const char gAmPmMarkersNarrowTag[]="AmPmMarkersNarrow";
 static const char gQuartersTag[]="quarters";
 static const char gNumberElementsTag[]="NumberElements";
 static const char gSymbolsTag[]="symbols";
@@ -368,6 +369,7 @@ DateFormatSymbols::copyData(const DateFormatSymbols& other) {
     assignArray(fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, other.fStandaloneShorterWeekdays, other.fStandaloneShorterWeekdaysCount);
     assignArray(fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, other.fStandaloneNarrowWeekdays, other.fStandaloneNarrowWeekdaysCount);
     assignArray(fAmPms, fAmPmsCount, other.fAmPms, other.fAmPmsCount);
+    assignArray(fNarrowAmPms, fNarrowAmPmsCount, other.fNarrowAmPms, other.fNarrowAmPmsCount );
     fTimeSeparator.fastCopyFrom(other.fTimeSeparator);  // fastCopyFrom() - see assignArray comments
     assignArray(fQuarters, fQuartersCount, other.fQuarters, other.fQuartersCount);
     assignArray(fShortQuarters, fShortQuartersCount, other.fShortQuarters, other.fShortQuartersCount);
@@ -448,6 +450,7 @@ void DateFormatSymbols::dispose()
     if (fStandaloneShorterWeekdays) delete[] fStandaloneShorterWeekdays;
     if (fStandaloneNarrowWeekdays)  delete[] fStandaloneNarrowWeekdays;
     if (fAmPms)                     delete[] fAmPms;
+    if (fNarrowAmPms)               delete[] fNarrowAmPms;
     if (fQuarters)                  delete[] fQuarters;
     if (fShortQuarters)             delete[] fShortQuarters;
     if (fStandaloneQuarters)        delete[] fStandaloneQuarters;
@@ -519,6 +522,7 @@ DateFormatSymbols::operator==(const DateFormatSymbols& other) const
         fStandaloneShorterWeekdaysCount == other.fStandaloneShorterWeekdaysCount &&
         fStandaloneNarrowWeekdaysCount == other.fStandaloneNarrowWeekdaysCount &&
         fAmPmsCount == other.fAmPmsCount &&
+        fNarrowAmPmsCount == other.fNarrowAmPmsCount &&
         fQuartersCount == other.fQuartersCount &&
         fShortQuartersCount == other.fShortQuartersCount &&
         fStandaloneQuartersCount == other.fStandaloneQuartersCount &&
@@ -547,6 +551,7 @@ DateFormatSymbols::operator==(const DateFormatSymbols& other) const
             arrayCompare(fStandaloneShorterWeekdays, other.fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount) &&
             arrayCompare(fStandaloneNarrowWeekdays, other.fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount) &&
             arrayCompare(fAmPms, other.fAmPms, fAmPmsCount) &&
+            arrayCompare(fNarrowAmPms, other.fNarrowAmPms, fNarrowAmPmsCount) &&
             fTimeSeparator == other.fTimeSeparator &&
             arrayCompare(fQuarters, other.fQuarters, fQuartersCount) &&
             arrayCompare(fShortQuarters, other.fShortQuarters, fShortQuartersCount) &&
@@ -1501,6 +1506,8 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
     fStandaloneNarrowWeekdaysCount=0;
     fAmPms = NULL;
     fAmPmsCount=0;
+    fNarrowAmPms = NULL;
+    fNarrowAmPmsCount=0;
     fTimeSeparator.setToBogus();
     fQuarters = NULL;
     fQuartersCount = 0;
@@ -1716,6 +1723,7 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
             initField(&fStandaloneShorterWeekdays, fStandaloneShorterWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
             initField(&fStandaloneNarrowWeekdays, fStandaloneNarrowWeekdaysCount, (const UChar *)gLastResortDayNames, kDayNum, kDayLen, status);
             initField(&fAmPms, fAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status);
+            initField(&fNarrowAmPms, fNarrowAmPmsCount, (const UChar *)gLastResortAmPmMarkers, kAmPmNum, kAmPmLen, status);
             initField(&fQuarters, fQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
             initField(&fShortQuarters, fShortQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
             initField(&fStandaloneQuarters, fStandaloneQuartersCount, (const UChar *)gLastResortQuarters, kQuarterNum, kQuarterLen, status);
@@ -1768,6 +1776,7 @@ DateFormatSymbols::initializeData(const Locale& locale, const char *type, UError
        }
     }
     initField(&fAmPms, fAmPmsCount, calData.getByKey(gAmPmMarkersTag, status), status);
+    initField(&fNarrowAmPms, fNarrowAmPmsCount, calData.getByKey(gAmPmMarkersNarrowTag, status), status);
 
     initField(&fQuarters, fQuartersCount, calData.getByKey2(gQuartersTag, gNamesWideTag, status), status);
     initField(&fShortQuarters, fShortQuartersCount, calData.getByKey2(gQuartersTag, gNamesAbbrTag, status), status);
index 9a7c107aeebd15bad79c2467c35df1bae8e985b2..2b309f208a3c938996e79f461320f4ebf80ac276 100644 (file)
@@ -1617,10 +1617,15 @@ SimpleDateFormat::subFormat(UnicodeString &appendTo,
         }
         break;
 
-    // for and "a" symbol, write out the whole AM/PM string
+    // for "a" symbol, write out the whole AM/PM string
     case UDAT_AM_PM_FIELD:
-        _appendSymbol(appendTo, value, fSymbols->fAmPms,
-                      fSymbols->fAmPmsCount);
+        if (count < 5) {
+            _appendSymbol(appendTo, value, fSymbols->fAmPms,
+                          fSymbols->fAmPmsCount);
+        } else {
+            _appendSymbol(appendTo, value, fSymbols->fNarrowAmPms,
+                          fSymbols->fNarrowAmPmsCount);
+        }
         break;
 
     // for ":", write out the time separator string
@@ -3022,7 +3027,24 @@ int32_t SimpleDateFormat::subParse(const UnicodeString& text, int32_t& start, UC
         break;
 
     case UDAT_AM_PM_FIELD:
-        return matchString(text, start, UCAL_AM_PM, fSymbols->fAmPms, fSymbols->fAmPmsCount, NULL, cal);
+        {
+            // optionally try both wide/abbrev and narrow forms
+            int32_t newStart = 0;
+            // try wide/abbrev
+            if( getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count < 5 ) {
+                if ((newStart = matchString(text, start, UCAL_AM_PM, fSymbols->fAmPms, fSymbols->fAmPmsCount, NULL, cal)) > 0) {
+                    return newStart;
+                }
+            }
+            // try narrow
+            if( getBooleanAttribute(UDAT_PARSE_MULTIPLE_PATTERNS_FOR_MATCH, status) || count >= 5 ) {
+                if ((newStart = matchString(text, start, UCAL_AM_PM, fSymbols->fNarrowAmPms, fSymbols->fNarrowAmPmsCount, NULL, cal)) > 0) {
+                    return newStart;
+                }
+            }
+            // no matches for given options
+            return -start;
+        }
 
     case UDAT_HOUR1_FIELD:
         // [We computed 'value' above.]
index dd920d39aa384352eeb8756acd3f6f4d0d3f5fe0..a6e90a4c1889b986adfb43c33369215edf4b30b8 100644 (file)
@@ -740,6 +740,12 @@ private:
     UnicodeString*  fAmPms;
     int32_t         fAmPmsCount;
 
+    /**
+     * Narrow Ampm strings. For example: "a" and "p".
+     */
+    UnicodeString*  fNarrowAmPms;
+    int32_t         fNarrowAmPmsCount;
+
     /**
      * Time separator string. For example: ":".
      */
index 1b2ce266c14f7302df11940ce2a9099a076464b6..ad96b5d3b5c6a67e78405b0dc36a9a963ea54dad 100644 (file)
@@ -1752,6 +1752,11 @@ void DateFormatTest::TestNarrowNames()
             "ccccc", "1970 01 01 0:00:00", "T",
             "ccccc", "1970 01 02 0:00:00", "F",
             "ccccc", "1970 01 03 0:00:00", "S",
+            
+            "h:mm a",     "2015 01 01 10:00:00", "10:00 AM",
+            "h:mm a",     "2015 01 01 22:00:00", "10:00 PM",
+            "h:mm aaaaa", "2015 01 01 10:00:00", "10:00 a",
+            "h:mm aaaaa", "2015 01 01 22:00:00", "10:00 p",
         };
 
         const char *CS_DATA[] = {
@@ -1801,10 +1806,25 @@ void DateFormatTest::TestNarrowNames()
             "ccccc", "1970 01 01 0:00:00", "\\u010C",
             "ccccc", "1970 01 02 0:00:00", "P",
             "ccccc", "1970 01 03 0:00:00", "S",
+            
+            "h:mm a",     "2015 01 01 10:00:00", "10:00 AM",
+            "h:mm a",     "2015 01 01 22:00:00", "10:00 PM",
+            "h:mm aaaaa", "2015 01 01 10:00:00", "10:00 AM",
+            "h:mm aaaaa", "2015 01 01 22:00:00", "10:00 PM",
+        };
+
+        const char *CA_DATA[] = {
+            "yyyy MM dd HH:mm:ss",
+
+            "h:mm a",     "2015 01 01 10:00:00", "10:00 a. m.",
+            "h:mm a",     "2015 01 01 22:00:00", "10:00 p. m.",
+            "h:mm aaaaa", "2015 01 01 10:00:00", "10:00 a.m.",
+            "h:mm aaaaa", "2015 01 01 22:00:00", "10:00 p.m.",
         };
 
       expectFormat(EN_DATA, ARRAY_SIZE(EN_DATA), Locale("en", "", ""));
       expectFormat(CS_DATA, ARRAY_SIZE(CS_DATA), Locale("cs", "", ""));
+      expectFormat(CA_DATA, ARRAY_SIZE(CA_DATA), Locale("ca", "", ""));
 }
 
 void DateFormatTest::TestEras()