]> granicus.if.org Git - icu/commitdiff
ICU-20844 ICU4J, reduce restriction on minInt=minFrac=0
authorPeter Edberg <pedberg@unicode.org>
Tue, 10 Mar 2020 03:44:43 +0000 (20:44 -0700)
committerpedberg-icu <42151464+pedberg-icu@users.noreply.github.com>
Tue, 10 Mar 2020 05:31:34 +0000 (22:31 -0700)
icu4j/main/classes/core/src/com/ibm/icu/number/NumberFormatterImpl.java
icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/format/NumberFormatTest.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/number/NumberFormatterApiTest.java

index 48607c051a62cae44a50e4d926c0dfdd0f732751..a84968533dd9ae48b46ab919db010d184a18417c 100644 (file)
@@ -444,6 +444,19 @@ class NumberFormatterImpl {
 
             // Add the fraction digits
             length += writeFractionDigits(micros, quantity, string, length + index);
+
+            if (length == 0) {
+                // Force output of the digit for value 0
+                if (micros.symbols.getCodePointZero() != -1) {
+                    length += string.insertCodePoint(index,
+                            micros.symbols.getCodePointZero(),
+                            NumberFormat.Field.INTEGER);
+                } else {
+                    length += string.insert(index,
+                            micros.symbols.getDigitStringsLocal()[0],
+                            NumberFormat.Field.INTEGER);
+                }
+            }
         }
 
         return length;
index 3a5fcdcda0c6c6828df4651acf6a8e472c8cf1b3..afe9679aaaac99e64256c0bb12c24a94f182a6d7 100644 (file)
@@ -155,10 +155,8 @@ final class NumberPropertyMapper {
         }
         // Validate min/max int/frac.
         // For backwards compatibility, minimum overrides maximum if the two conflict.
-        // The following logic ensures that there is always a minimum of at least one digit.
         if (minInt == 0 && maxFrac != 0) {
-            // Force a digit after the decimal point.
-            minFrac = minFrac <= 0 ? 1 : minFrac;
+            minFrac = (minFrac < 0 || (minFrac == 0 && maxInt == 0)) ? 1 : minFrac;
             maxFrac = maxFrac < 0 ? -1 : maxFrac < minFrac ? minFrac : maxFrac;
             minInt = 0;
             maxInt = maxInt < 0 ? -1 : maxInt > RoundingUtils.MAX_INT_FRAC_SIG ? -1 : maxInt;
index e555bb6887ae0675163e81cb75d09dd523bcb8f2..42034df573c8e0c233934370e2c8388f185a2cc3 100644 (file)
@@ -4166,6 +4166,62 @@ public class NumberFormatTest extends TestFmwk {
         }
     }
 
+    @Test
+    public void TestMinIntMinFracZero() {
+        class TestMinIntMinFracItem {
+            double value;;
+            String expDecFmt;
+            String expCurFmt;
+             // Simple constructor
+            public TestMinIntMinFracItem(double valueIn, String expDecFmtIn, String expCurFmtIn) {
+                value = valueIn;
+                expDecFmt = expDecFmtIn;
+                expCurFmt = expCurFmtIn;
+            }
+        };
+
+        final TestMinIntMinFracItem[] items = {
+            //                              decFmt curFmt
+            new TestMinIntMinFracItem( 10.0, "10", "$10" ),
+            new TestMinIntMinFracItem(  0.9, ".9", "$.9" ),
+            new TestMinIntMinFracItem(  0.0, "0",  "$0"  ),
+        };
+        int minInt, minFrac;
+
+        NumberFormat decFormat = NumberFormat.getInstance(ULocale.US, NumberFormat.NUMBERSTYLE);
+        decFormat.setMinimumIntegerDigits(0);
+        decFormat.setMinimumFractionDigits(0);
+        minInt = decFormat.getMinimumIntegerDigits();
+        minFrac = decFormat.getMinimumFractionDigits();
+        if (minInt != 0 || minFrac != 0) {
+            errln("after setting DECIMAL  minInt=minFrac=0, get minInt " + minInt + ", minFrac " + minFrac);
+        }
+        String decPattern = ((DecimalFormat)decFormat).toPattern();
+        if (decPattern.length() < 3 || decPattern.indexOf("#.#")< 0) {
+            errln("after setting DECIMAL  minInt=minFrac=0, expect pattern to contain \"#.#\", but get " + decPattern);
+        }
+
+        NumberFormat curFormat = NumberFormat.getInstance(ULocale.US, NumberFormat.CURRENCYSTYLE);
+        curFormat.setMinimumIntegerDigits(0);
+        curFormat.setMinimumFractionDigits(0);
+        minInt = curFormat.getMinimumIntegerDigits();
+        minFrac = curFormat.getMinimumFractionDigits();
+        if (minInt != 0 || minFrac != 0) {
+            errln("after setting CURRENCY minInt=minFrac=0, get minInt " + minInt + ", minFrac " + minFrac);
+        }
+
+        for (TestMinIntMinFracItem item: items) {
+            String decString = decFormat.format(item.value);
+            if (!decString.equals(item.expDecFmt)) {
+                errln("format DECIMAL  value " + item.value + ", expected \"" + item.expDecFmt + "\", got \"" + decString + "\"");
+            }
+            String curString = curFormat.format(item.value);
+            if (!curString.equals(item.expCurFmt)) {
+                errln("format CURRENCY value " + item.value + ", expected \"" + item.expCurFmt + "\", got \"" + curString + "\"");
+            }
+        }
+    }
+
     @Test
     public void TestBug9936() {
         DecimalFormat numberFormat =
index 2512b1fc7aac5e56a41073baacf90e980468e8cb..54c1d98e630cc7a80708df91fb697fa8746f2cfc 100644 (file)
@@ -1737,7 +1737,7 @@ public class NumberFormatterApiTest {
                 ".8765",
                 ".08765",
                 ".008765",
-                ""); // TODO: Avoid the empty string here?
+                "0"); // see ICU-20844
 
         assertFormatDescending(
                 "Integer Width Zero Fill 3",