Форматирование единиц измерения в экосистеме FormatJS базируется на
стандарте ECMAScript Internationalization API (Intl), в частности на
возможностях Intl.NumberFormat с параметром
style: "unit". Этот механизм опирается на данные CLDR
(Unicode Common Locale Data Repository), что обеспечивает корректное
локализованное отображение физических величин, размеров, скорости,
температуры, объёма данных и других измеряемых значений.
В основе лежит форматирование числа вместе с единицей измерения:
new Intl.NumberFormat("ru-RU", {
style: "unit",
unit: "kilometer",
unitDisplay: "long"
}).format(5);
Результат:
5 километров
Параметр style: "unit" переключает форматирование числа
в режим измеряемой величины. В отличие от обычного числового вывода,
здесь число и единица рассматриваются как единая лингвистическая
конструкция.
unit определяет конкретную физическую или логическую
единицу измерения. Поддержка зависит от реализации ICU и может
включать:
meter, kilometer,
centimeter, milekilogram, gram,
poundliter, milliliter,
cubic-meterkilometer-per-hour,
mile-per-hourcelsius, fahrenheitbyte, kilobyte,
megabyte, gigabytesecond, minute, hour,
dayПример:
new Intl.NumberFormat("en-US", {
style: "unit",
unit: "mile-per-hour"
}).format(120);
Вывод:
120 miles per hour
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 метра
Система учитывает правила множественного числа, характерные для языка. Это невозможно корректно реализовать простым конкатенированием строк.
В FormatJS интеграция с React реализуется через
react-intl, где используется компонент
FormattedNumber.
import { FormattedNumber } from "react-intl";
<FormattedNumber
value={150}
style="unit"
unit="kilobyte"
/>
Результат зависит от локали:
150 KB150 КБДополнительно поддерживается управление отображением:
<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, а не вручную.
Единицы измерения в 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.
В средах с ограниченной поддержкой Intl поведение может деградировать до простого вывода числа:
// fallback поведение
"5"
По этой причине библиотеки FormatJS часто используют полифилы
@formatjs/intl-numberformat для обеспечения единообразия
между средами.
При использовании unit-формата важно учитывать несколько особенностей:
Такая модель делает unit-формат частью международного стандарта представления измеримых значений, а не просто текстовой конкатенацией.
Для систематизации можно выделить несколько устойчивых категорий:
Линейные размеры
Масса
Объём
Скорость
Температура
Данные
Время