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

Форматирование единиц измерения в экосистеме FormatJS базируется на стандарте ECMAScript Internationalization API (Intl), в частности на возможностях Intl.NumberFormat с параметром style: "unit". Этот механизм опирается на данные CLDR (Unicode Common Locale Data Repository), что обеспечивает корректное локализованное отображение физических величин, размеров, скорости, температуры, объёма данных и других измеряемых значений.

Основная концепция unit-формата

В основе лежит форматирование числа вместе с единицей измерения:

new Intl.NumberFormat("ru-RU", {
  style: "unit",
  unit: "kilometer",
  unitDisplay: "long"
}).format(5);

Результат:

5 километров

Параметр style: "unit" переключает форматирование числа в режим измеряемой величины. В отличие от обычного числового вывода, здесь число и единица рассматриваются как единая лингвистическая конструкция.

Параметр unit

unit определяет конкретную физическую или логическую единицу измерения. Поддержка зависит от реализации ICU и может включать:

  • длину: meter, kilometer, centimeter, mile
  • массу: kilogram, gram, pound
  • объём: liter, milliliter, cubic-meter
  • скорость: kilometer-per-hour, mile-per-hour
  • температура: celsius, fahrenheit
  • цифровые данные: byte, kilobyte, megabyte, gigabyte
  • время: second, minute, hour, day

Пример:

new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "mile-per-hour"
}).format(120);

Вывод:

120 miles per hour

Параметр unitDisplay

unitDisplay управляет формой записи единицы измерения:

  • "long" — полное слово
  • "short" — сокращённая форма
  • "narrow" — максимально компактная форма

Примеры:

const value = 10;

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

new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "kilometer",
  unitDisplay: "short"
}).format(value);
// 10 km

new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "kilometer",
  unitDisplay: "narrow"
}).format(value);
// 10km

Локаль оказывает прямое влияние на форму единиц: в разных языках сокращения и грамматические конструкции отличаются.

Локализация и грамматика единиц

Особенность unit-формата заключается в том, что единица измерения не просто добавляется к числу, а интегрируется в грамматическую структуру языка.

Например:

new Intl.NumberFormat("ru-RU", {
  style: "unit",
  unit: "meter"
}).format(1);
1 метр
new Intl.NumberFormat("ru-RU", {
  style: "unit",
  unit: "meter"
}).format(2);
2 метра

Система учитывает правила множественного числа, характерные для языка. Это невозможно корректно реализовать простым конкатенированием строк.

Единицы измерения и React-Intl

В FormatJS интеграция с React реализуется через react-intl, где используется компонент FormattedNumber.

import { FormattedNumber } from "react-intl";

<FormattedNumber
  value={150}
  style="unit"
  unit="kilobyte"
/>

Результат зависит от локали:

  • en-US: 150 KB
  • ru-RU: 150 КБ

Дополнительно поддерживается управление отображением:

<FormattedNumber
  value={72}
  style="unit"
  unit="fahrenheit"
  unitDisplay="long"
/>

Результат:

72 degrees Fahrenheit

Температурные единицы

Температура является частным случаем единиц измерения, где особенно важна локализация терминов.

new Intl.NumberFormat("en-GB", {
  style: "unit",
  unit: "celsius"
}).format(25);
25 degrees Celsius
new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "fahrenheit"
}).format(25);
25 degrees Fahrenheit

Система автоматически добавляет слово degrees там, где это требуется языковой нормой.

Цифровые единицы и байты

Работа с информационными объёмами реализуется через специализированные единицы:

new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "megabyte",
  unitDisplay: "short"
}).format(64);
64 MB

При этом важно учитывать, что библиотека не выполняет автоматическое масштабирование значений (например, байты → килобайты). Масштабирование должно быть реализовано отдельно:

const bytes = 1048576;

new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "megabyte"
}).format(bytes / 1048576);
1 MB

Скорость и составные единицы

Составные единицы поддерживают дефисную форму записи:

new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "kilometer-per-hour"
}).format(90);
90 kilometers per hour
new Intl.NumberFormat("ru-RU", {
  style: "unit",
  unit: "meter-per-second"
}).format(10);
10 метров в секунду

Такие единицы формируются на основе предопределённых шаблонов ICU, а не вручную.

Связь с ICU MessageFormat

Единицы измерения в FormatJS существуют отдельно от ICU MessageFormat синтаксиса, однако часто используются совместно с сообщениями:

import { defineMessages } from "react-intl";

const messages = defineMessages({
  speed: {
    id: "speed.label",
    defaultMessage: "Скорость: {value, number, unit}"
  }
});

Хотя прямой unit-синтаксис в ICU message не является стандартным, числовое форматирование с unit обычно внедряется через FormattedNumber или Intl.NumberFormat.

Поведение при отсутствии поддержки unit

В средах с ограниченной поддержкой Intl поведение может деградировать до простого вывода числа:

// fallback поведение
"5"

По этой причине библиотеки FormatJS часто используют полифилы @formatjs/intl-numberformat для обеспечения единообразия между средами.

Практические особенности реализации

При использовании unit-формата важно учитывать несколько особенностей:

  • единица всегда задаётся строкой из стандартизированного набора ICU
  • локализация единиц зависит от CLDR, а не от ручных переводов
  • автоматическое преобразование масштаба отсутствует
  • форматирование включает грамматическую адаптацию под язык
  • поддержка различается между браузерами и Node.js версиями

Такая модель делает unit-формат частью международного стандарта представления измеримых значений, а не просто текстовой конкатенацией.

Типовые группы единиц

Для систематизации можно выделить несколько устойчивых категорий:

Линейные размеры

  • meter
  • kilometer
  • centimeter
  • mile

Масса

  • gram
  • kilogram
  • ounce
  • pound

Объём

  • liter
  • milliliter

Скорость

  • meter-per-second
  • kilometer-per-hour
  • mile-per-hour

Температура

  • celsius
  • fahrenheit

Данные

  • byte
  • kilobyte
  • megabyte
  • gigabyte

Время

  • second
  • minute
  • hour
  • day