views:

55

answers:

2

I would like to format numbers of type double with a German locale in Java. However something goes wrong since the output of the following code is : 0.0

package main;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.ParseException;
import java.util.Locale;

public class Test {

    private static String decimal2Format = "000.000"; 

    public static void main(String args[]){
        DecimalFormat format = (DecimalFormat)NumberFormat.getInstance(new Locale("de"));
        double value = 0;
        try {
            format.applyPattern(decimal2Format);
            value = format.parse("0.459").doubleValue();
        } catch (ParseException e) {
            e.printStackTrace();
        }

        System.out.println(value);
    }

}

Do you have any ideas what is wrong or missing?

Thanks, atticus

+7  A: 

You're trying to parse using a pattern which will expect a comma (as it's in German) but you've given it a period ("0.459"). It looks like DecimalFormat stops parsing when it sees a character it doesn't understand. If you change it to "0,459" you'll see it parse correctly and then output "0.459". (I'm not sure whether System.out.println uses the system default locale, in which case it might print "0,459" depending on your locale.)

Note that you haven't tried to format the number at all in this code - only parse a number. If you want to format it, call format. The double itself doesn't have an associated format - it's just a number. It's not like parsing using a particular formatter returns a value which retains that format.

Here's code which will perform actual formatting of a double value:

DecimalFormat format = (DecimalFormat)NumberFormat.getInstance(new Locale("de"));
double value = 0.459;
String formatted = format.format(value);
System.out.println(formatted); // Prints "0,459"

EDIT: Okay, so it sounds like you're converting it from one format to another (from US to European, for example). That means you should probably use two different DecimalFormat objects - you could switch the locale between calls, but that sounds a bit grim to me.

I believe one way to parse and detect errors is to use the parse overload which takes a ParsePosition as well. Set the position to 0 to start with, and afterwards check that it's at the end of the string - if it isn't, that means parsing has effectively failed. I find it odd that there isn't a method which does this automatically and throws an exception, but I can't see one...

You may also want to set the parser to produce a BigDecimal instead of a double, if you're dealing with values which are more logically decimal in nature. You can do this with the setParseBigDecimal method.

Jon Skeet
Two things regarding this issue:My goal is to parse, since I get the input as a String, so in fact I need to parse and and then format it. Then in this case I think I should use both parse and format methods, am I right?One other thing with parsing is that I need it to parse a little bit different. I am using this in a validation module, so when I get a "234.a23" String then I don't want it to be "234.0" after the validation but I want a parse exception to signal that something went wrong. Do you know any class that would behave in this way, or should I implement my own validation?
Atticus
@Atticus: I've edited my answer... hope this helps.
Jon Skeet
Thanks for the answer! It helped.
Atticus
A: 

I don't think you need to do applyPattern()... try this:-

    DecimalFormat format = (DecimalFormat) NumberFormat.getInstance(Locale.GERMAN);
    double value = 0;
    try {
        value = format.parse("0.459").doubleValue();
    }
    catch (ParseException e) {
        e.printStackTrace();
    }

    System.out.println(value);
limc
I have to do applyPattern(), because I want to format the number using a particular pattern.
Atticus
Which do you want to do, (1) parse/format using a specific pattern or (1) use the default numeric formatter for a particular locale? The two aren't generally mixable.
Alan Krueger
I want to use a parse and format thing using a specific formatter. When I format I want it to be locale specific, to have support (and this is only needed to differentiate the decimal separator) for different languages.
Atticus