9
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)?

2
  • I noticed something like this If i first try and format a double like this d = 1201 String retVal = df.format(d); then try to parse this formatted value which would be retVal = 1 201 double val = df.parse(retVal).doubleValue(); this would work and will see val = 1201.0 But i already have a string in FRENCH format (1 201) and direct parsing does not work. No idea why... if you help me answer the reason. Commented Dec 8, 2015 at 13:24
  • This may help : stackoverflow.com/a/8389625/3519951 Commented Dec 8, 2015 at 13:24

4 Answers 4

11

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'!
Sign up to request clarification or add additional context in comments.

5 Comments

Great observation !!! +1 from me. It needs some keen debugging to understand this
Well this is quite logical, as you don't want your number to break on two lines just because there is a space in it! (a number without spaces would not be broken unless it occupies the full line itself)
Thank you parker. One more doubt to your explanation. Please let me know , if bellow code will help parse without changing the input char groupingSep = (decimalFormat.getDecimalFormatSymbols()).getGroupingSeparator(); if(groupingSep == '\u00A0'){ groupingSep = ' '; DecimalFormatSymbols newSymbols = decimalFormat.getDecimalFormatSymbols(); newSymbols.setGroupingSeparator(groupingSep); decimalFormat.setDecimalFormatSymbols(newSymbols); }
@AmitNag Yes that will solve your problem! But please be aware that when you get formatted strings from other sources (like another NumberFormat with locale french) that do have the NBSP as grouping char will then be read wrong by your program!
@ParkerHalo Thank you for the clarification. It was very helpful.
4

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

1 Comment

String num = "1 201"; This input could be in any Locale Format like (1 201 : 1,201 etc) So that solution is not possible in my case. Any reason why this issue ?
3

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.

2 Comments

its an interesting observation, why would someone downvote it? maybe a comment how to make it better?
mate to make your solution be an answer to the question, just note that " " should be replaced by "\u00a0"
1

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();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.