问题
I am using java.text.NumberFormat
to parse String currency which has currency symbol. It is working for some cases while fails for other.
NumberFormat.getCurrencyInstance(Locale.FRANCE).parse("1 599,99 €"); //fails
NumberFormat.getCurrencyInstance(Locale.FRANCE).parse("599,99 €"); //works fine
Can somebody please explain why it is not working in first case? Is Joda-Money a better library for such type of parsing?
回答1:
The reason that this might not work for you, is usage of invalid white space character.
The format class expect the char with code 160 witch is describe as "Non-breaking space", when you may pass the code 30 witch is "Space".
You can run this code to check it.
NumberFormat currencyInstance = NumberFormat.getCurrencyInstance(Locale.FRANCE);
String france = "1 599,99 €";
String format = currencyInstance.format(1599.99);
Number number = currencyInstance.parse(format);
System.out.println("France: " + format);
System.out.println("Format: " + format);
System.out.println("Number: " + number);
if(france.equals(format)) {
number = currencyInstance.parse(france); // Must work;
System.out.println(number);
} else {
char[] fr = france.toCharArray();
char[] ft = format.toCharArray();
for(int i = 0; i < fr.length; i++) {
if(fr[i] != ft[i]) {
System.out.printf("The value on position %d are not equal. France: %d; Format: %d", i,(int)fr[i], (int)ft[i]);
}
}
}
Then environment details:
java version "1.7.0_17"
Java(TM) SE Runtime Environment (build 1.7.0_17-b02)
Java HotSpot(TM) 64-Bit Server VM (build 23.7-b01, mixed mode)
OS: Windows 7 64-bits.
ASCII table
NOTE:
As @Black Panter added this is known bug
JDK-4510618 : [Fmt-Nu] French thousands separator is non-breaking space
WORK AROUND
(1) Remove user's grouping separator (i.e. U+0020) in a String to be parsed.
(2) Replace user's grouping separator with the formatter's grouping seperator (U+00A0) if it's inconvenient to remove all spaces.
回答2:
it is because of the space in your number 1 599
, it will throw a ParseException
Remove the space and it will work like a charm
But it is not supposed to throw an exception, as the document states
Returns a Long if possible (e.g., within the range [Long.MIN_VALUE, Long.MAX_VALUE] and with no decimals), otherwise a Double. If IntegerOnly is set, will stop at a decimal point (or equivalent; e.g., for rational numbers "1 2/3", will stop after the 1). Does not throw an exception; if no object can be parsed, index is unchanged!
I just found this Link states about a bug relating to this.
来源:https://stackoverflow.com/questions/19488923/parse-currency-with-symbol-not-all-case-working-java