therefromhere therefromhere - 1 year ago 125
PHP Question

How do I get NumberFormatter to print negative currency values with a minus sign?

I'm using the PHP NumberFormatter class to print currency values.


$cFormatter = new NumberFormatter('en_US', NumberFormatter::CURRENCY);
$cFormatter->formatCurrency(123, 'USD');
$cFormatter->formatCurrency(123, 'BRL');
$cFormatter->formatCurrency(123, 'GBP');

That works fine, and returns
" respectively as expected.

But negative numbers are printed "accountancy style", surrounded by brackets, instead of a leading minus "-".


$cFormatter->formatCurrency(-456, 'USD');

, whereas I want
. Surely there's a simple way of doing this?

I can remove the brackets by override the prefix and postfix as follows:

$cFormatter->setTextAttribute(NumberFormatter::NEGATIVE_PREFIX, "-");
$cFormatter->setTextAttribute(NumberFormatter::NEGATIVE_SUFFIX, "");

But then I get no currency symbol eg

Is there some escape code for the currency symbol that I need to use when setting the NEGATIVE_PREFIX attribute?

Edit: I'm happy to set a different locale if that gives me the result I'm looking for.

Edit 2: Looking at the Intl library docs (which is the library used to implement NumberFormatter), the following looked promising:

¤ (\u00A4) : Prefix or suffix : No Currency sign, replaced by currency symbol. If doubled, replaced by international currency symbol. If tripled, replaced by currency plural names, for example, "US dollar" or "US dollars" for America. If present in a pattern, the monetary decimal separator is used instead of the decimal separator.

But this:

$cFormatter->setTextAttribute(NumberFormatter::NEGATIVE_PREFIX, "-¤");

Just prints "-¤123", so no joy.

Edit 3: I think I found the answer, see below.

Answer Source

I've found a slightly less hacky way to bend the en_US locale behaviour to what I'm looking for - the getPattern() / setPattern() functions.

$cFormatter = new NumberFormatter('en_US', NumberFormatter::CURRENCY);
$sPattern = $cFormatter->getPattern(); // returns "¤#,##0.00;(¤#,##0.00)";

$sMyPattern = "¤#,##0.00;-¤#,##0.00";
$cFormatter->formatCurrency(-456, 'USD');  // returns -$456.00
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download