php intl numberformatter

PHP NumberFormatter y moneda, no se puede establecer la precisión



intl (6)

Creo que tienes que usar una configuración regional que admita la moneda de destino. Así que en_US no tenemos el euro. de_DE lo tengo y fr_FR también. Así que no es extraño que fr_FR apoye el euro.

Parece que esto no es un error.

Quiero establecer una precisión de 0 al usar la clase de PHP NumberFormatter (de la extensión Intl ) con la moneda. Sin embargo tengo un resultado extraño. Aquí:

$numberFormatter = new NumberFormatter(''en-US'', NumberFormatter::CURRENCY); $numberFormatter->setAttribute(NumberFormatter::FRACTION_DIGITS, 0); echo $numberFormatter->formatCurrency(''45'', ''USD'');

Sale $45 , que es lo que quiero. Sin embargo, si cambio la moneda a EUR con la misma configuración:

echo $numberFormatter->formatCurrency(''45'', ''EUR'');

Sale a €45.00 (aunque explícitamente configurado para tener una precisión de cero).

Aún más extraño, si configuro la configuración regional en fr-FR , genera el número como se esperaba:

$numberFormatter = new NumberFormatter(''fr-FR'', NumberFormatter::CURRENCY); $numberFormatter->setAttribute(NumberFormatter::FRACTION_DIGITS, 0); echo $numberFormatter->formatCurrency(''45'', ''EUR'');

Sale a 45 € .

¿Es esto un error?


Debe proporcionar una combinación de moneda y moneda local que sea correcta. Por ejemplo, fr-FR / fr-bh / fr-ch support €, que es lo que debe proporcionarse en la función formatCurrency.


Esta función usa la información regional para dar formato al número en moneda, el formato que estoy usando es ''% # 10n'' para $:

/** * That it is an implementation of the function money_format for the * platforms that do not it bear. * The function accepts to same string of format accepts for the * original function of the PHP. * The function is tested using PHP 5.1.4 in Windows XP * and Apache WebServer. * * format I am are using is ''%#10n'' for $; * */ public static function money_format( $format, $number ) { $regex = ''/%((?:[/^!/-]|/+|/(|/=.)*)([0-9]+)?''. ''(?:#([0-9]+))?(?:/.([0-9]+))?([in%])/''; if (setlocale(LC_MONETARY, 0) == ''C'') { setlocale(LC_MONETARY, ''''); } $locale = localeconv(); preg_match_all($regex, $format, $matches, PREG_SET_ORDER); foreach ($matches as $fmatch) { $value = floatval($number); $flags = array( ''fillchar'' => preg_match(''//=(.)/'', $fmatch[1], $match) ? $match[1] : '' '', ''nogroup'' => preg_match(''//^/'', $fmatch[1]) > 0, ''usesignal'' => preg_match(''//+|/(/'', $fmatch[1], $match) ? $match[0] : ''+'', ''nosimbol'' => preg_match(''//!/'', $fmatch[1]) > 0, ''isleft'' => preg_match(''//-/'', $fmatch[1]) > 0 ); $width = trim($fmatch[2]) ? (int)$fmatch[2] : 0; $left = trim($fmatch[3]) ? (int)$fmatch[3] : 0; $right = trim($fmatch[4]) ? (int)$fmatch[4] : $locale[''int_frac_digits'']; $conversion = $fmatch[5]; $positive = true; if ($value < 0) { $positive = false; $value *= -1; } $letter = $positive ? ''p'' : ''n''; $prefix = $suffix = $cprefix = $csuffix = $signal = ''''; $signal = $positive ? $locale[''positive_sign''] : $locale[''negative_sign'']; switch (true) { case $locale["{$letter}_sign_posn"] == 1 && $flags[''usesignal''] == ''+'': $prefix = $signal; break; case $locale["{$letter}_sign_posn"] == 2 && $flags[''usesignal''] == ''+'': $suffix = $signal; break; case $locale["{$letter}_sign_posn"] == 3 && $flags[''usesignal''] == ''+'': $cprefix = $signal; break; case $locale["{$letter}_sign_posn"] == 4 && $flags[''usesignal''] == ''+'': $csuffix = $signal; break; case $flags[''usesignal''] == ''('': case $locale["{$letter}_sign_posn"] == 0: $prefix = ''(''; $suffix = '')''; break; } if (!$flags[''nosimbol'']) { $currency = $cprefix . ($conversion == ''i'' ? $locale[''int_curr_symbol''] : $locale[''currency_symbol'']) . $csuffix; } else { $currency = ''''; } $space = $locale["{$letter}_sep_by_space"] ? '' '' : ''''; $value = number_format($value, $right, $locale[''mon_decimal_point''], $flags[''nogroup''] ? '''' : $locale[''mon_thousands_sep'']); $value = @explode($locale[''mon_decimal_point''], $value); $n = strlen($prefix) + strlen($currency) + strlen($value[0]); if ($left > 0 && $left > $n) { $value[0] = str_repeat($flags[''fillchar''], $left - $n) . $value[0]; } $value = implode($locale[''mon_decimal_point''], $value); if ($locale["{$letter}_cs_precedes"]) { $value = $prefix . $currency . $space . $value . $suffix; } else { $value = $prefix . $value . $space . $currency . $suffix; } if ($width > 0) { $value = str_pad($value, $width, $flags[''fillchar''], $flags[''isleft''] ? STR_PAD_RIGHT : STR_PAD_LEFT); } $format = str_replace($fmatch[0], $value, $format); } return $format; }


Establezca el valor de configuración regional predeterminado en la entrada php que puede usar:

ini_set (''intl.default_locale'', ''de-DE'');

Para cambiar el formato de número use:

setlocale (LC_MONETARY, ''de-DE'');



Puede usar la siguiente línea de código para formatear el dinero:

$number = 1234.56; setlocale(LC_MONETARY,"en_US"); // Sets the Default for money echo money_format("%i", $number);

Te dará salida:

USD 1,234.56