Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java.text.MessageFormat increase decimal places precision for BigDecimal / Number

I am using java.text.MessageFormatto replace place holders in a template that displays price per unit. Following is the piece of code that does it.

public String format(Object[] arguments, String pattern) {
    MessageFormat formatter = new MessageFormat("");
    formatter.applyPattern(pattern);
    return formatter.format(arguments);
}

pattern is

{0} {1} per {2}

and arguments are

argument[0] = "USD", argument[1] = BigDecimal(0.0002), argument[2] = "shirt"

I expected the formatter to output

"USD 0.0002 per shirt"

But formatter is reducing the precision and produces

"USD 0 per shirt"

It looks like MessageFormat is considering just 3 digits after the decimal point. "BigDecimal(0.01)" works as expected.

So is there any property I can tweak to tell the MessageFormat it should use a certain precision? Changing the pattern is not an option for me.

I can convert the argument to String from BigDecimal before formatting. But that will be my last option.

EDIT: The limit of 3 decimal points comes from NumberFormat.

private int    maximumFractionDigits = 3; 

is there a way we can change this value and make MessageFormat use this?

like image 344
Arun Gowda Avatar asked Nov 17 '25 11:11

Arun Gowda


1 Answers

You can use formats such as {0,number,#.##} in the pattern. The Javadoc of MessageFormat has more details if you're interested.

Since you cannot change the pattern, converting the objects to string before-hand would be the only solution though

EDIT: actually I did not realize that the formats could be set programmatically:

public static void main(String[] args) {
    Object[] argument = new Object[3];
    argument[0] = "USD";
    argument[1] = new BigDecimal(0.0002);
    argument[2] = "shirt";

    System.out.println(format(argument, "{0} {1} per {2}"));
}

public static String format(Object[] arguments, String pattern) {
    MessageFormat formatter = new MessageFormat(pattern);

    NumberFormat nf = NumberFormat.getNumberInstance();
    nf.setMaximumFractionDigits(7);

    for (int i = 0; i < arguments.length; i++) {
        if (arguments[i] instanceof BigDecimal) {
            formatter.setFormat(i, nf);
        }
    }

    return formatter.format(arguments);
}

This should print: USD 0.0002 per shirt

like image 111
Guillaume Avatar answered Nov 19 '25 01:11

Guillaume



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!