如何让NumberFormatter在打印负数货币值时带有减号?

9
我将使用PHP NumberFormatter类来打印货币值。
例如:
  $cFormatter = new NumberFormatter('en_US', NumberFormatter::CURRENCY);
  $cFormatter->formatCurrency(123, 'USD');
  $cFormatter->formatCurrency(123, 'BRL');
  $cFormatter->formatCurrency(123, 'GBP');

那很好用,而且如预期地返回了"$123.00"、"R$123.00"、"£123.00"。但是负数会以“会计风格”打印,用括号括起来,而不是前导符号“-”。例如:
$cFormatter->formatCurrency(-456, 'USD');

返回结果为"($456.00)",但我想要的是"-$456.00"。肯定有一种简单的方法可以做到这一点吧?
我可以通过以下方式覆盖前缀和后缀来删除括号:
$cFormatter->setTextAttribute(NumberFormatter::NEGATIVE_PREFIX, "-");
$cFormatter->setTextAttribute(NumberFormatter::NEGATIVE_SUFFIX, "");

但是我得不到货币符号,例如"-456.00"
在设置NEGATIVE_PREFIX属性时,是否有一些需要使用货币符号的转义代码?
编辑:如果这能给我想要的结果,我可以设置不同的区域设置。
编辑2:查看Intl library docs(实现NumberFormatter的库),以下内容看起来很有前途:
¤ (\u00A4):前缀或后缀:没有货币符号,而是替换为货币符号。如果加倍,则替换为国际货币符号。如果三倍,则替换为货币复数名称,例如"美元"或"美元"。如果在模式中存在,则使用货币小数分隔符而不是小数分隔符。
但是这个:
$cFormatter->setTextAttribute(NumberFormatter::NEGATIVE_PREFIX, "-¤");

仅打印“-¤123”,所以没有乐趣。

编辑3:我认为我找到了答案,请见下文。


鉴于“如果这能给我想要的结果,我很乐意设置不同的语言环境。” 请查看我的更新答案:使用en_AU。 - hobodave
3个回答

17
我找到了一种稍微不那么繁琐的方法来调整en_US语言环境的行为,以符合我所需的要求 - getPattern() / setPattern() 函数。
$cFormatter = new NumberFormatter('en_US', NumberFormatter::CURRENCY);
$sPattern = $cFormatter->getPattern(); // returns "¤#,##0.00;(¤#,##0.00)";

$sMyPattern = "¤#,##0.00;-¤#,##0.00";
$cFormatter->setPattern($sMyPattern);
$cFormatter->formatCurrency(-456, 'USD');  // returns -$456.00

2

这样做会破坏本地化的意义。由于¤代表美元符号,您告诉人们您的模式始终将符号放在数字前面,而并非每种货币都是如此。如果您想删除括号,我建议采用更加简洁的方式,例如:

$locale = 'en_US';    
$nf = new \NumberFormatter($locale, \NumberFormatter::CURRENCY); 
$nf->setAttribute(\NumberFormatter::MAX_FRACTION_DIGITS, $decimals);

$pattern = str_replace(array('(',')'),'',$nf->getPattern());
$nf->setPattern($pattern);

echo $nf->format($number);

-1

你可以简单地这样做

$cFormatter->setTextAttribute(NumberFormatter::PAD_BEFORE_PREFIX, '-$')."\n";

1
为什么应该让楼主“尝试这个”?一个好的答案总是会解释做了什么以及为什么要那样做,不仅为了楼主,也为了未来可能会找到这个问题并阅读您的答案的 Stack Overflow 访问者。 - Maximilian Ast

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接