32

How do I get NumberFormat.getCurrencyInstance() to print negative USD currency values with a minus sign?

Žygimantas
  • 725
  • 3
  • 7
  • 13

7 Answers7

44

It requires a little tweaking of the DecimalFormat returned by NumberFormat.getCurrencyInstance() to do it in a locale-independent manner. Here's what I did (tested on Android):

DecimalFormat formatter = (DecimalFormat)NumberFormat.getCurrencyInstance();
String symbol = formatter.getCurrency().getSymbol();
formatter.setNegativePrefix(symbol+"-"); // or "-"+symbol if that's what you need
formatter.setNegativeSuffix("");

IIRC, Currency.getSymbol() may not return a value for all locales for all systems, but it should work for the major ones (and I think it has a reasonable fallback on its own, so you shouldn't have to do anything)

ageektrapped
  • 14,482
  • 7
  • 57
  • 72
27

Here is one I always end up using either in a java class or via the fmt:formatNumber jstl tag:

DecimalFormat format = new DecimalFormat("$#,##0.00;$-#,##0.00");
String formatted = format.format(15.5);

It always produces at least a $0.00 and is consistent when displayed. Also includes thousands seperators where needed. You can move the minus sign in front of the dollar sign if that is your requirement.

Gennadiy
  • 17,657
  • 4
  • 26
  • 21
2

It's probably best to create your own DecimalFormat if you want a specific format rather than relying on the default.

Edit: You could probably also cast the result of NumberFormat.getCurrencyInstance() to DecimalFormat and adjust it to your preferences.

Michael Borgwardt
  • 342,105
  • 78
  • 482
  • 720
  • Probably you are right, but my application should be able to format currency in may locales. Wouldn't it be too hard to implement formating for all those locales? – Žygimantas Jan 13 '10 at 12:16
2

Try:

NumberFormat.getCurrencyInstance(Locale.CANADA);

E-dou
  • 101
  • 3
0
NumberFormat.getCurrencyInstance(Locale.UK);
skrrgwasme
  • 9,358
  • 11
  • 54
  • 84
Pnemonic
  • 1,685
  • 17
  • 17
0

Since I faced this problem again, I did some research and found a more resilient solution provided by the ICU:

NumberFormatter
  .withLocale(...)
  .unit(Currency.getInstance("USD"))
  .sign(SignDisplay.AUTO) // "123", "0", and "-123"
  .format(123)
  .toString();

Check the API documentation of NumberFormatter for more details.

Žygimantas
  • 725
  • 3
  • 7
  • 13
0

Why poi REFUSES to support the FIRST option in excel currency formatting is beyond me! enter image description here

I don't like using the DecimalFormat for currency because your end cell value becomes a non-numeric with the introduction of the currency symbol. While working for a major financial institution, I was tasked with resolving this formatting issue. The core idea of this change is, because POI refuses to be reasonable and have comprehensive support of Excel's native options, I will infiltrate their code and change their values at the core. The following is my WORKAROUND:

private static final String CURRENCY_FORMAT_OVERRIDE = "\"$\"#,##0.00_);-\"$\"#,##0.00";
private static final String CURRENCY_FORMAT_TARGET = "\"$\"#,##0.00_);(\"$\"#,##0.00)";    

static { // static class level initializer
    Field field = org.apache.poi.ss.usermodel.BuiltinFormats.class.getDeclaredField("_formats");            
    field.setAccessible(true);
    String[] _formats = (String[])field.get(new org.apache.poi.ss.usermodel.BuiltinFormats());
    for(int i = 0; i < _formats.length; ++i) {
        if(_formats[i].equals(CURRENCY_FORMAT_TARGET)) {
            _formats[i]=CURRENCY_FORMAT_OVERRIDE;
            System.out.println("TAKE THAT, POI!!!");
        }
    }
}
rheaghen
  • 31
  • 5