Единицы измерения

Единицы измерения в международной локализации основаны на стандартах 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, mile
  • масса: gram, kilogram, ounce, pound
  • объём: liter, milliliter, gallon
  • температура: celsius, fahrenheit
  • скорость: kilometer-per-hour, mile-per-hour
  • энергия: joule, kilowatt-hour
  • цифровые данные: byte, 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, который задаёт уровень сокращения.

short

Наиболее распространённый вариант, использующий стандартные сокращения:

new Intl.NumberFormat("ru-RU", {
  style: "unit",
  unit: "kilogram",
  unitDisplay: "short"
}).format(10);
// "10 кг"

long

Полное текстовое представление единицы:

new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "kilogram",
  unitDisplay: "long"
}).format(10);
// "10 kilograms"

narrow

Максимально компактная форма, часто без пробела:

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"
});

Подобные случаи требуют проверки доступности единиц в целевой среде.

Взаимодействие с другими режимами Intl

Режим unit в Intl.NumberFormat существует параллельно с другими стилями форматирования:

  • decimal
  • currency
  • percent

Каждый стиль изменяет интерпретацию числа и набор применяемых правил. В отличие от валют, единицы не предполагают фиксированного масштаба или глобального стандарта конвертации внутри 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"

Такие формы ориентированы на плотное размещение данных, например в таблицах или мобильных интерфейсах.