From: Shane Carr Date: Fri, 1 Dec 2017 23:03:52 +0000 (+0000) Subject: ICU-13492 Fixing currency fraction length fallbacks in the DecimalFormat-to-NumberFor... X-Git-Tag: release-61-rc~175 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ceca3c430c206ac8cbb4c71c6c1560665ded57f1;p=icu ICU-13492 Fixing currency fraction length fallbacks in the DecimalFormat-to-NumberFormatter mapping function. X-SVN-Rev: 40684 --- diff --git a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java index 5c6a08c0103..f1cdafe1dec 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/number/NumberPropertyMapper.java @@ -122,6 +122,21 @@ final class NumberPropertyMapper { MathContext mathContext = RoundingUtils.getMathContextOrUnlimited(properties); boolean explicitMinMaxFrac = minFrac != -1 || maxFrac != -1; boolean explicitMinMaxSig = minSig != -1 || maxSig != -1; + // Resolve min/max frac for currencies, required for the validation logic and for when minFrac or maxFrac was + // set (but not both) on a currency instance. + // NOTE: Increments are handled in "Rounder.constructCurrency()". + if (useCurrency) { + if (minFrac == -1 && maxFrac == -1) { + minFrac = currency.getDefaultFractionDigits(currencyUsage); + maxFrac = currency.getDefaultFractionDigits(currencyUsage); + } else if (minFrac == -1) { + minFrac = Math.min(maxFrac, currency.getDefaultFractionDigits(currencyUsage)); + } else if (maxFrac == -1) { + maxFrac = Math.max(minFrac, currency.getDefaultFractionDigits(currencyUsage)); + } else { + // No-op: user override for both minFrac and maxFrac + } + } // 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. 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 74290f3b0b0..c7b7282acda 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 @@ -5566,7 +5566,7 @@ public class NumberFormatTest extends TestFmwk { df.setMaximumFractionDigits(3); expect2(df, 35.0, "$35.000"); df.setMinimumFractionDigits(-1); - expect2(df, 35.0, "$35"); + expect2(df, 35.0, "$35.00"); df.setMaximumFractionDigits(-1); expect2(df, 35.0, "$35.00"); } @@ -5916,4 +5916,21 @@ public class NumberFormatTest extends TestFmwk { expect2(df, 100, "a100"); expect2(df, -100, "-a100"); } + + @Test + public void TestCurrencyRoundingMinWithoutMax() { + NumberFormat currencyFormat = DecimalFormat.getCurrencyInstance(Locale.US); + currencyFormat.setCurrency(Currency.getInstance("AUD")); + currencyFormat.setMinimumFractionDigits(0); + expect(currencyFormat, 0.001, "A$0"); + + // NOTE: The size of the increment takes precedent over minFrac since ICU 59. + // CAD-Cash uses nickel rounding. + currencyFormat = DecimalFormat.getCurrencyInstance(Locale.US); + currencyFormat.setCurrency(Currency.getInstance("CAD")); + ((DecimalFormat)currencyFormat).setCurrencyUsage(CurrencyUsage.CASH); + currencyFormat.setMinimumFractionDigits(0); + // expect(currencyFormat, 0.08, "CA$0.1"); // ICU 58 and down + expect(currencyFormat, 0.08, "CA$0.10"); // ICU 59 and up + } }