From 955e0d9319b7747bd408a1ca99b6fa790b61f4ba Mon Sep 17 00:00:00 2001 From: Shane Carr Date: Wed, 16 May 2018 01:01:22 +0000 Subject: [PATCH] ICU-11897 Changing kPatternSeparatorSymbol to be a constant ";" and not loaded from data. X-SVN-Rev: 41380 --- icu4c/source/i18n/dcfmtsym.cpp | 2 +- icu4c/source/test/intltest/numfmtst.cpp | 33 +++++++++++++---- .../numberformattestspecification.txt | 2 +- .../ibm/icu/text/DecimalFormatSymbols.java | 37 ++++++++----------- .../data/numberformattestspecification.txt | 2 +- .../icu/dev/test/format/NumberFormatTest.java | 28 ++++++++++++++ 6 files changed, 72 insertions(+), 32 deletions(-) diff --git a/icu4c/source/i18n/dcfmtsym.cpp b/icu4c/source/i18n/dcfmtsym.cpp index a2cc58c4151..5050cfe9aff 100644 --- a/icu4c/source/i18n/dcfmtsym.cpp +++ b/icu4c/source/i18n/dcfmtsym.cpp @@ -66,7 +66,7 @@ static const UChar INTL_CURRENCY_SYMBOL_STR[] = {0xa4, 0xa4, 0}; static const char *gNumberElementKeys[DecimalFormatSymbols::kFormatSymbolCount] = { "decimal", "group", - "list", + NULL, /* #11897: the symbol is NOT the pattern separator symbol */ "percentSign", NULL, /* Native zero digit is deprecated from CLDR - get it from the numbering system */ NULL, /* Pattern digit character is deprecated from CLDR - use # by default always */ diff --git a/icu4c/source/test/intltest/numfmtst.cpp b/icu4c/source/test/intltest/numfmtst.cpp index 982b261ab07..b7692192378 100644 --- a/icu4c/source/test/intltest/numfmtst.cpp +++ b/icu4c/source/test/intltest/numfmtst.cpp @@ -9285,14 +9285,31 @@ void NumberFormatTest::TestParseNaN() { void NumberFormatTest::Test11897_LocalizedPatternSeparator() { IcuTestErrorCode status(*this, "Test11897_LocalizedPatternSeparator"); - DecimalFormatSymbols dfs("en", status); - dfs.setSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol, u"!", FALSE); - DecimalFormat df(u"0", dfs, status); - df.applyPattern("a0;b0", status); // should not throw - UnicodeString result; - assertEquals("should apply the normal pattern", df.getNegativePrefix(result.remove()), "b"); - df.applyLocalizedPattern(u"c0!d0", status); // should not throw - assertEquals("should apply the localized pattern", df.getNegativePrefix(result.remove()), "d"); + // In a locale with a different symbol, like arabic, + // kPatternSeparatorSymbol should still be ';' + { + DecimalFormatSymbols dfs("ar", status); + assertEquals("pattern separator symbol should be ;", + u";", + dfs.getSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol)); + } + + // However, the custom symbol should be used in localized notation + // when set manually via API + { + DecimalFormatSymbols dfs("en", status); + dfs.setSymbol(DecimalFormatSymbols::kPatternSeparatorSymbol, u"!", FALSE); + DecimalFormat df(u"0", dfs, status); + df.applyPattern("a0;b0", status); // should not throw + UnicodeString result; + assertEquals("should apply the normal pattern", + df.getNegativePrefix(result.remove()), + "b"); + df.applyLocalizedPattern(u"c0!d0", status); // should not throw + assertEquals("should apply the localized pattern", + df.getNegativePrefix(result.remove()), + "d"); + } } void NumberFormatTest::Test13055_PercentageRounding() { diff --git a/icu4c/source/test/testdata/numberformattestspecification.txt b/icu4c/source/test/testdata/numberformattestspecification.txt index 23be52502a9..9f2ea192016 100644 --- a/icu4c/source/test/testdata/numberformattestspecification.txt +++ b/icu4c/source/test/testdata/numberformattestspecification.txt @@ -692,7 +692,7 @@ sl #.##0;#.##0− #,##0;#,##0- K // JDK does not have data for "×10^" in this locale en_SE 0,00×10^0;0,00×10^0- 0.00E0;0.00E0- K // JDK does not seem to transform the digits in localized patterns -ar_SA #\u066C##\u0660\u066B\u0660\u0660\u061Ba# #,##0.00;a#,##0.00 K +ar_SA #\u066C##\u0660\u066B\u0660\u0660;a# #,##0.00;a#,##0.00 K test toPattern set locale en diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormatSymbols.java b/icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormatSymbols.java index 07757d0b68d..6bd264b6b2c 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormatSymbols.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormatSymbols.java @@ -1272,7 +1272,6 @@ public class DecimalFormatSymbols implements Cloneable, Serializable { private static final String[] SYMBOL_KEYS = { "decimal", "group", - "list", "percentSign", "minusSign", "plusSign", @@ -1310,7 +1309,6 @@ public class DecimalFormatSymbols implements Cloneable, Serializable { private static final String[] SYMBOL_DEFAULTS = new String[] { String.valueOf(DEF_DECIMAL_SEPARATOR), // decimal String.valueOf(DEF_GROUPING_SEPARATOR), // group - ";", // list String.valueOf(DEF_PERCENT), // percentSign String.valueOf(DEF_MINUS_SIGN), // minusSign String.valueOf(DEF_PLUS_SIGN), // plusSign @@ -1381,21 +1379,18 @@ public class DecimalFormatSymbols implements Cloneable, Serializable { // Copy data from the numberElements map into instance fields setDecimalSeparatorString(numberElements[0]); setGroupingSeparatorString(numberElements[1]); - - // See CLDR #9781 - // assert numberElements[2].length() == 1; - patternSeparator = numberElements[2].charAt(0); - - setPercentString(numberElements[3]); - setMinusSignString(numberElements[4]); - setPlusSignString(numberElements[5]); - setExponentSeparator(numberElements[6]); - setPerMillString(numberElements[7]); - setInfinity(numberElements[8]); - setNaN(numberElements[9]); - setMonetaryDecimalSeparatorString(numberElements[10]); - setMonetaryGroupingSeparatorString(numberElements[11]); - setExponentMultiplicationSign(numberElements[12]); + // #11897: pattern separator is always ';', not from data + patternSeparator = ';'; + setPercentString(numberElements[2]); + setMinusSignString(numberElements[3]); + setPlusSignString(numberElements[4]); + setExponentSeparator(numberElements[5]); + setPerMillString(numberElements[6]); + setInfinity(numberElements[7]); + setNaN(numberElements[8]); + setMonetaryDecimalSeparatorString(numberElements[9]); + setMonetaryGroupingSeparatorString(numberElements[10]); + setExponentMultiplicationSign(numberElements[11]); digit = '#'; // Localized pattern character no longer in CLDR padEscape = '*'; @@ -1488,11 +1483,11 @@ public class DecimalFormatSymbols implements Cloneable, Serializable { // If monetary decimal or grouping were not explicitly set, then set them to be the same as // their non-monetary counterparts. - if (numberElements[10] == null) { - numberElements[10] = numberElements[0]; + if (numberElements[9] == null) { + numberElements[9] = numberElements[0]; } - if (numberElements[11] == null) { - numberElements[11] = numberElements[1]; + if (numberElements[10] == null) { + numberElements[10] = numberElements[1]; } return new CacheData(validLocale, digits, numberElements); diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberformattestspecification.txt b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberformattestspecification.txt index 549550742d2..74795b02d14 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberformattestspecification.txt +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/data/numberformattestspecification.txt @@ -683,7 +683,7 @@ sl #.##0;#.##0− #,##0;#,##0- K // JDK does not have data for "×10^" in this locale en_SE 0,00×10^0;0,00×10^0- 0.00E0;0.00E0- K // JDK does not seem to transform the digits in localized patterns -ar_SA #\u066C##\u0660\u066B\u0660\u0660\u061Ba# #,##0.00;a#,##0.00 K +ar_SA #\u066C##\u0660\u066B\u0660\u0660;a# #,##0.00;a#,##0.00 K test toPattern set locale en diff --git a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java index a5d2aea11c6..604f4c6d820 100644 --- a/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java +++ b/icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java @@ -5243,6 +5243,34 @@ public class NumberFormatTest extends TestFmwk { assertNotEquals("df2 != df1", df2, df1); } + @Test + public void Test11897_LocalizedPatternSeparator() { + // In a locale with a different symbol, like arabic, + // kPatternSeparatorSymbol should still be ';' + { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(new ULocale("ar")); + assertEquals("pattern separator symbol should be ;", + ';', + dfs.getPatternSeparator()); + } + + // However, the custom symbol should be used in localized notation + // when set manually via API + { + DecimalFormatSymbols dfs = new DecimalFormatSymbols(new ULocale("en")); + dfs.setPatternSeparator('!'); + DecimalFormat df = new DecimalFormat("0", dfs); + df.applyPattern("a0;b0"); // should not throw + assertEquals("should apply the normal pattern", + df.getNegativePrefix(), + "b"); + df.applyLocalizedPattern("c0!d0"); // should not throw + assertEquals("should apply the localized pattern", + df.getNegativePrefix(), + "d"); + } + } + @Test public void Test13055() { DecimalFormat df = (DecimalFormat) NumberFormat.getPercentInstance();