Format floats and unformat currencies
- Format a float number to a locale's currency or decimal format.
- Remove the formatting of a number to convert it to a float that you can save in a database.
Code
https://www.php.net/manual/en/class.numberformatter.php
format_*()
functions return stringsparse_*()
functions return floatsNumberFormatter::TYPE_CURRENCY
does not work
function format_currency($locale, $value, $currency = NULL) {
$fmt = numfmt_create($locale, NumberFormatter::CURRENCY);
$currency = @$currency ?: numfmt_get_symbol($fmt, NumberFormatter::INTL_CURRENCY_SYMBOL);
return numfmt_format_currency($fmt, $value, $currency);
}
function parse_currency($locale, $string) {
$fmt = numfmt_create($locale, NumberFormatter::CURRENCY);
return numfmt_parse_currency($fmt, $string, $currency);
}
function format_accounting($locale, $value, $currency = NULL) {
$fmt = numfmt_create($locale, NumberFormatter::CURRENCY_ACCOUNTING);
$currency = @$currency ?: numfmt_get_symbol($fmt, NumberFormatter::INTL_CURRENCY_SYMBOL);
return numfmt_format_currency($fmt, $value, $currency);
}
function parse_accounting($locale, $string) {
$fmt = numfmt_create($locale, NumberFormatter::CURRENCY_ACCOUNTING);
return numfmt_parse_currency($fmt, $string, $currency);
}
function format_decimal($locale, $value, $type = NULL) {
$fmt = numfmt_create($locale, NumberFormatter::DECIMAL);
$type = @$type ?: NumberFormatter::TYPE_DEFAULT;
return numfmt_format($fmt, $value, $type);
}
function parse_decimal($locale, $string, $type = NULL) {
$fmt = numfmt_create($locale, NumberFormatter::DECIMAL);
$type = @$type ?: NumberFormatter::TYPE_DOUBLE;
return numfmt_parse($fmt, $string, $type);
}
function ascii($string) {
return str_replace(["\xe2\x80\xaf", "\xc2\xa0"], ' ', $string);
}
Usage
function output() {
$value = -1000.01;
$locales = ['en_US', 'fr_FR', 'de_DE', 'nl_NL', 'ru_RU'];
$html = [];
foreach ($locales as $locale) {
$string = format_currency($locale, $value);
$ascii = ascii($string);
$value = parse_currency($locale, $string);
$html []= $locale . ' Currency '. ' => float: ' . $value . ' | ASCII: ' . $ascii . ' | UTF-8: ' . $string;
$string = format_accounting($locale, $value);
$ascii = ascii($string);
$value = parse_accounting($locale, $string);
$html []= $locale . ' Accounting '. ' => float: ' . $value . ' | ASCII: ' . $ascii . ' | UTF-8: ' . $string;
$string = format_decimal($locale, $value);
$ascii = ascii($string);
$value = parse_decimal($locale, $string);
$html []= $locale . ' Decimal '. ' => float: ' . $value . ' | ASCII: ' . $ascii . ' | UTF-8: ' . $string;
}
echo join(PHP_EOL, $html);
}
output();
Output
On the screenshot, you see the narrow no-break space <0x202f>
and the no-break space <0xa0>
; not visible on HTML.
en_US Currency => float: -1000.01 | ASCII: -$1,000.01 | UTF-8: -$1,000.01
en_US Accounting => float: -1000.01 | ASCII: ($1,000.01) | UTF-8: ($1,000.01)
en_US Decimal => float: -1000.01 | ASCII: -1,000.01 | UTF-8: -1,000.01
fr_FR Currency => float: -1000.01 | ASCII: -1 000,01 € | UTF-8: -1 000,01 €
fr_FR Accounting => float: -1000.01 | ASCII: (1 000,01 €) | UTF-8: (1 000,01 €)
fr_FR Decimal => float: -1000.01 | ASCII: -1 000,01 | UTF-8: -1 000,01
de_DE Currency => float: -1000.01 | ASCII: -1.000,01 € | UTF-8: -1.000,01 €
de_DE Accounting => float: -1000.01 | ASCII: -1.000,01 € | UTF-8: -1.000,01 €
de_DE Decimal => float: -1000.01 | ASCII: -1.000,01 | UTF-8: -1.000,01
nl_NL Currency => float: -1000.01 | ASCII: € -1.000,01 | UTF-8: € -1.000,01
nl_NL Accounting => float: -1000.01 | ASCII: (€ 1.000,01) | UTF-8: (€ 1.000,01)
nl_NL Decimal => float: -1000.01 | ASCII: -1.000,01 | UTF-8: -1.000,01
ru_RU Currency => float: -1000.01 | ASCII: -1 000,01 ₽ | UTF-8: -1 000,01 ₽
ru_RU Accounting => float: -1000.01 | ASCII: -1 000,01 ₽ | UTF-8: -1 000,01 ₽
ru_RU Decimal => float: -1000.01 | ASCII: -1 000,01 | UTF-8: -1 000,01