Как форматировать отрицательные валютные суммы в скобках по стандартам бухгалтерии?

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

Введение

В финансовой отчётности, бухгалтерских документах и балансах отрицательные валютные суммы показываются в скобках, а не со знаком минус. Например, убыток в пятьсот долларов будет записан как ($500.00) вместо -$500.00. Такой подход делает отрицательные значения более заметными, снижает риск пропустить убытки и соответствует принятым стандартам бухгалтерского учёта.

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

Почему в бухгалтерском учёте используются скобки

Традиция заключать отрицательные суммы в скобки появилась до эры компьютеров в бухгалтерии. Печатный минус мог быть маленьким, блеклым или его было легко пропустить в столбцах чисел. Скобки формируют чёткие границы вокруг отрицательных значений, делая их сразу заметными.

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

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

Как использовать формат accounting с currencySign

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

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

console.log(formatter.format(-1234.56));
// Output: "($1,234.56)"

console.log(formatter.format(1234.56));
// Output: "$1,234.56"

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

Опция currencySign влияет только на форматирование валюты. Необходимо также задать style: 'currency' и указать код currency, чтобы опция подействовала.

Сравнение стандартного и бухгалтерского форматов

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

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

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

console.log(standard.format(-500));
// Output: "-$500.00"

console.log(accounting.format(-500));
// Output: "($500.00)"

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

Если не задать опцию currencySign, форматтер по умолчанию ведёт себя как "standard".

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

console.log(formatter.format(-500));
// Output: "-$500.00"

Как отличается бухгалтерское оформление в разных локалях

В разных странах символ валюты и скобки могут располагаться по-разному — это зависит от местных правил. API Intl.NumberFormat автоматически учитывает такие отличия.

const currencies = [
  { locale: 'en-US', currency: 'USD' },
  { locale: 'de-DE', currency: 'EUR' },
  { locale: 'fr-FR', currency: 'EUR' },
  { locale: 'ja-JP', currency: 'JPY' }
];

currencies.forEach(({ locale, currency }) => {
  const formatter = new Intl.NumberFormat(locale, {
    style: 'currency',
    currency: currency,
    currencySign: 'accounting'
  });

  console.log(`${locale}: ${formatter.format(-1234.56)}`);
});

// Output:
// en-US: ($1,234.56)
// de-DE: (-1.234,56 €)
// fr-FR: (1 234,56 €)
// ja-JP: (¥-1,235)

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

В некоторых странах минус-знак ставится внутри скобок рядом с числом, в других — рядом с символом валюты. Форматтер сам учитывает такие нюансы согласно правилам локали.

Объединение бухгалтерского оформления с параметрами отображения знака

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

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

console.log(always.format(500));
// Output: "+$500.00"

console.log(always.format(-500));
// Output: "($500.00)"

С signDisplay: 'always' положительные суммы отображаются со знаком «+», а отрицательные по-прежнему в скобках. Это понятно показывает как прибыль, так и убытки.

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

console.log(never.format(500));
// Output: "$500.00"

console.log(never.format(-500));
// Output: "$500.00"

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

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

console.log(exceptZero.format(500));
// Output: "+$500.00"

console.log(exceptZero.format(-500));
// Output: "($500.00)"

console.log(exceptZero.format(0));
// Output: "$0.00"

С signDisplay: 'exceptZero' положительные суммы показываются со знаком «+», отрицательные — в скобках, а ноль отображается без какого-либо знака. Такой формат удобен для отчетов о прибылях и убытках, когда важно выделить изменения, оставляя ноль нейтральным.

Когда использовать бухгалтерский формат

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

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

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

const accounts = [
  { name: 'Cash', balance: 15000 },
  { name: 'Accounts Receivable', balance: -3500 },
  { name: 'Inventory', balance: 12000 },
  { name: 'Accounts Payable', balance: -8000 }
];

accounts.forEach(account => {
  const formatted = accountingFormatter.format(account.balance);
  console.log(`${account.name}: ${formatted}`);
});

// Output:
// Cash: $15,000.00
// Accounts Receivable: ($3,500.00)
// Inventory: $12,000.00
// Accounts Payable: ($8,000.00)

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

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

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

// For a shopping cart or refund:
console.log(standardFormatter.format(-25.50));
// Output: "-$25.50"

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

Поддержка бухгалтерского формата в браузерах

Опция currencySign: "accounting" поддерживается во всех современных браузерах. Chrome, Edge, Firefox, Safari и их мобильные версии поддерживают эту функцию в выпусках, начиная с 2019 года.

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

function formatCurrency(amount) {
  try {
    const formatter = new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: 'USD',
      currencySign: 'accounting'
    });
    return formatter.format(amount);
  } catch (error) {
    // Fallback for browsers without accounting support
    const formatter = new Intl.NumberFormat('en-US', {
      style: 'currency',
      currency: 'USD'
    });
    return formatter.format(amount);
  }
}

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