【发布时间】:2013-10-27 01:40:13
【问题描述】:
我想使用 PHP 的 Intl 的 NumberFormatter 类以人类可读的格式显示价格。我们的项目需要什么:
- CLDR 数字模式、货币和分隔符将需要通过我们的代码进行配置,而不是默认为 Intl/ICU 所知道的。
- 我们的应用程序将处理小数。 NumberFormatter 应该显示我们传递给它的所有小数。
但是,在尝试使用不同的配置以找到适合我们项目的确切组合时,我注意到一些我无法解释的效果。以下代码 sn-p 中的三个格式化程序几乎相同。与第一个相反,第二个使用欧元而不是美元,第三个设置了货币符号。第一个格式化程序的输出与我预期的一样,但是当我更改货币或设置货币符号时,MIN_FRACTION_DIGITS 属性将被忽略并且符号永远不会更改。
<?php
$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
$fmt->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, 4);
echo $fmt->formatCurrency(1234567890.891234567890000, "EUR")."\n";
// Outputs 1.234.567.890,8912 €
$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
$fmt->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, 4);
echo $fmt->formatCurrency(1234567890.891234567890000, "USD")."\n";
// Ouputs 1.234.567.890,89 $
$fmt = new NumberFormatter('de_DE', NumberFormatter::CURRENCY);
$fmt->setAttribute(NumberFormatter::MIN_FRACTION_DIGITS, 4);
$fmt->setSymbol(\NumberFormatter::CURRENCY_SYMBOL, '%');
echo $fmt->formatCurrency(1234567890.891234567890000, "EUR")."\n";
// Outputs 1.234.567.890,89 €
?>
Unicode CLDR number pattern documentation 的 General Purpose Numbers 下的第一行描述了在解析货币模式时,模式的小数部分中的两个零将需要替换为应用认为是合适的。这里的应用程序是 ICU(PHP 用于此的 C 库),MIN_FRACTION_DIGITS 属性的作用是让我覆盖第一个示例中的默认行为,但不能覆盖第二个或第三个示例。
有人能解释一下这种看似随机的行为变化吗?如果您需要任何其他信息,请告诉我。
【问题讨论】:
-
在我发布这个问题一分钟后,我偶然发现了PHP NumberFormatter and Currency, can't set precision,这听起来与我遇到的完全相同的问题,但这仍然不能解释为什么在 ICU 中设置了这个限制。