Как заставить NumberFormatter печатать отрицательные значения валюты со знаком минус?

StackOverflow https://stackoverflow.com/questions/1160860

Вопрос

Я использую PHP Числовой форматтер класс для печати значений валюты.

Например:

  $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".

Есть ли какой-нибудь escape-код для символа валюты, который мне нужно использовать при установке атрибута NEGATIVE_PREFIX?

Редактировать: Я буду рад установить другой языковой стандарт, если это даст мне тот результат, который я ищу.

Редактировать 2: Глядя на Документы международной библиотеки (библиотека, используемая для реализации NumberFormatter), многообещающе выглядело следующее:

¤ (\u00A4) :Префикс или суффикс:Знак валюты отсутствует, заменен символом валюты.При удвоении заменяется символом международной валюты.Если утроено, заменяется названиями валют во множественном числе, например, «доллар США» или «доллары США» для Америки.Если он присутствует в шаблоне, вместо десятичного разделителя используется денежный десятичный разделитель.

Но это:

$cFormatter->setTextAttribute(NumberFormatter::NEGATIVE_PREFIX, "-¤");

Просто печатает «-¤123», так что никакой радости.

Редактировать 3: Думаю, я нашел ответ, см. ниже.

Это было полезно?

Решение

Я нашел немного менее хакерский способ изменить поведение локали 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

Другие советы

Поступая так, вы как бы портите смысл локализации.Поскольку ¤ представляет знак доллара, и вы говорите, что ваш шаблон всегда помещает знак в начало числа, что не относится к каждой валюте.Если вы хотите удалить скобки, я бы сказал что-то вроде:

$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);

Просто вы можете сделать

$cFormatter->setTextAttribute(NumberFormatter::PAD_BEFORE_PREFIX, '-$')."\n";
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top