phpnumberformatter

PHP NumberFormatter::CURRENCY displays USD as abbreviation instead of as symbol in my locale


Another problem in the PHP NumberFormatter class for my language and locale (bg_BG, Bulgaria): the Bulgarian textual abbreviation for USD is displayed instead of the USD symbol ($). Example: 16,32 щ.д. instead of 16,32 $.

I instantiate the NumberFormatter class the standard way:

$curr = new NumberFormatter('bg_BG', NumberFormatter::CURRENCY);

I then print money-related stuff like this:

echo $curr->formatCurrency($amount, $currency);

When the currency is EUR, the euro symbol is displayed as expected, e.g. 49,47 €. When the currency is my own, the BGN, the textual abbreviation л.в. is displayed because we don't have a currency symbol for our currency.

It was the standard to display the textual abbreviation щ.д. for the USD until the late 1990s but things have changed since then.

I'm not sure if I can report this issue to the PHP team or if they'd care, so I'd like to be able to use a custom fix. But after a couple of hours of reading, I'm still clueless about forcing PHP to use the symbol instead of the text.

If I add this:

$curr->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, '$');

it replaces my own currency's abbreviation л.в. with $, which is wrong.

Does anyone know how to force PHP to use the symbol instead of the abbreviation only for USD? (I have PHP 8.3.3 on my local server.)


Solution

  • It shouldn't use $ because too many currencies use dollar, how would you tell USD from AUD, or CAD? but if you still want to force it you can override the methods like in my example below.

    see this example in action here at 3val

    <?php
    
    class BulgarianUSDollarSignFormatter extends NumberFormatter
    {
        public function formatCurrency(float $amount, string $currency): string|false
        {
            return str_replace('щ.д.', '$', parent::formatCurrency($amount, $currency));
        }
    }
    
    $curr = new BulgarianUSDollarSignFormatter('bg_BG', NumberFormatter::CURRENCY);
    $amount = '5665.25';
    
    $currency = 'USD';
    echo $curr->formatCurrency($amount, $currency).PHP_EOL;
    $currency = 'EUR';
    echo $curr->formatCurrency($amount, $currency).PHP_EOL;
    $currency = 'BGN';
    echo $curr->formatCurrency($amount, $currency).PHP_EOL;
    $currency = 'AUD';
    echo $curr->formatCurrency($amount, $currency).PHP_EOL;
    

    outputs

    5 665,25 $
    5 665,25 €
    5 665,25 лв.
    5 665,25 AUD