Reputation: 347
I'm having a really strange bug, where NumberFormat seemingly ignores the fraction digits I set. I'm using this rather simple method to format a double value representing a currency into a locale-specific String to show on screen:
public static String formatValueString(String currencyISO, double value) {
NumberFormat numberFormat = NumberFormat.getCurrencyInstance();
if (value != Math.floor(value)) {
numberFormat.setMinimumFractionDigits(2);
numberFormat.setMaximumFractionDigits(2);
} else {
numberFormat.setMinimumFractionDigits(0);
numberFormat.setMaximumFractionDigits(0);
}
numberFormat.setCurrency(java.util.Currency.getInstance(currencyISO));
String result = numberFormat.format(value);
return result;
}
It should show 2 decimal places only when needed, which according to the documentation of setCurrency should work:
Sets the currency used by this number format when formatting currency values. The min and max fraction digits remain the same.
Well.. It works most of the time. 2.0 with ISO "GBP" is correctly formated to "2 £" when the device language is set to German and "£2" when it's set to English in the US.
However 2.0 with "USD" as ISO results in "2,00 $", when set to German. All other languages and all other currencies I have tested work as intended.
I really have no idea, what I could be doing wrong for it to only not work in that one specific case. Any ideas?
Edit:
I tried this simplified version:
public static String formatValueString(String currencyISO, double value) {
NumberFormat numberFormat = NumberFormat.getCurrencyInstance();
numberFormat.setMinimumFractionDigits(0);
numberFormat.setMaximumFractionDigits(0);
numberFormat.setCurrency(java.util.Currency.getInstance(currencyISO));
String result = numberFormat.format(value);
return result;
}
Same result, still shows 2 decimal places that shouldn't be there(again, only for US-Dollar in German), the Math.floor part is definitely not the problem.
Edit 2: Doing this with screenshots now. Ignore all the commented and other unimportant stuff.
With "EUR" and 2.0 as value everything works fine and the result is "2 €"
But with "USD" and the same value the result is now "2.00 $".
In both cases the maximumFractionDigits and minimumFractionDigits are still correctly set to 0 in the numberFormat object, after the setCurrency().
So where are these decimal places coming from???
Upvotes: 3
Views: 5044
Reputation: 789
I know this is an old question, but I had the same issue today and was able to work around it. Basically, when you set the currency on a NumberFormat, it overwrites the minimum and maximum fraction digits. You can see it here in this copy of the JDK code: https://github.com/frohoff/jdk8u-dev-jdk/blob/master/src/share/classes/sun/util/locale/provider/NumberFormatProviderImpl.java#L212
Once you know this, it's pretty easy to workaround: you just set the currency before setting anything else.
public static String formatValueString(String currencyISO, double value) {
NumberFormat numberFormat = NumberFormat.getCurrencyInstance();
numberFormat.setCurrency(java.util.Currency.getInstance(currencyISO));
numberFormat.setMinimumFractionDigits(0);
numberFormat.setMaximumFractionDigits(0);
String result = numberFormat.format(value);
return result;
}
That's it. Now you should have the correct number of fractional digits.
Upvotes: 3