ICU-13230 Fixing DecimalFormat parser to ignore grouping separators when there is no grouping separator in the pattern OR when setGroupingUsed(false) is explicitly called.

X-SVN-Rev: 40181
This commit is contained in:
Shane Carr 2017-06-19 21:03:07 +00:00
parent 6735aadcbc
commit 0a19183f1b
5 changed files with 61 additions and 8 deletions

View File

@ -456,6 +456,29 @@ output useGrouping
12,345 1
12345 0
test grouping used setters in parsing
set pattern #,##0
begin
locale useGrouping parse output breaks
en_US 1 123,456 123456
en_US 0 123,456 123
en_US 1 123.456 123.456
en_US 0 123.456 123.456
fr_FR 1 123,456 123.456
fr_FR 0 123,456 123.456
// JDK returns 123 here; not sure why.
fr_FR 1 123.456 123456 K
fr_FR 0 123.456 123
test no grouping in pattern with parsing
set pattern 0
begin
locale parse output breaks
en_US 123,456 123
en_US 123.456 123.456
fr_FR 123,456 123.456
fr_FR 123.456 123
test grouping setters
set locale en_US
set pattern 0

View File

@ -1095,6 +1095,7 @@ public class Parse {
if (mode == null) mode = ParseMode.LENIENT;
boolean integerOnly = properties.getParseIntegerOnly();
boolean ignoreExponent = properties.getParseNoExponent();
boolean ignoreGrouping = properties.getGroupingSize() < 0;
// Set up the initial state
ParserState state = threadLocalParseState.get().clear();
@ -1175,8 +1176,10 @@ public class Parse {
acceptPrefix(cp, StateName.AFTER_PREFIX, state, item);
}
if (mode == ParseMode.LENIENT || mode == ParseMode.FAST) {
if (!ignoreGrouping) {
acceptGrouping(cp, StateName.AFTER_INTEGER_DIGIT, state, item);
if (state.length > 0 && mode == ParseMode.FAST) break;
}
if (parseCurrency) {
acceptCurrency(cp, StateName.BEFORE_PREFIX, state, item);
}
@ -1195,7 +1198,9 @@ public class Parse {
}
if (mode == ParseMode.LENIENT || mode == ParseMode.FAST) {
acceptWhitespace(cp, StateName.AFTER_PREFIX, state, item);
if (!ignoreGrouping) {
acceptGrouping(cp, StateName.AFTER_INTEGER_DIGIT, state, item);
}
if (parseCurrency) {
acceptCurrency(cp, StateName.AFTER_PREFIX, state, item);
}
@ -1210,8 +1215,10 @@ public class Parse {
acceptDecimalPoint(cp, StateName.AFTER_FRACTION_DIGIT, state, item);
if (state.length > 0 && mode == ParseMode.FAST) break;
}
if (!ignoreGrouping) {
acceptGrouping(cp, StateName.AFTER_INTEGER_DIGIT, state, item);
if (state.length > 0 && mode == ParseMode.FAST) break;
}
acceptBidi(cp, StateName.BEFORE_SUFFIX, state, item);
if (state.length > 0 && mode == ParseMode.FAST) break;
acceptPadding(cp, StateName.BEFORE_SUFFIX, state, item);

View File

@ -456,6 +456,29 @@ output useGrouping
12,345 1
12345 0
test grouping used setters in parsing
set pattern #,##0
begin
locale useGrouping parse output breaks
en_US 1 123,456 123456
en_US 0 123,456 123
en_US 1 123.456 123.456
en_US 0 123.456 123.456
fr_FR 1 123,456 123.456
fr_FR 0 123,456 123.456
// JDK returns 123 here; not sure why.
fr_FR 1 123.456 123456 K
fr_FR 0 123.456 123
test no grouping in pattern with parsing
set pattern 0
begin
locale parse output breaks
en_US 123,456 123
en_US 123.456 123.456
fr_FR 123,456 123.456
fr_FR 123.456 123
test grouping setters
set locale en_US
set pattern 0

View File

@ -697,8 +697,8 @@ public class NumberFormatDataDrivenTest {
properties.setMaximumSignificantDigits(tuple.maxSigDigits);
}
if (tuple.useGrouping != null && tuple.useGrouping == 0) {
properties.setGroupingSize(Integer.MAX_VALUE);
properties.setSecondaryGroupingSize(Integer.MAX_VALUE);
properties.setGroupingSize(-1);
properties.setSecondaryGroupingSize(-1);
}
if (tuple.multiplier != null) {
properties.setMultiplier(new BigDecimal(tuple.multiplier));

View File

@ -4952,7 +4952,7 @@ public class NumberFormatTest extends TestFmwk {
@Test
public void Test11739() {
NumberFormat nf = NumberFormat.getCurrencyInstance(new ULocale("sr_BA"));
((DecimalFormat) nf).applyPattern("0.0 ¤¤¤");
((DecimalFormat) nf).applyPattern("#,##0.0 ¤¤¤");
ParsePosition ppos = new ParsePosition(0);
CurrencyAmount result = nf.parseCurrency("1.500 амерички долар", ppos);
assertEquals("Should parse to 1500 USD", new CurrencyAmount(1500, Currency.getInstance("USD")), result);