How to change the decimal separator of DecimalFormat from comma to dot/point?
Asked Answered
D

8

234

I have this little crazy method that converts BigDecimal values into nice and readable Strings.

private String formatBigDecimal(BigDecimal bd){
    DecimalFormat df = new DecimalFormat();
    df.setMinimumFractionDigits(3);
    df.setMaximumFractionDigits(3);
    df.setMinimumIntegerDigits(1);
    df.setMaximumIntegerDigits(3);
    df.setGroupingSize(20);
    return df.format(bd);
}

It however, also produces a so called grouping separator "," that makes all my values come out like this:

xxx,xxx

I do need the separator to be a dot or a point and not a comma. Does anybody have a clue of how to accomplish this little feat?

I have read this and in particular this to death now but I cannot find a way to get this done. Am I approaching this the wrong way? Is there a much more elegant way of doing this? Maybe even a solution that accounts for different local number representations, since the comma would be perfect by European standards.

Denice answered 19/2, 2011 at 23:11 Comment(2)
See also #5236556Cyprinid
Change the language, it worked for me. #4947984Karisakarissa
S
388

You can change the separator either by setting a locale or using the DecimalFormatSymbols.

If you want the grouping separator to be a point, you can use an european locale:

NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
DecimalFormat df = (DecimalFormat)nf;

Alternatively you can use the DecimalFormatSymbols class to change the symbols that appear in the formatted numbers produced by the format method. These symbols include the decimal separator, the grouping separator, the minus sign, and the percent sign, among others:

DecimalFormatSymbols otherSymbols = new DecimalFormatSymbols(currentLocale);
otherSymbols.setDecimalSeparator(',');
otherSymbols.setGroupingSeparator('.'); 
DecimalFormat df = new DecimalFormat(formatString, otherSymbols);

currentLocale can be obtained from Locale.getDefault() i.e.:

Locale currentLocale = Locale.getDefault();
Sturgeon answered 19/2, 2011 at 23:33 Comment(9)
you can use applyPattern on the decimal format to get your .00Compound
I have changed otherSymbols.setDecimalSeparator(','); as otherSymbols.setDecimalSeparator('.'); Thanks .It works for me .Diacritic
it's how the format looks like, e.g. String formatString = "#,###,###,##0.00"; see docs.oracle.com/javase/7/docs/api/java/text/DecimalFormat.html for syntaxSightread
"You can use an european locale". Well, you cannot use any locale from Europe because Locale.UK will return 1,567.90 and not 1.567,90Herr
Side note: NumberFormat.getNumberInstance() can run unusually slowly on some Android 7 devices. An alternative is String.format() which runs quickly. See https://mcmap.net/q/102515/-how-to-format-decimals-in-a-currency-formatBesom
@Chris, Can you please guide me for "###.###,00" this pattern. As by using this it gives me Malformed pattern "###.###,00" exception.Hargis
What is currentLocale and what do I need it for?Joyous
I tried your method, but it refused to work until the moment I called the df.setDecimalFormatSymbols(otherSymbols); method (thank you, Oracle documentation). Consider including that information in your answerJoyous
For NumberFormat.getCurrencyInstance you need to use setMonetaryGroupingSeparator and setMonetaryDecimalSeparatorBharal
A
16

Europe is quite huge. I'm not sure if they use the same format all over. However this or this answer will be of help.

String text = "1,234567";
NumberFormat nf_in = NumberFormat.getNumberInstance(Locale.GERMANY);
double val = nf_in.parse(text).doubleValue();

NumberFormat nf_out = NumberFormat.getNumberInstance(Locale.UK);
nf_out.setMaximumFractionDigits(3);
String output = nf_out.format(val);

I.e. use the correct locale.

Assoil answered 19/2, 2011 at 23:33 Comment(1)
Indeed sir! In the UK "£1,234.00" is to be seen, while in France "1 234,00€" is expected (group separator, decimal separator, currency symbol and currency position have changed).Sightread
E
13

This worked in my case:

DecimalFormat df2 = new DecimalFormat("#.##");           
df2.setDecimalFormatSymbols(DecimalFormatSymbols.getInstance(Locale.ENGLISH));
Ethelda answered 17/7, 2020 at 21:2 Comment(0)
S
11
public String getGermanCurrencyFormat(double value) {
    NumberFormat nf = NumberFormat.getNumberInstance(Locale.GERMAN);
    nf.setGroupingUsed(true);
    return "€ " + nf.format(value);
}
Ssm answered 15/10, 2011 at 14:28 Comment(0)
A
5

BigDecimal does not seem to respect Locale settings.

Locale.getDefault(); //returns sl_SI

Slovenian locale should have a decimal comma. Guess I had strange misconceptions regarding numbers.

a = new BigDecimal("1,2") //throws exception
a = new BigDecimal("1.2") //is ok

a.toPlainString() // returns "1.2" always

I have edited a part of my message that made no sense since it proved to be due the human error (forgot to commit data and was looking at the wrong thing).

Same as BigDecimal can be said for any Java .toString() functions. I guess that is good in some ways. Serialization for example or debugging. There is an unique string representation.

Also as others mentioned using formatters works OK. Just use formatters, same for the JSF frontend, formatters do the job properly and are aware of the locale.

Agnostic answered 26/3, 2012 at 15:18 Comment(0)
P
3
String money = output.replace(',', '.');
Pteridology answered 1/8, 2013 at 14:53 Comment(2)
Number can be in arabic format, and they uses another separator: (٫) (in hex U+066B). en.wikipedia.org/wiki/Decimal_mark#Other_numeral_systems Numbers are diferent too: en.wikipedia.org/wiki/Arabic_(Unicode_block)Dogbane
very interesting solution. so... do you offer to use this construction for each place with parsing number to string and vice versa?Breslau
S
2

This worked for me...

    double num = 10025000;
    new DecimalFormat("#,###.##");
    DecimalFormat df = (DecimalFormat) DecimalFormat.getInstance(Locale.GERMAN);
    System.out.println(df.format(num));
Shechem answered 21/12, 2020 at 9:42 Comment(0)
I
1

you could just use replace function before you return the string in the method

return df.format(bd).replace(",", ".")
Immingle answered 3/11, 2020 at 15:49 Comment(1)
What is the point to repeat already posted wrong solution?Breslau

© 2022 - 2024 — McMap. All rights reserved.