numfmt_format_currency
Format the currency value according to the formatter rules.
Parameters
The numeric currency value.
The 3-letter ISO 4217 currency code indicating the currency to use.
Return Values
String representing the formatted currency value, or false on failure.
Examples
Example #1 numfmt_format_currency() example
$fmt = numfmt_create ( ‘de_DE’ , NumberFormatter :: CURRENCY );
echo numfmt_format_currency ( $fmt , 1234567.891234567890000 , «EUR» ). «\n» ;
echo numfmt_format_currency ( $fmt , 1234567.891234567890000 , «RUR» ). «\n» ;
$fmt = numfmt_create ( ‘ru_RU’ , NumberFormatter :: CURRENCY );
echo numfmt_format_currency ( $fmt , 1234567.891234567890000 , «EUR» ). «\n» ;
echo numfmt_format_currency ( $fmt , 1234567.891234567890000 , «RUR» ). «\n» ;
?>?php
Example #2 OO example
$fmt = new NumberFormatter ( ‘de_DE’ , NumberFormatter :: CURRENCY );
echo $fmt -> formatCurrency ( 1234567.891234567890000 , «EUR» ). «\n» ;
echo $fmt -> formatCurrency ( 1234567.891234567890000 , «RUR» ). «\n» ;
$fmt = new NumberFormatter ( ‘ru_RU’ , NumberFormatter :: CURRENCY );
echo $fmt -> formatCurrency ( 1234567.891234567890000 , «EUR» ). «\n» ;
echo $fmt -> formatCurrency ( 1234567.891234567890000 , «RUR» ). «\n» ;
?>?php
The above example will output:
1.234.567,89 € 1.234.567,89 RUR 1 234 567,89€ 1 234 567,89р.
Notes
Note:
Formats achievable by this method of formatting cannot fully use the possibilities of underlying ICU library, such as to format currency with narrow currency symbol.
To fully utilize them use msgfmt_format_message() .
See Also
- numfmt_get_error_code() — Get formatter’s last error code
- numfmt_format() — Format a number
- numfmt_parse_currency() — Parse a currency number
- msgfmt_format_message() — Quick format message
User Contributed Notes 9 notes
While this function accepts floats for currency (in order to display cents), you should (for applications where this is critical) never store or handle money using floats, as rounding errors may occur. Work with integers (or a BigInt class if integers aren’t large enough) internally instead, where the integer represents the total number of cents. An alternative (especially if you need more precision than cents) is using the BC (Binary Calculator) Math module, that handles arbitrary precision numbers with 100% accuracy.
When you want to format currency’s without sub units and the currency is not the one used by the given locale you need to set the currency code before as TextAttribute _BEFORE_ setting the NumberFormatter::FRACTION_DIGITS
$fmt = new NumberFormatter ( ‘en_US’ , NumberFormatter :: CURRENCY );
$fmt -> setTextAttribute ( NumberFormatter :: CURRENCY_CODE , ‘EUR’ );
$fmt -> setAttribute ( NumberFormatter :: FRACTION_DIGITS , 0 );
$fmt -> formatCurrency ( 100 , ‘EUR’ );
?>
The note about different formatting[1] actually does not depend on the PHP version but on the version of the icu library[2] that PHP is compiled against because this library has a database with formatting rules for the different locales.
formatCurrency() does not follow international standard for currency decimal, published here : https://www.currency-iso.org/en/home/tables/table-a1.html.
To define decimal I found that we need to use format() function after setting some NumberFormat attributes.
For example «COP» (Colombian peso) if defined to use 2 decimals, but NumberFormat::formatCurrency() use 0 decimal for this currency (I do not know why!).
$fmt = new \NumberFormatter( ‘fr’, \NumberFormatter::CURRENCY);
$fmt->setTextAttribute( $fmt::CURRENCY_CODE, ‘COP’ );
$fmt->setAttribute( $fmt::FRACTION_DIGITS, 2 );
$numberString = $fmt->format( 1234.56 );
If locale change to ‘en’ then the output is : COP1,234.56
When setting the pattern, don’t forget that space character between currency symbol and number (either as prefix or suffix) should not be breakable (like for HTML). For example, in UTF-8 you should use the no-break-space character («\xC2\xA0»):
$fmt = new NumberFormatter ( ‘en_US’ , NumberFormatter :: CURRENCY );
$fmt -> setPattern ( str_replace ( ‘¤#’ , «¤\xC2\xA0#» , $fmt -> getPattern ()));
?>
Currency symbols seem to have spurious support.
Take for example the Thai Baht symbol.. ฿ which doesn’t seem supported in the Thai locale, but is in other locales such as Chinese Simplified..
$fmt = new NumberFormatter ( ‘th_TH’ , NumberFormatter :: CURRENCY );
echo $fmt -> formatCurrency ( 100 , ‘THB’ );
// Outputs: THB 100
$fmt = new NumberFormatter ( ‘zh_Hans’ , NumberFormatter :: CURRENCY );
echo $fmt -> formatCurrency ( 100 , ‘THB’ );
// Outputs: ฿ 100
?>
This had me scratching my head. When working with certain English locales (e.g. «en_US» and «en_CA» among others but certainly not all), it is important to note that negative numbers are formatted differently between PHP 5.5 and PHP 5.6.
$formatter = new NumberFormatter ( ‘en_US’ , NumberFormatter :: CURRENCY );
echo $formatter -> formatCurrency (- 0.99 , ‘USD’ ), PHP_EOL ;
$formatter = new NumberFormatter ( ‘en_CA’ , NumberFormatter :: CURRENCY );
echo $formatter -> formatCurrency (- 0.99 , ‘USD’ ), PHP_EOL ;
This function is typically over a 1000 times slower on the first run in a php session compared to subsequent runs, and that is using a newly created formatter each time.
Timings for the first run have been from 60ms to 195ms, whereas subsequent runs are well under 100us.
For comparison, creating the formatter takes about 100us.
It seams that for currency symbols that contain the dollar sign ‘$’ the resulting formatted number is broken: 95.23 is formatted .23 instead of $95.23. As a workaround, you need to modify the pattern by adding a space:
$fmt = new NumberFormatter ( ‘en_US’ , NumberFormatter :: CURRENCY );
$fmt -> setTextAttribute ( NumberFormatter :: CURRENCY_CODE , ‘CAD’ );
$fmt -> setPattern ( str_replace ( ‘¤#’ , ‘¤ #’ , $fmt -> getPattern () ) );
echo $fmt -> formatCurrency ( 100 , ‘CAD’ );
?>
gibbs / currency_symbols.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
$ currency_symbols = array ( |
‘AED’ => ‘د.إ’ , // ? |
‘AFN’ => ‘Af’ , |
‘ALL’ => ‘Lek’ , |
‘AMD’ => » , |
‘ANG’ => ‘ƒ’ , |
‘AOA’ => ‘Kz’ , // ? |
‘ARS’ => ‘$’ , |
‘AUD’ => ‘$’ , |
‘AWG’ => ‘ƒ’ , |
‘AZN’ => ‘ман’ , |
‘BAM’ => ‘KM’ , |
‘BBD’ => ‘$’ , |
‘BDT’ => ‘৳’ , // ? |
‘BGN’ => ‘лв’ , |
‘BHD’ => ‘.د.ب’ , // ? |
‘BIF’ => ‘FBu’ , // ? |
‘BMD’ => ‘$’ , |
‘BND’ => ‘$’ , |
‘BOB’ => ‘$b’ , |
‘BRL’ => ‘R$’ , |
‘BSD’ => ‘$’ , |
‘BTN’ => ‘Nu.’ , // ? |
‘BWP’ => ‘P’ , |
‘BYR’ => ‘p.’ , |
‘BZD’ => ‘BZ$’ , |
‘CAD’ => ‘$’ , |
‘CDF’ => ‘FC’ , |
‘CHF’ => ‘CHF’ , |
‘CLF’ => » , // ? |
‘CLP’ => ‘$’ , |
‘CNY’ => ‘¥’ , |
‘COP’ => ‘$’ , |
‘CRC’ => ‘₡’ , |
‘CUP’ => ‘’ , |
‘CVE’ => ‘$’ , // ? |
‘CZK’ => ‘Kč’ , |
‘DJF’ => ‘Fdj’ , // ? |
‘DKK’ => ‘kr’ , |
‘DOP’ => ‘RD$’ , |
‘DZD’ => ‘دج’ , // ? |
‘EGP’ => ‘£’ , |
‘ETB’ => ‘Br’ , |
‘EUR’ => ‘€’ , |
‘FJD’ => ‘$’ , |
‘FKP’ => ‘£’ , |
‘GBP’ => ‘£’ , |
‘GEL’ => ‘ლ’ , // ? |
‘GHS’ => ‘¢’ , |
‘GIP’ => ‘£’ , |
‘GMD’ => ‘D’ , // ? |
‘GNF’ => ‘FG’ , // ? |
‘GTQ’ => ‘Q’ , |
‘GYD’ => ‘$’ , |
‘HKD’ => ‘$’ , |
‘HNL’ => ‘L’ , |
‘HRK’ => ‘kn’ , |
‘HTG’ => ‘G’ , // ? |
‘HUF’ => ‘Ft’ , |
‘IDR’ => ‘Rp’ , |
‘ILS’ => ‘₪’ , |
‘INR’ => ‘₹’ , |
‘IQD’ => ‘ع.د’ , // ? |
‘IRR’ => ‘﷼’ , |
‘ISK’ => ‘kr’ , |
‘JEP’ => ‘£’ , |
‘JMD’ => ‘J$’ , |
‘JOD’ => ‘JD’ , // ? |
‘JPY’ => ‘¥’ , |
‘KES’ => ‘KSh’ , // ? |
‘KGS’ => ‘лв’ , |
‘KHR’ => ‘៛’ , |
‘KMF’ => ‘CF’ , // ? |
‘KPW’ => ‘₩’ , |
‘KRW’ => ‘₩’ , |
‘KWD’ => ‘د.ك’ , // ? |
‘KYD’ => ‘$’ , |
‘KZT’ => ‘лв’ , |
‘LAK’ => ‘₭’ , |
‘LBP’ => ‘£’ , |
‘LKR’ => ‘₨’ , |
‘LRD’ => ‘$’ , |
‘LSL’ => ‘L’ , // ? |
‘LTL’ => ‘Lt’ , |
‘LVL’ => ‘Ls’ , |
‘LYD’ => ‘ل.د’ , // ? |
‘MAD’ => ‘د.م.’ , //? |
‘MDL’ => ‘L’ , |
‘MGA’ => ‘Ar’ , // ? |
‘MKD’ => ‘ден’ , |
‘MMK’ => ‘K’ , |
‘MNT’ => ‘₮’ , |
‘MOP’ => ‘MOP$’ , // ? |
‘MRO’ => ‘UM’ , // ? |
‘MUR’ => ‘₨’ , // ? |
‘MVR’ => ‘.ރ’ , // ? |
‘MWK’ => ‘MK’ , |
‘MXN’ => ‘$’ , |
‘MYR’ => ‘RM’ , |
‘MZN’ => ‘MT’ , |
‘NAD’ => ‘$’ , |
‘NGN’ => ‘₦’ , |
‘NIO’ => ‘C$’ , |
‘NOK’ => ‘kr’ , |
‘NPR’ => ‘₨’ , |
‘NZD’ => ‘$’ , |
‘OMR’ => ‘﷼’ , |
‘PAB’ => ‘B/.’ , |
‘PEN’ => ‘S/.’ , |
‘PGK’ => ‘K’ , // ? |
‘PHP’ => ‘₱’ , |
‘PKR’ => ‘₨’ , |
‘PLN’ => ‘zł’ , |
‘PYG’ => ‘Gs’ , |
‘QAR’ => ‘﷼’ , |
‘RON’ => ‘lei’ , |
‘RSD’ => ‘Дин.’ , |
‘RUB’ => ‘руб’ , |
‘RWF’ => ‘ر.س’ , |
‘SAR’ => ‘﷼’ , |
‘SBD’ => ‘$’ , |
‘SCR’ => ‘₨’ , |
‘SDG’ => ‘£’ , // ? |
‘SEK’ => ‘kr’ , |
‘SGD’ => ‘$’ , |
‘SHP’ => ‘£’ , |
‘SLL’ => ‘Le’ , // ? |
‘SOS’ => ‘S’ , |
‘SRD’ => ‘$’ , |
‘STD’ => ‘Db’ , // ? |
‘SVC’ => ‘$’ , |
‘SYP’ => ‘£’ , |
‘SZL’ => ‘L’ , // ? |
‘THB’ => ‘฿’ , |
‘TJS’ => ‘TJS’ , // ? TJS (guess) |
‘TMT’ => ‘m’ , |
‘TND’ => ‘د.ت’ , |
‘TOP’ => ‘T$’ , |
‘TRY’ => ‘₤’ , // New Turkey Lira (old symbol used) |
‘TTD’ => ‘$’ , |
‘TWD’ => ‘NT$’ , |
‘TZS’ => » , |
‘UAH’ => ‘₴’ , |
‘UGX’ => ‘USh’ , |
‘USD’ => ‘$’ , |
‘UYU’ => ‘$U’ , |
‘UZS’ => ‘лв’ , |
‘VEF’ => ‘Bs’ , |
‘VND’ => ‘₫’ , |
‘VUV’ => ‘VT’ , |
‘WST’ => ‘WS$’ , |
‘XAF’ => ‘FCFA’ , |
‘XCD’ => ‘$’ , |
‘XDR’ => » , |
‘XOF’ => » , |
‘XPF’ => ‘F’ , |
‘YER’ => ‘﷼’ , |
‘ZAR’ => ‘R’ , |
‘ZMK’ => ‘ZK’ , // ? |
‘ZWL’ => ‘Z$’ , |
); |