Система именования единиц измерения в JavaScript опирается на стандартизированные коды CLDR (Unicode Common Locale Data Repository), которые позволяют унифицировать отображение физических величин, скоростей, объёмов, расстояний и других измеримых сущностей в зависимости от языка и региональных правил.
В рамках Intl API работа с единицами измерения реализуется через два основных механизма:
Intl.DisplayNames с типом "unit"Intl.NumberFormat с опцией
style: "unit"Оба подхода решают задачу локализованного отображения единиц, но имеют различную область применения и уровень гибкости.
Единицы измерения в Intl API задаются строковыми идентификаторами, соответствующими CLDR Unit Identifiers. Эти идентификаторы не являются произвольными и должны соответствовать спецификации.
Примеры базовых единиц:
"meter""kilometer""gram""kilogram""liter""second""minute""hour""celsius""fahrenheit""mile""yard"Составные единицы формируются через дефис:
"kilometer-per-hour""mile-per-hour""meter-per-second""kilowatt-hour""liter-per-100-kilometer"Такая система позволяет описывать как простые, так и производные физические величины.
Intl.DisplayNames предназначен для получения
локализованных текстовых названий единиц без форматирования чисел. Он
возвращает строковое представление единицы в выбранной локали.
const units = new Intl.DisplayNames('ru', { type: 'unit' });
units.of('meter');
// "метр"
units.of('kilometer');
// "километр"
units.of('mile-per-hour');
// "мили в час"
Один и тот же идентификатор возвращает разные строки в зависимости от языка:
new Intl.DisplayNames('en', { type: 'unit' }).of('kilogram');
// "kilogram"
new Intl.DisplayNames('ru', { type: 'unit' }).of('kilogram');
// "килограмм"
Система учитывает грамматические нормы языка, включая склонения и предлоги в составных единицах.
Intl.DisplayNames предоставляет только название единицы,
но не работает с числом. Он не учитывает:
Поэтому он используется преимущественно для интерфейсов, где требуется справочное отображение единицы, а не форматирование измерений.
Для полноценного форматирования числовых значений с единицами
используется Intl.NumberFormat.
const formatter = new Intl.NumberFormat('ru', {
style: 'unit',
unit: 'kilometer'
});
formatter.format(5);
// "5 км"
В отличие от DisplayNames, здесь происходит полное
форматирование числа вместе с единицей.
Опция unit определяет конкретную единицу измерения.
Поддерживаются:
"meter""kilometer""centimeter""mile""gram""kilogram""ounce""pound""liter""milliliter""gallon""second""minute""hour""day""mile-per-hour""kilometer-per-hour"Опция unitDisplay управляет степенью сокращения
единицы:
"long"Полное текстовое представление:
new Intl.NumberFormat('en', {
style: 'unit',
unit: 'kilometer',
unitDisplay: 'long'
}).format(3);
// "3 kilometers"
"short"Сокращённый вариант:
// "3 km"
"narrow"Максимально компактный формат:
// "3km"
Разница между short и narrow особенно
заметна в языках с длинными локализованными обозначениями.
Intl.NumberFormat учитывает правила множественного
числа, характерные для конкретного языка.
const f = new Intl.NumberFormat('ru', {
style: 'unit',
unit: 'kilometer'
});
f.format(1); // "1 километр"
f.format(2); // "2 километра"
f.format(5); // "5 километров"
Морфологические формы выбираются автоматически на основе правил plural rules CLDR.
Intl поддерживает сложные единицы, описывающие отношения величин.
new Intl.NumberFormat('en', {
style: 'unit',
unit: 'mile-per-hour'
}).format(60);
// "60 mph"
new Intl.NumberFormat('en', {
style: 'unit',
unit: 'liter-per-100-kilometer'
}).format(7.5);
// "7.5 L/100km"
Составные единицы особенно полезны в автомобильных, научных и инженерных интерфейсах.
В разных локалях единицы могут иметь различные формы:
Например:
new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'celsius'
}).format(25);
// "25°C"
new Intl.NumberFormat('ru', {
style: 'unit',
unit: 'celsius'
}).format(25);
// "25 °C"
Различие может быть как в пробелах, так и в использовании символов.
Unit identifiers чувствительны к точному написанию. Следует учитывать:
Некорректные значения приводят к ошибкам или игнорированию параметров.
Создание экземпляра Intl.NumberFormat или
Intl.DisplayNames является затратной операцией. В
высоконагруженных сценариях экземпляры обычно кешируются:
Несмотря на широкую поддержку, существуют ограничения:
При смене языка все единицы автоматически пересчитываются:
Это позволяет строить интерфейсы без ручного управления локализацией единиц.