Ручное формирование строк для чисел, дат, валют и списков в JavaScript приводит к множеству скрытых ошибок, связанных с локалями, правилами отображения и региональными стандартами. Конкатенация строк и самописные функции быстро усложняются при поддержке нескольких языков и форматов.
Типичный пример ручного форматирования чисел:
function formatPrice(value) {
return value.toFixed(2) + " $";
}
Подобный подход игнорирует локаль, порядок символов валюты, разделители тысяч и правила округления, которые отличаются в разных регионах.
Для даты аналогичная проблема:
function formatDate(date) {
return date.getDate() + "." + (date.getMonth() + 1) + "." + date.getFullYear();
}
Такое представление не учитывает различия между форматами
DD.MM.YYYY, MM/DD/YYYY, порядком компонентов и
локальными стандартами отображения времени.
Intl.NumberFormat предоставляет стандартизированный
способ отображения чисел с учётом локали.
const formatter = new Intl.NumberFormat("ru-RU");
formatter.format(1234567.89); // "1 234 567,89"
Ключевые возможности:
const priceFormatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD"
});
priceFormatter.format(99.99); // "$99.99"
В других локалях результат изменяется без изменения кода:
new Intl.NumberFormat("de-DE", {
style: "currency",
currency: "EUR"
}).format(99.99); // "99,99 €"
new Intl.NumberFormat("en-US", {
style: "percent"
}).format(0.42); // "42%"
new Intl.NumberFormat("en-US", {
minimumFractionDigits: 0,
maximumFractionDigits: 2
}).format(12.3456); // "12.35"
Intl.DateTimeFormat устраняет необходимость вручную
собирать строки дат и времени.
const dt = new Intl.DateTimeFormat("ru-RU");
dt.format(new Date());
new Intl.DateTimeFormat("en-GB", {
year: "numeric",
month: "long",
day: "2-digit"
}).format(new Date());
Результат зависит от локали и настроек, но структура остаётся консистентной.
new Intl.DateTimeFormat("en-US", {
hour: "2-digit",
minute: "2-digit"
}).format(new Date());
new Intl.DateTimeFormat("en-US", {
timeZone: "UTC",
year: "numeric",
month: "2-digit",
day: "2-digit"
}).format(new Date());
Ручное преобразование через getTimezoneOffset заменяется
декларативной настройкой.
Отображение относительного времени (например, “3 дня назад”) часто реализуется вручную через разницу дат.
function formatAgo(days) {
return days + " days ago";
}
Intl.RelativeTimeFormat заменяет такие конструкции:
const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });
rtf.format(-3, "day"); // "3 days ago"
rtf.format(2, "hour"); // "in 2 hours"
Поддерживаемые единицы:
Склейка строк через join не учитывает локальные союзы и
правила перечислений.
["яблоко", "груша", "слива"].join(", ");
Intl.ListFormat корректно оформляет списки:
new Intl.ListFormat("ru", { style: "long", type: "conjunction" })
.format(["яблоко", "груша", "слива"]);
Возможные режимы:
conjunction — и/and спискиdisjunction — или/or спискиunit — единицы измеренияРучная реализация множественных форм числительных часто выглядит громоздко:
function getLabel(n) {
if (n === 1) return "item";
return "items";
}
Intl.PluralRules формализует правила:
const pr = new Intl.PluralRules("ru");
pr.select(1); // "one"
pr.select(2); // "few"
pr.select(5); // "many"
Далее правила связываются с локализованными строками.
Использование Intl позволяет централизовать
форматирование через фабрики:
const formatters = {
number: new Intl.NumberFormat("ru-RU"),
currency: new Intl.NumberFormat("ru-RU", {
style: "currency",
currency: "RUB"
}),
date: new Intl.DateTimeFormat("ru-RU"),
};
Такой подход исключает дублирование логики форматирования в бизнес-коде.
Ручные конструкции типа:
if (locale === "ru") { ... }
else if (locale === "en") { ... }
заменяются передачей локали в Intl:
new Intl.NumberFormat(locale).format(value);
new Intl.DateTimeFormat(locale).format(date);
Логика выбора представления переносится в движок ECMAScript.
Форматирование перестаёт зависеть от:
Пример комплексного вывода без ручной логики:
const locale = "de-DE";
const price = new Intl.NumberFormat(locale, {
style: "currency",
currency: "EUR"
}).format(12345.67);
const date = new Intl.DateTimeFormat(locale, {
dateStyle: "medium"
}).format(new Date());
Intl работает в браузерах и Node.js с единым API, что
устраняет необходимость платформенных ветвлений.
globalThis.Intl.NumberFormat
globalThis.Intl.DateTimeFormat
Это делает форматирование независимым от UI-слоя, серверной среды или сборщика.
Самописные библиотеки форматирования часто дублируют функциональность стандартного API:
Использование Intl устраняет необходимость в подобных
утилитах и снижает вероятность ошибок в краевых случаях, связанных с
региональными стандартами отображения данных.