I'm using the PHP NumberFormatter class to print currency values.
我正在使用PHP NumberFormatter类来打印货币值。
Eg:
$cFormatter = new NumberFormatter('en_US', NumberFormatter::CURRENCY);
$cFormatter->formatCurrency(123, 'USD');
$cFormatter->formatCurrency(123, 'BRL');
$cFormatter->formatCurrency(123, 'GBP');
That works fine, and returns "$123.00
", "R$123.00
", "£123.00
" respectively as expected.
工作正常,并按预期分别返回“$ 123.00”,“R $ 123.00”,“£123.00”。
But negative numbers are printed "accountancy style", surrounded by brackets, instead of a leading minus "-".
但负数字印在“会计风格”上,用括号括起来,而不是前导减去“ - ”。
eg:
$cFormatter->formatCurrency(-456, 'USD');
Returns "($456.00)"
, whereas I want "-$456.00"
. Surely there's a simple way of doing this?
返回“($ 456.00)”,而我想要“ - $ 456.00”。当然有一种简单的方法可以做到这一点?
I can remove the brackets by override the prefix and postfix as follows:
我可以通过覆盖前缀和后缀删除括号,如下所示:
$cFormatter->setTextAttribute(NumberFormatter::NEGATIVE_PREFIX, "-");
$cFormatter->setTextAttribute(NumberFormatter::NEGATIVE_SUFFIX, "");
But then I get no currency symbol eg "-456.00"
.
但后来我没有货币符号,例如“-456.00”。
Is there some escape code for the currency symbol that I need to use when setting the NEGATIVE_PREFIX attribute?
在设置NEGATIVE_PREFIX属性时,是否需要使用货币符号的转义码?
Edit: I'm happy to set a different locale if that gives me the result I'm looking for.
编辑:我很高兴设置一个不同的区域设置,如果这给了我正在寻找的结果。
Edit 2: Looking at the Intl library docs (which is the library used to implement NumberFormatter), the following looked promising:
编辑2:查看Intl库文档(这是用于实现NumberFormatter的库),以下看起来很有希望:
¤ (\u00A4) : Prefix or suffix : No Currency sign, replaced by currency symbol. If doubled, replaced by international currency symbol. If tripled, replaced by currency plural names, for example, "US dollar" or "US dollars" for America. If present in a pattern, the monetary decimal separator is used instead of the decimal separator.
¤(\ u00A4):前缀或后缀:无货币符号,替换为货币符号。如果加倍,则用国际货币符号代替。如果是三倍,则替换为货币复数名称,例如美国的“美元”或“美元”。如果存在于模式中,则使用货币小数分隔符而不是小数分隔符。
But this:
$cFormatter->setTextAttribute(NumberFormatter::NEGATIVE_PREFIX, "-¤");
Just prints "-¤123", so no joy.
只需打印“-¤123”,就没有喜悦。
Edit 3: I think I found the answer, see below.
编辑3:我想我找到了答案,见下文。
3 个解决方案
#1
I've found a slightly less hacky way to bend the en_US locale behaviour to what I'm looking for - the getPattern() / setPattern() functions.
我发现将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
By doing so, you are kinda ruining the point of the localization. Since the ¤ represent the dollar sign and your are telling that your pattern always puts the sign in the beginning of the number, which is not the case for every currency. If you want to remove the parenthesis, I would go something more like,
通过这样做,你有点破坏了本地化的重点。由于¤代表美元符号,并且您告诉您的模式总是将符号放在数字的开头,而不是每种货币的情况。如果你想删除括号,我会更喜欢,
$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);
#3
Simply you can do
你可以做到
$cFormatter->setTextAttribute(NumberFormatter::PAD_BEFORE_PREFIX, '-$')."\n";
#1
I've found a slightly less hacky way to bend the en_US locale behaviour to what I'm looking for - the getPattern() / setPattern() functions.
我发现将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
By doing so, you are kinda ruining the point of the localization. Since the ¤ represent the dollar sign and your are telling that your pattern always puts the sign in the beginning of the number, which is not the case for every currency. If you want to remove the parenthesis, I would go something more like,
通过这样做,你有点破坏了本地化的重点。由于¤代表美元符号,并且您告诉您的模式总是将符号放在数字的开头,而不是每种货币的情况。如果你想删除括号,我会更喜欢,
$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);
#3
Simply you can do
你可以做到
$cFormatter->setTextAttribute(NumberFormatter::PAD_BEFORE_PREFIX, '-$')."\n";