Amit Nag
Amit Nag

Reputation: 93

Java Decimal Format parsing issue

public class NumFormatTest
{
    public static void main(String[] args) throws ParseException 
    {
        String num = "1 201";
        DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.FRANCE);
        System.out.println("Number Before parse: "+num);        
        double  dm = df.parse(num).doubleValue();
        System.out.println("Number After parse: "+dm);  
    }
}

Output:

 Number Before parse: 1 201

 Number After parse: 1.0

Expected Output:

  Number Before parse: 1 201

  Number After parse: **1201**

Can any please help me understand why parse is not able to convert a FRENCH locale formatted string (1 201) to normal double value (1201.0)?

Upvotes: 9

Views: 3993

Answers (4)

ParkerHalo
ParkerHalo

Reputation: 4430

There are two kinds of spaces. The "normal" space character (No. 32 - HEX 0x20) and the non-breaking space (NBSP) (No. 160 - HEX 0xA0).

The French locale expects the whitespace character between the digits to be the non breaking space! You can help yourself with this line of code:

String num = "1 201";
num = num.replaceAll(" ", "\u00A0");    // '\u00A0' is the non breaking whitespace character!

This way your code will work like expected. Please note that if you format a double into a String with French locale the resulting whitespace character will be the NBSP too!!!

DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.FRENCH);
System.out.println(df.format(1201.1));
// This will print "1 202,1" But the space character will be '\u00A0'!

Upvotes: 11

ashiquzzaman33
ashiquzzaman33

Reputation: 5741

You can use

 String num = "1 201";
 DecimalFormat df = (DecimalFormat) NumberFormat.getNumberInstance(Locale.FRANCE);
 System.out.println("Number Before parse: "+num);   

 DecimalFormatSymbols symbols = df.getDecimalFormatSymbols();
 symbols.setGroupingSeparator(' ');
 df.setDecimalFormatSymbols(symbols);

 double  dm = df.parse(num).doubleValue();
 System.out.println("Number After parse: "+dm);  

Expected Output:

Number Before parse: 1 201
Number After parse:  1201.0

Upvotes: 4

why_vincent
why_vincent

Reputation: 2262

This seems to work.

public double parse(String decimalAsText) {
    NumberFormat decimalFormat = NumberFormat.getNumberInstance(Locale.FRANCE);
    decimalAsText = decimalAsText.replace(' ', '\u00a0');
    ParsePosition pp = new ParsePosition(0);
    Number n = decimalFormat.parse(decimalAsText, pp);
    return n.doubleValue();
}

Upvotes: 1

AlexRNL
AlexRNL

Reputation: 148

Actually, Java is using the character unbreakable space (\u00a0) to parse French numbers.

Thus, the following code actually works:

String num = "1\u00a0201";
double dm = df.parse(num).doubleValue();
System.out.println("Number After parse: " + dm);

See @ParkerHalo answer which provide more details.

Upvotes: 3

Related Questions