Как управлять знаками плюс и минус в форматировании валюты

Используйте опцию signDisplay, чтобы показывать или скрывать положительные и отрицательные знаки при форматировании сумм валют в JavaScript

Введение

Когда вы отображаете сумму транзакции, например $500, в банковском приложении, пользователи не могут понять, представляет ли это депозит или снятие средств. Отсутствие знака плюс или минус создает двусмысленность. Показывая +$500 или -$500, вы четко указываете направление транзакции.

Финансовые приложения нуждаются в точном контроле над тем, как знаки отображаются вместе с денежными суммами. Истории транзакций показывают депозиты и снятия с явными знаками. Отчеты о прибылях и убытках отображают доходы и убытки с четкими положительными и отрицательными индикаторами. Изменения баланса счета требуют видимых знаков, чтобы показать, поступили ли деньги на счет или были сняты. В JavaScript опция signDisplay в Intl.NumberFormat позволяет точно контролировать, когда знаки плюс и минус появляются при форматировании валюты.

Как форматируется валюта по умолчанию

По умолчанию Intl.NumberFormat показывает знак минус для отрицательных сумм и не показывает знак для положительных сумм.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD"
});

console.log(formatter.format(250.50));
// Вывод: "$250.50"

console.log(formatter.format(-75.25));
// Вывод: "-$75.25"

console.log(formatter.format(0));
// Вывод: "$0.00"

Такое поведение по умолчанию хорошо подходит для отображения цен и балансов счетов. Однако при отображении сумм транзакций или финансовых изменений отсутствие знака плюс для положительных значений делает направление неочевидным.

Использование signDisplay для управления знаками валюты

Опция signDisplay контролирует, когда знаки плюс и минус появляются при форматировании валюты. Передайте эту опцию при создании форматтера чисел для валюты.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  signDisplay: "always"
});

console.log(formatter.format(250.50));
// Вывод: "+$250.50"

console.log(formatter.format(-75.25));
// Вывод: "-$75.25"

Теперь положительные суммы отображаются со знаком плюс, делая депозиты и доходы явными, а не подразумеваемыми.

Понимание значений signDisplay для валюты

Опция signDisplay принимает пять значений. Каждое значение служит определённым целям в финансовых отображениях.

Значение auto для стандартного форматирования валюты

Значение "auto" является поведением по умолчанию. Оно отображает минус для отрицательных сумм, но не показывает знак для положительных.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  signDisplay: "auto"
});

console.log(formatter.format(1000));
// Вывод: "$1,000.00"

console.log(formatter.format(-500));
// Вывод: "-$500.00"

console.log(formatter.format(0));
// Вывод: "$0.00"

Используйте "auto" для отображения цен, балансов счетов и других абсолютных значений валюты, где отрицательные суммы требуют идентификации, а положительные предполагаются по умолчанию.

Значение always для отображения всех направлений транзакций

Значение "always" отображает знаки для всех сумм, включая положительные, отрицательные и нулевые.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  signDisplay: "always"
});

console.log(formatter.format(1000));
// Вывод: "+$1,000.00"

console.log(formatter.format(-500));
// Вывод: "-$500.00"

console.log(formatter.format(0));
// Вывод: "+$0.00"

Используйте "always" для историй транзакций, отчётов о прибылях и убытках, а также для лент активности счетов, где направление движения денег важно для каждой записи. Явный плюс уточняет, что положительные суммы представляют депозиты, доходы или поступления.

Значение exceptZero для выделения реальных изменений

Значение "exceptZero" отображает знаки для положительных и отрицательных сумм, но опускает знак для нуля.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  signDisplay: "exceptZero"
});

console.log(formatter.format(1000));
// Вывод: "+$1,000.00"

console.log(formatter.format(-500));
// Вывод: "-$500.00"

console.log(formatter.format(0));
// Вывод: "$0.00"

Используйте "exceptZero" для отображения изменений баланса, где ноль представляет отсутствие изменений. Это делает ноль визуально отличным от реальных прибылей или убытков. Торговые платформы и инвестиционные приложения используют этот формат для отображения изменений цен и изменений стоимости портфеля.

отрицательное значение для акцентирования долгов

"negative" отображает знак минус только для отрицательных сумм, исключая отрицательный ноль. Положительные суммы и ноль отображаются без знаков.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  signDisplay: "negative"
});

console.log(formatter.format(1000));
// Вывод: "$1,000.00"

console.log(formatter.format(-500));
// Вывод: "-$500.00"

console.log(formatter.format(0));
// Вывод: "$0.00"

Используйте "negative" для отображения балансов счетов, где отрицательные суммы представляют долги или перерасходы, требующие выделения. Отсутствие знака плюс для положительных балансов подчеркивает нормальность, в то время как отрицательные балансы привлекают внимание.

значение never для отображения абсолютных сумм

"never" отображает денежные суммы без каких-либо знаков, даже для отрицательных значений.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  signDisplay: "never"
});

console.log(formatter.format(1000));
// Вывод: "$1,000.00"

console.log(formatter.format(-500));
// Вывод: "$500.00"

console.log(formatter.format(0));
// Вывод: "$0.00"

Используйте "never" для отображения абсолютных сумм, где направление передается другими способами. Например, в списках транзакций с отдельными колонками для дебетов и кредитов или при использовании цветовой кодировки для обозначения положительных и отрицательных значений, удаление знака предотвращает избыточность информации.

Комбинирование signDisplay с бухгалтерским стилем

Форматирование валюты поддерживает бухгалтерскую нотацию, которая отображает отрицательные суммы в скобках. Установите currencySign в значение "accounting", чтобы включить этот формат.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  currencySign: "accounting"
});

console.log(formatter.format(1000));
// Вывод: "$1,000.00"

console.log(formatter.format(-500));
// Вывод: "($500.00)"

Бухгалтерский формат заключает отрицательные суммы в скобки вместо использования знака минус. Этот стиль часто используется в финансовых отчетах, бухгалтерском программном обеспечении и бизнес-отчетах.

Вы можете комбинировать бухгалтерскую нотацию с различными значениями signDisplay, чтобы контролировать, как отображаются положительные суммы, в то время как отрицательные суммы используют скобки.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  currencySign: "accounting",
  signDisplay: "always"
});

console.log(formatter.format(1000));
// Вывод: "+$1,000.00"

console.log(formatter.format(-500));
// Вывод: "($500.00)"

console.log(formatter.format(0));
// Вывод: "+$0.00"

С signDisplay: "always" положительные суммы отображаются со знаком плюс, в то время как отрицательные суммы продолжают использовать скобки. Этот формат хорошо подходит для отчетов о прибылях и убытках, где как прибыли, так и убытки должны быть четко идентифицированы.

С signDisplay: "exceptZero" ноль отображается без знака, в то время как положительные и отрицательные суммы используют свои соответствующие индикаторы.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  currencySign: "accounting",
  signDisplay: "exceptZero"
});

console.log(formatter.format(1000));
// Вывод: "+$1,000.00"

console.log(formatter.format(-500));
// Вывод: "($500.00)"

console.log(formatter.format(0));
// Вывод: "$0.00"

Эта комбинация подчеркивает фактические изменения, делая ноль визуально нейтральным.

Как работает signDisplay с режимами отображения валюты

Форматирование валюты поддерживает три режима отображения самой валюты. Опция currencyDisplay управляет тем, отображать ли валюту в виде символа, кода или названия.

Опция signDisplay работает одинаково во всех режимах отображения валюты.

const symbol = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  currencyDisplay: "symbol",
  signDisplay: "always"
});

console.log(symbol.format(100));
// Вывод: "+$100.00"

const code = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  currencyDisplay: "code",
  signDisplay: "always"
});

console.log(code.format(100));
// Вывод: "+USD 100.00"

const name = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  currencyDisplay: "name",
  signDisplay: "always"
});

console.log(name.format(100));
// Вывод: "+100.00 долларов США"

Знак отображается в соответствующем месте независимо от того, как отображается валюта. Это обеспечивает единообразное отображение знака во всех форматах валюты.

Позиционирование знака зависит от локали

Разные локали размещают знак в разных местах относительно символа валюты. JavaScript автоматически обрабатывает эти локально-специфические соглашения.

const enUS = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  signDisplay: "always"
});

console.log(enUS.format(100));
// Вывод: "+$100.00"

console.log(enUS.format(-100));
// Вывод: "-$100.00"

const frFR = new Intl.NumberFormat("fr-FR", {
  style: "currency",
  currency: "EUR",
  signDisplay: "always"
});

console.log(frFR.format(100));
// Вывод: "+100,00 €"

console.log(frFR.format(-100));
// Вывод: "-100,00 €"

В американском английском знак появляется перед символом валюты. Во французском языке знак появляется перед числом, а символ валюты — после. Форматировщик соблюдает эти локальные соглашения, учитывая ваш выбор signDisplay.

Некоторые локали размещают отрицательные знаки иначе, чем положительные, даже при использовании signDisplay: "always".

const nlNL = new Intl.NumberFormat("nl-NL", {
  style: "currency",
  currency: "EUR",
  signDisplay: "always"
});

console.log(nlNL.format(100));
// Вывод: "+€ 100,00"

console.log(nlNL.format(-100));
// Вывод: "-€ 100,00"

JavaScript гарантирует, что вывод соответствует правилам форматирования для каждой локали, сохраняя при этом видимость знака, которую вы указали.

Примеры использования управления знаком валюты в реальном мире

Различные финансовые контексты требуют разных стратегий отображения знаков.

Истории транзакций

Банковские приложения и платежные платформы отображают списки транзакций, где каждая запись показывает движение денег — поступление или расход. Используйте signDisplay: "always", чтобы явно указать направление каждой транзакции.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  signDisplay: "always"
});

const transactions = [
  { description: "Salary deposit", amount: 3500 },
  { description: "Rent payment", amount: -1200 },
  { description: "Grocery store", amount: -85.50 },
  { description: "Refund", amount: 25 }
];

transactions.forEach(transaction => {
  console.log(`${transaction.description}: ${formatter.format(transaction.amount)}`);
});
// Вывод:
// Salary deposit: +$3,500.00
// Rent payment: -$1,200.00
// Grocery store: -$85.50
// Refund: +$25.00

Явные знаки уточняют, увеличила или уменьшила каждая транзакция баланс счета.

Отчеты о прибылях и убытках

Финансовые отчеты показывают доходы и убытки с четкими положительными и отрицательными индикаторами. Используйте signDisplay: "always" с обозначением "accounting" для профессиональных финансовых отчетов.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  currencySign: "accounting",
  signDisplay: "always"
});

const financials = {
  revenue: 150000,
  expenses: -95000,
  netIncome: 55000
};

console.log(`Revenue: ${formatter.format(financials.revenue)}`);
// Вывод: Revenue: +$150,000.00

console.log(`Expenses: ${formatter.format(financials.expenses)}`);
// Вывод: Expenses: ($95,000.00)

console.log(`Net Income: ${formatter.format(financials.netIncome)}`);
// Вывод: Net Income: +$55,000.00

Этот формат соответствует бухгалтерским стандартам, делая как доходы, так и убытки понятными.

Индикаторы изменения баланса

Инвестиционные платформы и торговые приложения показывают, как изменялась стоимость счета с течением времени. Используйте signDisplay: "exceptZero", чтобы выделить фактические изменения, оставляя отсутствие изменений визуально нейтральным.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  signDisplay: "exceptZero"
});

const changes = [
  { period: "Today", change: 125.50 },
  { period: "This week", change: -45.75 },
  { period: "This month", change: 0 },
  { period: "This year", change: 1850 }
];

changes.forEach(item => {
  console.log(`${item.period}: ${formatter.format(item.change)}`);
});
// Вывод:
// Today: +$125.50
// This week: -$45.75
// This month: $0.00
// This year: +$1,850.00

Ноль отображается без знака, выделяя период без изменений.

Балансы счетов

Банковские приложения отображают текущие балансы счетов, где отрицательные значения указывают на перерасход. Используйте signDisplay: "negative", чтобы выделить долги, при этом положительные балансы отображаются как обычные.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  signDisplay: "negative"
});

const accounts = [
  { name: "Checking", balance: 2500 },
  { name: "Savings", balance: 15000 },
  { name: "Credit Card", balance: -850 }
];

accounts.forEach(account => {
  console.log(`${account.name}: ${formatter.format(account.balance)}`);
});
// Результат:
// Checking: $2,500.00
// Savings: $15,000.00
// Credit Card: -$850.00

Минусовый знак привлекает внимание к отрицательному балансу, в то время как положительные балансы отображаются без знаков.

Сравнение цен: абсолютные различия

Приложения для покупок и инструменты сравнения цен показывают, насколько отличаются цены между вариантами. Используйте signDisplay: "never" для отображения абсолютных различий в ценах, где направление не имеет значения.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  signDisplay: "never"
});

const comparisons = [
  { item: "Laptop A vs B", difference: -150 },
  { item: "Phone X vs Y", difference: 75 },
  { item: "Tablet M vs N", difference: -25 }
];

comparisons.forEach(comp => {
  console.log(`${comp.item}: ${formatter.format(comp.difference)} difference`);
});
// Результат:
// Laptop A vs B: $150.00 difference
// Phone X vs Y: $75.00 difference
// Tablet M vs N: $25.00 difference

Все суммы отображаются как положительные значения, показывая величину различий независимо от того, какой вариант дороже.

Комбинирование signDisplay с точностью десятичных знаков

Опция signDisplay работает со всеми другими параметрами форматирования валют. Вы можете управлять количеством десятичных знаков, округлением и отображением знаков одновременно.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  signDisplay: "always",
  minimumFractionDigits: 2,
  maximumFractionDigits: 2
});

console.log(formatter.format(1234.5));
// Результат: "+$1,234.50"

console.log(formatter.format(-89.1));
// Результат: "-$89.10"

Это обеспечивает единообразную точность десятичных знаков при явном отображении знаков для всех сумм.

Вы также можете комбинировать signDisplay с минимальным и максимальным количеством значимых цифр для научных или финансовых расчетов.

const formatter = new Intl.NumberFormat("en-US", {
  style: "currency",
  currency: "USD",
  signDisplay: "always",
  minimumSignificantDigits: 3,
  maximumSignificantDigits: 3
});

console.log(formatter.format(1234.567));
// Результат: "+$1,230"

console.log(formatter.format(-0.0456));
// Результат: "-$0.0456"

Форматер применяет правила значимых цифр, сохраняя при этом поведение отображения знаков, которое вы указали.

Что нужно помнить

Опция signDisplay в Intl.NumberFormat управляет отображением знаков плюс и минус в форматированных суммах валют. Используйте "always", чтобы показывать явные знаки для всех сумм, "exceptZero", чтобы скрыть знак для нуля, "auto" для поведения по умолчанию, "negative", чтобы показывать только минус, и "never", чтобы скрыть все знаки.

Выбирайте подходящее значение signDisplay в зависимости от вашего финансового контекста. Истории транзакций требуют явных знаков для всех сумм. Индикаторы изменения баланса выигрывают от визуальной нейтральности нуля. Балансы счетов хорошо работают с выделением только отрицательных значений. Для сравнения цен часто нужны абсолютные значения без знаков.

Комбинируйте signDisplay с бухгалтерской нотацией, режимами отображения валюты и опциями точности десятичных знаков, чтобы создать точный формат валюты, необходимый вашему финансовому приложению. JavaScript автоматически обрабатывает позиционирование знаков в зависимости от локали, соблюдая ваши предпочтения отображения знаков.