Работа с валютами в интернационализированных интерфейсах требует
строгого соблюдения локальных правил форматирования: символ валюты, его
позиция, разделители разрядов, округление и правила отображения
отрицательных значений зависят от локали. В экосистеме FormatJS
финансовое форматирование опирается на стандарт ECMAScript
Internationalization API (Intl), а именно на
Intl.NumberFormat с параметром
style: "currency".
Библиотека FormatJS расширяет и стабилизирует работу с i18n в JavaScript-приложениях, предоставляя унифицированные инструменты поверх нативных API браузера и Node.js. Основой валютного форматирования является спецификация ECMA-402.
Официальная документация и исходный код: FormatJS Documentation FormatJS GitHub
Форматирование денежных значений выполняется через:
new Intl.NumberFormat(locale, {
style: 'currency',
currency: 'USD'
}).format(1234.56);
Ключевой параметр — currency, определяющий ISO-код
валюты.
Пример:
const usd = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
});
usd.format(1234.56); // $1,234.56
const eur = new Intl.NumberFormat('de-DE', {
style: 'currency',
currency: 'EUR'
});
eur.format(1234.56); // 1.234,56 €
Различие между локалями проявляется не только в символах, но и в порядке отображения и разделителях.
В контексте FormatJS работа с валютами может происходить через несколько уровней:
Intl.NumberFormatreact-intlОсновная задача FormatJS — обеспечить одинаковое поведение
форматирования во всех окружениях, включая старые браузеры, где
Intl может быть неполным.
ISO 4217 код валюты:
currency: 'USD' // доллар США
currency: 'EUR' // евро
currency: 'JPY' // японская иена
Неверный код вызывает RangeError.
Определяет способ отображения валюты:
"symbol" — $ / €"code" — USD / EUR"name" — US dollars / euros"narrowSymbol" — компактный символ (например, $ без
уточнений)Примеры:
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
currencyDisplay: 'symbol'
}).format(1000);
// $1,000.00
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
currencyDisplay: 'code'
}).format(1000);
// USD 1,000.00
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
currencyDisplay: 'name'
}).format(1000);
// 1,000.00 US dollars
Разные локали влияют на:
Пример сравнения:
const value = 1234567.89;
new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(value);
// $1,234,567.89
new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR' }).format(value);
// 1 234 567,89 €
new Intl.NumberFormat('ru-RU', { style: 'currency', currency: 'RUB' }).format(value);
// 1 234 567,89 ₽
FormatJS использует те же CLDR-данные (Unicode Common Locale Data Repository), что обеспечивает согласованность между платформами.
FormatJS активно использует ICU-синтаксис через
react-intl и intl-messageformat. Валюта может
быть частью локализованных сообщений.
Пример:
import { FormattedNumber } from 'react-intl';
<FormattedNumber
value={2500}
style="currency"
currency="EUR"
/>
В ICU-строках:
Баланс: {amount, number, currency}
С параметрами:
{
amount: 1500
}
При этом формат валюты зависит от текущей локали контекста.
Валюты требуют строгого контроля дробной части.
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
minimumFractionDigits: 0,
maximumFractionDigits: 0
}).format(1234.56);
// $1,235
Особенности:
ECMA-402 автоматически применяет стандартные правила валют:
new Intl.NumberFormat('ja-JP', {
style: 'currency',
currency: 'JPY'
}).format(5000);
// ¥5,000
Для интерфейсов с большими числами используется компактная запись:
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
notation: 'compact'
}).format(1500000);
// $1.5M
new Intl.NumberFormat('ru-RU', {
style: 'currency',
currency: 'RUB',
notation: 'compact'
}).format(1500000);
// 1,5 млн ₽
| Локаль | symbol | code | name |
|---|---|---|---|
| en-US | $1,000 | USD 1,000 | 1,000 US dollars |
| de-DE | 1.000 € | EUR 1.000 | 1.000 Euro |
| ja-JP | ¥1,000 | JPY 1,000 | 1,000 Japanese yen |
FormatJS обеспечивает:
Intlreact-intlВалютное форматирование является одним из ключевых сценариев, где различия платформ особенно заметны.
Иногда требуется отклониться от стандартов локали.
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
currencyDisplay: 'narrowSymbol',
useGrouping: false
}).format(1000000);
// $1000000
Разные локали по-разному отображают отрицательные суммы:
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
}).format(-500);
// -$500.00
Альтернативные форматы:
new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD',
currencySign: 'accounting'
}).format(-500);
// ($500.00)
При использовании FormatJS и Intl возникают типовые
ограничения:
В React-приложениях FormatJS часто используется через
react-intl:
import { IntlProvider, FormattedNumber } from 'react-intl';
<IntlProvider locale="en-US">
<FormattedNumber
value={1234.56}
style="currency"
currency="USD"
/>
</IntlProvider>
Динамическое изменение локали автоматически пересчитывает валютное отображение без ручной логики.
FormatJS поддерживает SSR-сценарии:
const formatter = new Intl.NumberFormat('en-US', {
style: 'currency',
currency: 'USD'
});
formatter.format(999.99);
Сервер возвращает уже локализованную строку, уменьшая нагрузку клиента.
Валюта становится частью UI-логики:
FormatJS обеспечивает единообразие отображения вне зависимости от источника данных и региона пользователя.