7

I've used DecimalFormat df = new DecimalFormat("#,###.00"); to format a BigDecimal.

Now, I want to use that formatted value (say it is '1 250,00') to create new BigDecimal. I've tried this:

BigDecimal result = new BigDecimal(model.getValue().replace(",",".").replace(" ",""));

But that space between 1 and 2 in 1 250.00 is not replaced. How can I fix it?

Example:

DecimalFormat df = new DecimalFormat("#,###.00");
BigDecimal example = new BigDecimal("1250");
String str = df.format(example);
System.out.println(str.replace(",",".").replace(" ",""));
Tunaki
  • 132,869
  • 46
  • 340
  • 423
rakamakafo
  • 1,144
  • 5
  • 21
  • 44
  • 2
    You may have a different kind of whitespace. Try with `replaceAll("\\s+", "")` instead. – Mena Sep 03 '15 at 11:35
  • Tried your code, for `String s ="1 250,00"` it works fine. So problem isn't with replace method – SacJn Sep 03 '15 at 11:41
  • @Tunaki, I've put an example. Try it. My localization is Moscow/Russia, if it helps. output - 1 250. 00 – rakamakafo Sep 03 '15 at 11:41

4 Answers4

7

DecimalFormat Javadoc specifies that the symbol , is the grouping separator. By default, for your locale, this separator is not a space but a non-breaking space. This can be shown by the following code:

DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.forLanguageTag("ru-RU"));
System.out.println((int) symbols.getGroupingSeparator());

You will see that the int printed is 160, which corresponds to "Non-breaking space" in ISO-8859-1.

To remove that character, we can use its Unicode representation and replace that:

DecimalFormat df = new DecimalFormat("#,###.00");
String str = df.format(new BigDecimal("1250"));
System.out.println(str.replace(",", ".").replace("\u00A0", ""));

For a more general solution, not depending on the current locale, we could retrieve the grouping separator and use that directly:

DecimalFormat df = new DecimalFormat("#,###.00");
String groupingSeparator = String.valueOf(df.getDecimalFormatSymbols().getGroupingSeparator());
String str = df.format(new BigDecimal("1250"));
System.out.println(str.replace(",", ".").replace(groupingSeparator, ""));
Tunaki
  • 132,869
  • 46
  • 340
  • 423
7

You can set grouping separator (e.g. thousand separator) character in your pattern by using DecimalFormatSymbols. It looks that in your locale it is non-breaking space so try to set it to normal space like

DecimalFormatSymbols symbols = new DecimalFormatSymbols(Locale.getDefault());
symbols.setGroupingSeparator(' ');//simple space

DecimalFormat df = new DecimalFormat("#,###.00", symbols);

BigDecimal example = new BigDecimal("1250");
String str = df.format(example);

Now your formatter will use simple space so you will be able to replace it with your code

System.out.println(str.replace(",", ".").replaceAll(" ", ""));

Output: 1250.00.

Pshemo
  • 122,468
  • 25
  • 185
  • 269
2

You can use the parse method from your DecimalFormat object.

df.setParseBigDecimal(true);    
BigDecimal bigDecimal = (BigDecimal) df.parse(model.getValue());

Take a look at the selected answer in this SO question.

Community
  • 1
  • 1
Milan Milanov
  • 412
  • 1
  • 8
  • 27
  • `df.parse(str)` may return other type than `BigInteger` for instance it can return `Long`. You may want to change your solution to something like `new BigDecimal(df.parse(model.getValue()).toString());` – Pshemo Sep 03 '15 at 12:20
  • If the number is formatted and parsed with the same `DecimalFormat` object, it should work. – Milan Milanov Sep 03 '15 at 12:27
  • Not necessarily. `df.parse(df.format(BigDecimal.ONE)).getClass()` returns `class java.lang.Long` to me. – Pshemo Sep 03 '15 at 12:30
  • Actually now I see that your original solution was better because it can avoiding loss of precision in case of double values. All you need to add is `df.setParseBigDecimal(true);` to ensure that all `df.parse` calls will return `BigDecimal`. – Pshemo Sep 03 '15 at 12:39
  • It is also mentioned in the SO question I linked to, but thanks for explicitly pointing it out (even to me). – Milan Milanov Sep 03 '15 at 12:41
2

In your format

new DecimalFormat("#,###.00"); 

the symbol , is meant for grouping separator. After removing the symbol , from your format you get the output 1250.00 (without grouping separator in your case space).

DecimalFormat df = new DecimalFormat("####.00");
BigDecimal example = new BigDecimal("1250");
String str = df.format(example);
System.out.println(str.replace(",",".").replace(" ",""));

Output: 1250.00

There is alternative (2nd) solution and it works without altering your format "#,###.00". Use .setGroupingSize(0) from DecimalFormat:

DecimalFormat df = new DecimalFormat("#,###.00");
df.setGroupingSize(0);
BigDecimal example = new BigDecimal("1250");
String str = df.format(example);
System.out.println(str);

Output: 1250.00