From: Peter Edberg Date: Tue, 12 Jul 2011 06:58:44 +0000 (+0000) Subject: ICU-8583 J, Only parse arbitrary currency for calls that can return the found currenc... X-Git-Tag: milestone-59-0-1~4660 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=3803ce751db03872ff6c5fec9143e598073316a9;p=icu ICU-8583 J, Only parse arbitrary currency for calls that can return the found currency (e.g. parseCurrency) X-SVN-Rev: 30315 --- diff --git a/icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java b/icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java index 2e56bb67739..659a208247c 100644 --- a/icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java +++ b/icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java @@ -2691,6 +2691,15 @@ public class DecimalFormat extends NumberFormat { if (iso != null) { if (currency != null) { currency[0] = Currency.getInstance(iso); + } else { + // The formatter is currency-style but the client has not requested + // the value of the parsed currency. In this case, if that value does + // not match the formatter's current value, then the parse fails. + Currency effectiveCurr = getEffectiveCurrency(); + if (iso.compareTo(effectiveCurr.getCurrencyCode()) != 0) { + pos = -1; + continue; + } } pos = ppos.getIndex(); } else { 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 3e6f7fc662d..e1084ccefcd 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 @@ -579,6 +579,101 @@ public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk { } } + public void TestParseCurrency() { + class ParseCurrencyItem { + private String localeString; + private String descrip; + private String currStr; + private int numExpectPos; + private int numExpectVal; + private int curExpectPos; + private int curExpectVal; + private String curExpectCurr; + + ParseCurrencyItem(String locStr, String desc, String curr, int numExPos, int numExVal, int curExPos, int curExVal, String curExCurr) { + localeString = locStr; + descrip = desc; + currStr = curr; + numExpectPos = numExPos; + numExpectVal = numExVal; + curExpectPos = curExPos; + curExpectVal = curExVal; + curExpectCurr = curExCurr; + } + public String getLocaleString() { return localeString; } + public String getDescrip() { return descrip; } + public String getCurrStr() { return currStr; } + public int getNumExpectPos() { return numExpectPos; } + public int getNumExpectVal() { return numExpectVal; } + public int getCurExpectPos() { return curExpectPos; } + public int getCurExpectVal() { return curExpectVal; } + public String getCurExpectCurr() { return curExpectCurr; } + } + final ParseCurrencyItem[] parseCurrencyItems = { + new ParseCurrencyItem( "en_US", "dollars2", "$2.00", 5, 2, 5, 2, "USD" ), + new ParseCurrencyItem( "en_US", "dollars4", "$4", 2, 4, 2, 4, "USD" ), + new ParseCurrencyItem( "en_US", "dollars9", "9\u00A0$", 0, 0, 0, 0, "" ), + new ParseCurrencyItem( "en_US", "pounds3", "\u00A33.00", 0, 0, 5, 3, "GBP" ), + new ParseCurrencyItem( "en_US", "pounds5", "\u00A35", 0, 0, 2, 5, "GBP" ), + new ParseCurrencyItem( "en_US", "pounds7", "7\u00A0\u00A3", 0, 0, 0, 0, "" ), + new ParseCurrencyItem( "en_US", "euros8", "\u20AC8", 0, 0, 2, 8, "EUR" ), + + new ParseCurrencyItem( "en_GB", "pounds3", "\u00A33.00", 5, 3, 5, 3, "GBP" ), + new ParseCurrencyItem( "en_GB", "pounds5", "\u00A35", 2, 5, 2, 5, "GBP" ), + new ParseCurrencyItem( "en_GB", "pounds7", "7\u00A0\u00A3", 0, 0, 0, 0, "" ), + new ParseCurrencyItem( "en_GB", "euros4", "4,00\u00A0\u20AC", 0, 0, 0, 0, "" ), + new ParseCurrencyItem( "en_GB", "euros6", "6\u00A0\u20AC", 0, 0, 0, 0, "" ), + new ParseCurrencyItem( "en_GB", "euros8", "\u20AC8", 0, 0, 2, 8, "EUR" ), + new ParseCurrencyItem( "en_GB", "dollars4", "$4", 0, 0, 2, 4, "USD" ), + + new ParseCurrencyItem( "fr_FR", "euros4", "4,00\u00A0\u20AC", 6, 4, 6, 4, "EUR" ), + new ParseCurrencyItem( "fr_FR", "euros6", "6\u00A0\u20AC", 3, 6, 3, 6, "EUR" ), + new ParseCurrencyItem( "fr_FR", "euros8", "\u20AC8", 0, 0, 0, 0, "" ), + new ParseCurrencyItem( "fr_FR", "dollars2", "$2.00", 0, 0, 0, 0, "" ), + new ParseCurrencyItem( "fr_FR", "dollars4", "$4", 0, 0, 0, 0, "" ), + }; + for (ParseCurrencyItem item: parseCurrencyItems) { + String localeString = item.getLocaleString(); + ULocale uloc = new ULocale(localeString); + NumberFormat fmt = null; + try { + fmt = NumberFormat.getCurrencyInstance(uloc); + } catch (Exception e) { + errln("NumberFormat.getCurrencyInstance fails for locale " + localeString); + continue; + } + String currStr = item.getCurrStr(); + ParsePosition parsePos = new ParsePosition(0); + + Number numVal = fmt.parse(currStr, parsePos); + if ( parsePos.getIndex() != item.getNumExpectPos() || (numVal != null && numVal.intValue() != item.getNumExpectVal()) ) { + if (numVal != null) { + errln("NumberFormat.getCurrencyInstance parse " + localeString + "/" + item.getDescrip() + + ", expect pos/val " + item.getNumExpectPos() + "/" + item.getNumExpectVal() + + ", get " + parsePos.getIndex() + "/" + numVal.intValue() ); + } else { + errln("NumberFormat.getCurrencyInstance parse " + localeString + "/" + item.getDescrip() + + ", expect pos/val " + item.getNumExpectPos() + "/" + item.getNumExpectVal() + + ", get " + parsePos.getIndex() + "/(NULL)" ); + } + } + + parsePos.setIndex(0); + CurrencyAmount currAmt = fmt.parseCurrency(currStr, parsePos); + if ( parsePos.getIndex() != item.getCurExpectPos() || (currAmt != null && (currAmt.getNumber().intValue() != item.getCurExpectVal() || + currAmt.getCurrency().getCurrencyCode().compareTo(item.getCurExpectCurr()) != 0)) ) { + if (currAmt != null) { + errln("NumberFormat.getCurrencyInstance parseCurrency " + localeString + "/" + item.getDescrip() + + ", expect pos/val/curr " + item.getCurExpectPos() + "/" + item.getCurExpectVal() + "/" + item.getCurExpectCurr() + + ", get " + parsePos.getIndex() + "/" + currAmt.getNumber().intValue() + "/" + currAmt.getCurrency().getCurrencyCode() ); + } else { + errln("NumberFormat.getCurrencyInstance parseCurrency " + localeString + "/" + item.getDescrip() + + ", expect pos/val/curr " + item.getCurExpectPos() + "/" + item.getCurExpectVal() + "/" + item.getCurExpectCurr() + + ", get " + parsePos.getIndex() + "/(NULL)" ); + } + } + } + } /** * Test the Currency object handling, new as of ICU 2.2.