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?

有帮助吗?

解决方案

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.

其他提示

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top