Formatting currency using numberFormatter - php

I ran into some problems using the php NumberFormatter class. I want rounded digits to be displayed without any decimals, and digits which has decimals to be rounded with 2 decimals. i.e.
$fmt = new NumberFormatter('nl', NumberFormatter::CURRENCY);
$fmt->setAttribute(\NumberFormatter::MIN_FRACTION_DIGITS, 0);
$fmt->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, 2);
var_dump($fmt->formatCurrency(15.15, 'EUR')); //Outputs € 15,15
var_dump($fmt->formatCurrency(15, 'EUR')); //Outputs € 15,00
As you can see the last dump is outputting 15,00 but I'm expecting 15 here.
Whenever I use the "full" locale nl_NL instead of nl the formatter behaves as expected, but I'm unable to use that because I only have the language available in my locale.
$fmt = new NumberFormatter('nl_NL', NumberFormatter::CURRENCY);
$fmt->setAttribute(\NumberFormatter::MIN_FRACTION_DIGITS, 0);
$fmt->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, 2);
var_dump($fmt->formatCurrency(15.15, 'EUR')); //Outputs € 15,15
var_dump($fmt->formatCurrency(15, 'EUR')); //Output € 15
This seems like a bug in the NumberFormatter but I really have no clue how to fix it or figure out some other workaround. I'd be very grateful for any help.

Dirty fix:
$formattedCurrency = preg_replace('/,00$/', '', $fmt->formatCurrency(15, 'EUR'));

you can use the MAX_SIGNIFICANT_DIGITS attribute:
$fmt = new NumberFormatter('nl', NumberFormatter::CURRENCY);
$fmt->setAttribute(\NumberFormatter::MAX_SIGNIFICANT_DIGITS, 7);
var_dump($fmt->formatCurrency(15.15, 'EUR')); // Outputs € 15,15
var_dump($fmt->formatCurrency(15, 'EUR')); // Outputs € 15

Related

How to "cut the fluff" out from PHP's NumberFormatter to display a "compact" money sum for a spreadsheet context? [duplicate]

I'm trying to format revenue totals as grabbed from a db, and using php's NumberFormatter class, with the formatCurrency method.
However, I do not want to print out the actual € / Euro symbol with this. I just want the plain number, with comma's and decimal points.
Example;
1234.56 should be formatted as 1,234.56
The current output is giving €1,234.56.
Code I'm using:
$array['total_revenue'] = $this
->db
->query($sql)
->row_array()['SUM( booking_total )'];
$formatter = new NumberFormatter('en_GB', NumberFormatter::CURRENCY);
echo $formatter->formatCurrency($array['total_revenue'], 'EUR') . PHP_EOL;
Would anyone have any ideas on how I can fix this up to remove the euro symbol?
You should use setSymbol() function:
$formatter = new NumberFormatter('en_GB', NumberFormatter::CURRENCY);
$formatter->setSymbol(NumberFormatter::CURRENCY_SYMBOL, '');
echo $formatter->formatCurrency($array['total_revenue'], 'EUR') . PHP_EOL;
I came here because for some reason, $formatter->setSymbol(NumberFormatter::CURRENCY_SYMBOL, ''); was being ignored by $formatter->formatCurrency($array['total_revenue'], 'USD');
To resolve this issue, I found out a solution here.
https://www.php.net/manual/en/numberformatter.setsymbol.php#124153
this could be obvious to some, but setSymbol(NumberFormatter::CURRENCY_SYMBOL, '') doesn't work for formatCurrency - it will simply be ignored...
use NumberFormatter::CURRENCY and $fmt->format(123); to get a currency value with the symbol specified as CURRENCY_SYMBOL (or INTL_CURRENCY_SYMBOL)
i.e
$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
$fmt->setSymbol(NumberFormatter::CURRENCY_SYMBOL, '');
$fmt->setAttribute(NumberFormatter::FRACTION_DIGITS, 2);
echo $fmt->format(56868993064.7985);
//Output: 56.868.993.064,80 
A simple regex is a quick fix for your problem. Try;
$actual = $formatter->formatCurrency($array['total_revenue'], 'EUR') . PHP_EOL;
$output = preg_replace( '/[^0-9,"."]/', '', $actual );
echo $output;
Hope this helps
The formatCurrency() method is convenient in that it automatically formats the amount according to the rules of the specified currency. For example, when formatting an amount in Euros, the number should show 2 decimal places. But when formatting an amount in Yen, the number should have no decimals as fractions of Yen do not exist (as far as I know). Other currencies may have 3 or even 4 decimals.
If the goal is to keep all functionality of the formatCurrency() method except for the removal of the currency symbol (or code), then I'd suggest this snippet:
$localeCode = 'en_US';
$currencyCode = 'USD';
$amount = 10000;
$formatter = new \NumberFormatter($localeCode, \NumberFormatter::CURRENCY);
$formatter->setTextAttribute(\NumberFormatter::CURRENCY_CODE, $currencyCode);
$formatter->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, '');
$formatter->format($amount);
Please note that it is necessary to set the currency code BEFORE clearing the currency symbol. Trying to set the currency after clearing the symbol will not work, as setting the currency will automatically load the related symbol.

FPDF print properly currency symbol given by NumberFormatter class

I'm adding a price value, retrived from a db, inside a cell on a pdf created with FPDF, using this function:
$fmt = numfmt_create( 'it_IT', NumberFormatter::CURRENCY );
numfmt_format_currency($fmt, $row['prezzo'], "EUR")
Considering that the EUR symbol would be output like this:
 €
I've tried to define a EURO costant:
define('EURO',chr(128));
but i can't use it with NumberFormatter.
How can i print the € symbol correctly in the pdf?

NumberFormatter generate unbreakable space

I try to put a formated currency input from php as value of an input,
$format = numfmt_create( 'fr_FR', NumberFormatter::CURRENCY);
$datavalue = numfmt_format_currency($format, $data['value'], 'EUR');
It works, but the result contain unbreakable space caracter like so
value='10,0 €'
That lead to mess up with my design, I didn't found how to remove it yet
Already tried :
str_replace(' ', " ", $datavalue);
Run the result through html_entity_decode() then perform your str_replace(' ', '', $datavalue);
That class/function prefers an integer be passed to it, so you need to clean up your data before you ever get to the function.
You can use numberFormatter
example:
$amount = '12345.67';
$formatter = new NumberFormatter('fr_FR', NumberFormatter::CURRENCY);
echo 'format: ', $formatter->formatCurrency($amount, 'EUR'), PHP_EOL;
//output
12 345,67 €
edit: other method is use this MoneyFormat
example
$number = 1234.56;
// let's print the international format for the en_US locale
setlocale(LC_MONETARY, 'en_US');
echo money_format('%i', $number) . "\n";
// USD 1,234.56

Removing currency symbol from formatCurrency

I'm trying to format revenue totals as grabbed from a db, and using php's NumberFormatter class, with the formatCurrency method.
However, I do not want to print out the actual € / Euro symbol with this. I just want the plain number, with comma's and decimal points.
Example;
1234.56 should be formatted as 1,234.56
The current output is giving €1,234.56.
Code I'm using:
$array['total_revenue'] = $this
->db
->query($sql)
->row_array()['SUM( booking_total )'];
$formatter = new NumberFormatter('en_GB', NumberFormatter::CURRENCY);
echo $formatter->formatCurrency($array['total_revenue'], 'EUR') . PHP_EOL;
Would anyone have any ideas on how I can fix this up to remove the euro symbol?
You should use setSymbol() function:
$formatter = new NumberFormatter('en_GB', NumberFormatter::CURRENCY);
$formatter->setSymbol(NumberFormatter::CURRENCY_SYMBOL, '');
echo $formatter->formatCurrency($array['total_revenue'], 'EUR') . PHP_EOL;
I came here because for some reason, $formatter->setSymbol(NumberFormatter::CURRENCY_SYMBOL, ''); was being ignored by $formatter->formatCurrency($array['total_revenue'], 'USD');
To resolve this issue, I found out a solution here.
https://www.php.net/manual/en/numberformatter.setsymbol.php#124153
this could be obvious to some, but setSymbol(NumberFormatter::CURRENCY_SYMBOL, '') doesn't work for formatCurrency - it will simply be ignored...
use NumberFormatter::CURRENCY and $fmt->format(123); to get a currency value with the symbol specified as CURRENCY_SYMBOL (or INTL_CURRENCY_SYMBOL)
i.e
$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
$fmt->setSymbol(NumberFormatter::CURRENCY_SYMBOL, '');
$fmt->setAttribute(NumberFormatter::FRACTION_DIGITS, 2);
echo $fmt->format(56868993064.7985);
//Output: 56.868.993.064,80 
A simple regex is a quick fix for your problem. Try;
$actual = $formatter->formatCurrency($array['total_revenue'], 'EUR') . PHP_EOL;
$output = preg_replace( '/[^0-9,"."]/', '', $actual );
echo $output;
Hope this helps
The formatCurrency() method is convenient in that it automatically formats the amount according to the rules of the specified currency. For example, when formatting an amount in Euros, the number should show 2 decimal places. But when formatting an amount in Yen, the number should have no decimals as fractions of Yen do not exist (as far as I know). Other currencies may have 3 or even 4 decimals.
If the goal is to keep all functionality of the formatCurrency() method except for the removal of the currency symbol (or code), then I'd suggest this snippet:
$localeCode = 'en_US';
$currencyCode = 'USD';
$amount = 10000;
$formatter = new \NumberFormatter($localeCode, \NumberFormatter::CURRENCY);
$formatter->setTextAttribute(\NumberFormatter::CURRENCY_CODE, $currencyCode);
$formatter->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, '');
$formatter->format($amount);
Please note that it is necessary to set the currency code BEFORE clearing the currency symbol. Trying to set the currency after clearing the symbol will not work, as setting the currency will automatically load the related symbol.

Php INTL format currency

This code:
$formatter = new \NumberFormatter('ar', \NumberFormatter::CURRENCY);
echo $formatter->formatCurrency(1234.99, 'EUR'), PHP_EOL;
outputs:
€ ١٬٢٣٤٫٩٩
Is there any way to make formatCurrenct to output
EUR ١٬٢٣٤٫٩٩
and still would be nice if ISO symbols would be translated.. so if i pass YER as a currency, I want to get something like this:
ر.ي.‏ ١٬٢٣٥

Categories