I have to show price of an item. If the price is only in dollars, it should look like an integer. But if it contains cents, it should look like double value and always have two symbols after decimal separator:
2 550$
2 550,55$
2 550,50$
I decided to use Decimal format for this task, but I don't know how to properly handle the cents.
Here is my solution:
public static String moneyFormat(double amount, String currency) {
DecimalFormatSymbols dfSymbols = new DecimalFormatSymbols();
dfSymbols.setDecimalSeparator(',');
dfSymbols.setGroupingSeparator(' ');
dfSymbols.setCurrencySymbol(currency);
DecimalFormat df;
if (isInteger(amount)) {
df = new DecimalFormat("###,###,##0 \u00A4", dfSymbols);
} else {
df = new DecimalFormat("###,###,##0.00 \u00A4", dfSymbols);
}
df.setGroupingUsed(true);
return df.format(amount);
}
private static boolean isInteger(double amount) {
return !Double.isInfinite(amount) && (amount == Math.floor(amount));
}
The amount comes from server in Double, therefore, probably, we can have some errors in case if 2$ will be represented as 1,999(9)$ but I am not sure how to test for such errors.
As an alternative to passing two patterns I can use df.setMaximumFractionDigits();
:
df = new DecimalFormat("###,###,##0.00 \u00A4", dfSymbols);
if (isInteger(amount)) {
df.setMaximumFractionDigits(0);
} else {
df.setMaximumFractionDigits(2);
}
But the question stays the same: can I handle integers in some other, cleaner way?
Update
Unfortunately, changing output from server to String or other types is not an option. And I forgot to mention, that it for Android. I don't use classes of platform, so I haven't added it to tags.
String
prefer this (In combination withBigDecimal
). An other approach isInteger
of cent. Just get rid of the double as soon as possible at your end. \$\endgroup\$