Единицы измерения в международной локализации основаны на стандартах
Unicode CLDR и реализуются через форматирование чисел в соответствии с
локалью и системой измерений. В JavaScript основным инструментом работы
с такими значениями является Intl.NumberFormat, который
поддерживает режим unit и позволяет формировать
локализованные представления физических величин, скоростей, объёмов,
информационных единиц и производных комбинаций.
Поддержка единиц включается через параметр
style: "unit". В этом режиме числовое значение
интерпретируется как величина с указанной размерностью, а строковое
представление формируется с учётом локали.
const formatter = new Intl.NumberFormat("ru-RU", {
style: "unit",
unit: "meter"
});
formatter.format(5);
// "5 м"
В разных локалях результат отличается не только по языку, но и по правилам сокращений и пробелов:
const en = new Intl.NumberFormat("en-US", { style: "unit", unit: "meter" });
en.format(5);
// "5 m"
Единицы определяются спецификацией ICU. Они группируются по категориям:
meter, kilometer,
centimeter, millimeter, milegram, kilogram, ounce,
poundliter, milliliter,
galloncelsius, fahrenheitkilometer-per-hour,
mile-per-hourjoule, kilowatt-hourbyte, kilobyte,
megabyte, gigabyteПример работы с разными единицами:
const distance = new Intl.NumberFormat("ru-RU", {
style: "unit",
unit: "kilometer"
});
distance.format(12.5);
// "12,5 км"
const speed = new Intl.NumberFormat("en-US", {
style: "unit",
unit: "mile-per-hour"
});
speed.format(65);
// "65 mph"
Поведение отображения регулируется параметром
unitDisplay, который задаёт уровень сокращения.
Наиболее распространённый вариант, использующий стандартные сокращения:
new Intl.NumberFormat("ru-RU", {
style: "unit",
unit: "kilogram",
unitDisplay: "short"
}).format(10);
// "10 кг"
Полное текстовое представление единицы:
new Intl.NumberFormat("en-US", {
style: "unit",
unit: "kilogram",
unitDisplay: "long"
}).format(10);
// "10 kilograms"
Максимально компактная форма, часто без пробела:
new Intl.NumberFormat("en-US", {
style: "unit",
unit: "kilogram",
unitDisplay: "narrow"
}).format(10);
// "10kg"
Встроенная система учитывает грамматические формы множественного числа в зависимости от локали. Это исключает необходимость ручной обработки склонений.
const ru = new Intl.NumberFormat("ru-RU", {
style: "unit",
unit: "meter"
});
ru.format(1);
// "1 м"
ru.format(2);
// "2 м"
ru.format(5);
// "5 м"
В английской локали различие отражается явно:
const en = new Intl.NumberFormat("en-US", {
style: "unit",
unit: "mile"
});
en.format(1);
// "1 mile"
en.format(2);
// "2 miles"
Некоторые единицы представляют собой комбинации базовых измерений. Они используются для выражения производных величин.
const speed = new Intl.NumberFormat("ru-RU", {
style: "unit",
unit: "kilometer-per-hour"
});
speed.format(90);
// "90 км/ч"
const speedEn = new Intl.NumberFormat("en-US", {
style: "unit",
unit: "mile-per-hour"
});
speedEn.format(55);
// "55 mph"
const data = new Intl.NumberFormat("en-US", {
style: "unit",
unit: "megabyte"
});
data.format(250);
// "250 MB"
Разные регионы используют различные системы измерений. Intl автоматически адаптирует отображение единиц к локали, но не выполняет автоматическое преобразование значений.
const usDistance = new Intl.NumberFormat("en-US", {
style: "unit",
unit: "kilometer"
});
usDistance.format(10);
// "10 km"
Значение остаётся неизменным, но формат отображения соответствует принятым соглашениям языка.
В некоторых случаях локаль влияет на выбор предпочтительной единицы
при форматировании через более высокоуровневые API, но
Intl.NumberFormat работает исключительно с уже заданной
единицей.
Температура поддерживается как отдельный класс единиц с учётом локальных стандартов.
const tempRu = new Intl.NumberFormat("ru-RU", {
style: "unit",
unit: "celsius"
});
tempRu.format(25);
// "25 °C"
const tempUs = new Intl.NumberFormat("en-US", {
style: "unit",
unit: "fahrenheit"
});
tempUs.format(77);
// "77°F"
Температурные единицы отличаются от других тем, что часто включают символ градуса как часть формата.
Информационные единицы подчиняются отдельным правилам округления и масштабирования, зависящим от реализации ICU.
const bytes = new Intl.NumberFormat("en-US", {
style: "unit",
unit: "byte",
unitDisplay: "long"
});
bytes.format(1024);
// "1,024 bytes"
В некоторых реализациях возможно автоматическое преобразование в
килобайты и мегабайты при использовании специализированных форматов
более высокого уровня, однако базовый Intl.NumberFormat
отображает значение строго в указанной единице.
Форматирование единиц подчиняется правилам округления, задаваемым
параметрами minimumFractionDigits и
maximumFractionDigits.
const formatter = new Intl.NumberFormat("ru-RU", {
style: "unit",
unit: "kilometer",
maximumFractionDigits: 2
});
formatter.format(12.3456);
// "12,35 км"
const formatterEn = new Intl.NumberFormat("en-US", {
style: "unit",
unit: "mile",
maximumFractionDigits: 1
});
formatterEn.format(3.1415);
// "3.1 mi"
Форматирование единиц применяется поверх числового значения без изменения его семантики. Это позволяет использовать единицы как слой представления:
function formatDistance(valueInMeters, locale) {
const formatter = new Intl.NumberFormat(locale, {
style: "unit",
unit: "meter",
maximumFractionDigits: 0
});
return formatter.format(valueInMeters);
}
formatDistance(1500, "ru-RU");
// "1 500 м"
Такой подход разделяет вычисления и отображение, сохраняя единообразие представления данных.
Поддержка конкретных единиц зависит от версии ICU в среде выполнения. Некоторые единицы могут отсутствовать в старых окружениях. При использовании неподдерживаемой единицы поведение может варьироваться: от выброса ошибки до деградации в числовой формат без единицы.
new Intl.NumberFormat("ru-RU", {
style: "unit",
unit: "unknown-unit"
});
Подобные случаи требуют проверки доступности единиц в целевой среде.
Режим unit в Intl.NumberFormat существует
параллельно с другими стилями форматирования:
decimalcurrencypercentКаждый стиль изменяет интерпретацию числа и набор применяемых правил. В отличие от валют, единицы не предполагают фиксированного масштаба или глобального стандарта конвертации внутри API.
new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD"
}).format(100);
new Intl.NumberFormat("en-US", {
style: "unit",
unit: "kilogram"
}).format(100);
Различие заключается в семантике: валюты включают финансовые правила, единицы — физические и технические измерения.
В интерфейсах с ограниченным пространством часто используется
unitDisplay: "narrow" совместно с округлением.
new Intl.NumberFormat("en-US", {
style: "unit",
unit: "kilobyte",
unitDisplay: "narrow",
maximumFractionDigits: 0
}).format(1536);
// "1,536KB"
Такие формы ориентированы на плотное размещение данных, например в таблицах или мобильных интерфейсах.