ICU-11805 DecimalFormat missing negative sign in US locale formatToCharacterIterator

X-SVN-Rev: 37925
This commit is contained in:
Craig Cornelius 2015-09-09 20:52:52 +00:00
parent b574c33a88
commit 266f4e8b67
3 changed files with 97 additions and 25 deletions

View file

@ -4184,6 +4184,7 @@ public class DecimalFormat extends NumberFormat {
s = intl ? symbols.getInternationalCurrencySymbol() :
symbols.getCurrencySymbol();
}
// Here is where FieldPosition could be set for CURRENCY PLURAL.
buffer.append(s);
continue;
case PATTERN_PERCENT:
@ -4238,14 +4239,33 @@ public class DecimalFormat extends NumberFormat {
}
// [Spark/CDL] Invoke formatAffix2Attribute to add attributes for affix
if (parseAttr) {
// Updates for Ticket 11805.
int offset = affix.indexOf(symbols.getCurrencySymbol());
if (-1 == offset) {
offset = affix.indexOf(symbols.getPercent());
if (-1 == offset) {
offset = 0;
}
if (offset > -1) {
formatAffix2Attribute(isPrefix, Field.CURRENCY, buf, offset,
symbols.getCurrencySymbol().length());
}
offset = affix.indexOf(symbols.getMinusString());
if (offset > -1) {
formatAffix2Attribute(isPrefix, Field.SIGN, buf, offset,
symbols.getMinusString().length());
}
// TODO: Consider if Percent and Permille can be more than one character.
offset = affix.indexOf(symbols.getPercent());
if (offset > -1) {
formatAffix2Attribute(isPrefix, Field.PERCENT, buf, offset,
1);
}
offset = affix.indexOf(symbols.getPerMill());
if (offset > -1) {
formatAffix2Attribute(isPrefix, Field.PERMILLE, buf, offset,
1);
}
offset = pattern.indexOf("¤¤¤");
if (offset > -1) {
formatAffix2Attribute(isPrefix, Field.CURRENCY, buf, offset,
affix.length() - offset);
}
formatAffix2Attribute(affix, buf.length() + offset, buf.length() + affix.length());
}
// If kCurrencySymbol or kIntlCurrencySymbol is in the affix, check for currency symbol.
@ -4279,23 +4299,16 @@ public class DecimalFormat extends NumberFormat {
return affix.length();
}
/**
* [Spark/CDL] This is a newly added method, used to add attributes for prefix and
* suffix.
*/
private void formatAffix2Attribute(String affix, int begin, int end) {
// [Spark/CDL] It is the invoker's responsibility to ensure that, before the
// invocation of this method, attributes is not null. if( attributes == null )
// return;
if (affix.indexOf(symbols.getCurrencySymbol()) > -1) {
addAttribute(Field.CURRENCY, begin, end);
} else if (affix.indexOf(symbols.getMinusSign()) > -1) {
addAttribute(Field.SIGN, begin, end);
} else if (affix.indexOf(symbols.getPercent()) > -1) {
addAttribute(Field.PERCENT, begin, end);
} else if (affix.indexOf(symbols.getPerMill()) > -1) {
addAttribute(Field.PERMILLE, begin, end);
// Fix for prefix and suffix in Ticket 11805.
private void formatAffix2Attribute(boolean isPrefix, Field fieldType,
StringBuffer buf, int offset, int symbolSize) {
int begin;
begin = offset;
if (!isPrefix) {
begin += buf.length();
}
addAttribute(fieldType, begin, begin + symbolSize);
}
/**

View file

@ -1,6 +1,6 @@
/*
*******************************************************************************
* Copyright (C) 2001-2010, International Business Machines Corporation and *
* Copyright (C) 2001-2015, International Business Machines Corporation and *
* others. All Rights Reserved. *
*******************************************************************************
*/
@ -311,7 +311,7 @@ public class IntlTestDecimalFormatAPIC extends com.ibm.icu.dev.test.TestFmwk {
t_Format(8, negativeNumber, NumberFormat.getCurrencyInstance(us),
getNegativeCurrencyVectorUS());
// test multiple grouping seperators
// test multiple grouping separators
number = new Long(100300400);
t_Format(11, number, NumberFormat.getNumberInstance(us),
getNumberVector2US());
@ -356,6 +356,8 @@ public class IntlTestDecimalFormatAPIC extends com.ibm.icu.dev.test.TestFmwk {
private static List<FieldContainer> getNegativeCurrencyVectorUS() {
List<FieldContainer> v = new ArrayList<FieldContainer>(4);
// SIGN added with fix for issue 11805.
v.add(new FieldContainer(0, 1, NumberFormat.Field.SIGN));
v.add(new FieldContainer(1, 2, NumberFormat.Field.CURRENCY));
v.add(new FieldContainer(2, 5, NumberFormat.Field.INTEGER));
v.add(new FieldContainer(5, 6, NumberFormat.Field.DECIMAL_SEPARATOR));

View file

@ -4251,11 +4251,68 @@ public class NumberFormatTest extends com.ibm.icu.dev.test.TestFmwk {
errln("decfmt.toPattern results wrong, expected \u200B$100.00, got " + currFmtResult);
}
}
public void TestNumberFormatTestTupleToString() {
new NumberFormatTestTuple().toString();
}
// Testing for Issue 11805.
public void TestFormatToCharacterIteratorIssue11805 () {
final double number = -350.76;
DecimalFormat dfUS = (DecimalFormat) DecimalFormat.getCurrencyInstance(Locale.US);
String strUS = dfUS.format(number);
Set<AttributedCharacterIterator.Attribute> resultUS = dfUS.formatToCharacterIterator(number).getAllAttributeKeys();
assertEquals("Negative US Results: " + strUS, 5, resultUS.size());
// For each test, add assert that all the fields are present and in the right spot.
// TODO: Add tests for identify and position of each field, as in IntlTestDecimalFormatAPIC.
DecimalFormat dfDE = (DecimalFormat) DecimalFormat.getCurrencyInstance(Locale.GERMANY);
String strDE = dfDE.format(number);
Set<AttributedCharacterIterator.Attribute> resultDE = dfDE.formatToCharacterIterator(number).getAllAttributeKeys();
assertEquals("Negative DE Results: " + strDE, 5, resultDE.size());
DecimalFormat dfIN = (DecimalFormat) DecimalFormat.getCurrencyInstance(new Locale("hi", "in"));
String strIN = dfIN.format(number);
Set<AttributedCharacterIterator.Attribute> resultIN = dfIN.formatToCharacterIterator(number).getAllAttributeKeys();
assertEquals("Negative IN Results: " + strIN, 5, resultIN.size());
DecimalFormat dfJP = (DecimalFormat) DecimalFormat.getCurrencyInstance(Locale.JAPAN);
String strJP = dfJP.format(number);
Set<AttributedCharacterIterator.Attribute> resultJP = dfJP.formatToCharacterIterator(number).getAllAttributeKeys();
assertEquals("Negative JA Results: " + strJP, 3, resultJP.size());
DecimalFormat dfGB = (DecimalFormat) DecimalFormat.getCurrencyInstance(new Locale("en", "gb"));
String strGB = dfGB.format(number);
Set<AttributedCharacterIterator.Attribute> resultGB = dfGB.formatToCharacterIterator(number).getAllAttributeKeys();
assertEquals("Negative GB Results: " + strGB , 5, resultGB.size());
DecimalFormat dfPlural = (DecimalFormat) NumberFormat.getInstance(new Locale("en", "gb"),
NumberFormat.PLURALCURRENCYSTYLE);
strGB = dfPlural.format(number);
resultGB = dfPlural.formatToCharacterIterator(number).getAllAttributeKeys();
assertEquals("Negative GB Results: " + strGB , 5, resultGB.size());
strGB = dfPlural.format(1);
resultGB = dfPlural.formatToCharacterIterator(1).getAllAttributeKeys();
assertEquals("Negative GB Results: " + strGB , 4, resultGB.size());
// Test output with unit value.
DecimalFormat auPlural = (DecimalFormat) NumberFormat.getInstance(new Locale("en", "au"),
NumberFormat.PLURALCURRENCYSTYLE);
String strAU = auPlural.format(1L);
Set<AttributedCharacterIterator.Attribute> resultAU =
auPlural.formatToCharacterIterator(1L).getAllAttributeKeys();
assertEquals("Unit AU Result: " + strAU , 4, resultAU.size());
// Verify Permille fields.
DecimalFormatSymbols sym = new DecimalFormatSymbols(new Locale("en", "gb"));
DecimalFormat dfPermille = new DecimalFormat("####0.##\u2030", sym);
strGB = dfPermille.format(number);
resultGB = dfPermille.formatToCharacterIterator(number).getAllAttributeKeys();
assertEquals("Negative GB Permille Results: " + strGB , 3, resultGB.size());
}
// Testing for Issue 11808.
public void TestRoundUnnecessarytIssue11808 () {
DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance();