Как форматировать измерения, такие как 5 километров или 10 фунтов
Отображайте расстояние, вес, температуру и другие измерения с учетом локального формата и единиц
Введение
Измерения передают количественные значения с единицами, которые придают им смысл. Пять километров указывают на расстояние, десять фунтов — на вес, а двадцать градусов Цельсия — на температуру. Приложения, отображающие измерения, должны показывать как числовое значение, так и единицу измерения в формате, понятном пользователям.
Разные локали форматируют измерения по-разному. Американцы пишут "5 km" или "5 kilometers" в зависимости от контекста. Немцы могут писать "5 km" с другими правилами расстановки пробелов. Одно и то же измерение может быть представлено как "5 km", "5km" или "5 kilometers" в зависимости от локали и желаемой степени подробности. В некоторых регионах используются метрические единицы, в других — имперские, но форматирование единиц также варьируется в зависимости от локали.
JavaScript предоставляет API Intl.NumberFormat для форматирования измерений с учетом локали и соответствующего отображения единиц. В этом уроке объясняется, как форматировать измерения, такие как расстояние, вес, температура, объем и скорость, с правильным отображением единиц для любой локали.
Измерения нуждаются в единицах для контекста
Числа без единиц теряют смысл во многих контекстах. Число 5 может означать 5 километров, 5 миль, 5 метров или 5 футов. Пользователи не могут интерпретировать значение без указания единицы измерения.
Единицы должны отображаться последовательно с числовым значением. Когда вы пишете "5 километров", единица "километров" является важной информацией. Когда вы пишете "10 фунтов", единица "фунтов" идентифицирует измерение как вес, а не валюту.
Для одного и того же типа измерений существуют разные системы единиц. Расстояние можно измерять в километрах, милях, метрах, футах или других единицах. Вес можно измерять в килограммах, фунтах, унциях или граммах. Температуру можно измерять в градусах Цельсия, Фаренгейта или Кельвина. Приложения должны форматировать используемую систему единиц так, чтобы она соответствовала ожиданиям пользователей.
Форматирование единиц с помощью Intl.NumberFormat
Intl.NumberFormat создаёт форматировщик единиц, если в параметрах передать style: 'unit'. Также необходимо указать, какую единицу форматировать, используя параметр unit с идентификатором единицы.
const formatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer'
});
console.log(formatter.format(5));
// Вывод: "5 km"
Это создаёт форматировщик для американского английского, который отображает значения в километрах. Метод format() преобразует число в строку с сокращением единицы "километр".
Параметр unit принимает стандартизированные идентификаторы единиц. Эти идентификаторы используют строчные слова, разделённые дефисами. К распространённым идентификаторам относятся kilometer, meter, mile, pound, kilogram, celsius, fahrenheit, liter и gallon.
const distanceFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer'
});
const weightFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'pound'
});
console.log(distanceFormatter.format(5));
// Вывод: "5 km"
console.log(weightFormatter.format(10));
// Вывод: "10 lb"
Каждый форматировщик автоматически применяет соответствующее сокращение единицы для указанного идентификатора. Вам не нужно знать, какое сокращение соответствует каждой единице.
Локаль определяет форматирование единиц
Параметр локали управляет тем, как форматируются единицы, включая пробелы, разделители и сокращения. Одна и та же единица может давать разный результат в зависимости от локали.
const usFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer'
});
const deFormatter = new Intl.NumberFormat('de-DE', {
style: 'unit',
unit: 'kilometer'
});
const frFormatter = new Intl.NumberFormat('fr-FR', {
style: 'unit',
unit: 'kilometer'
});
console.log(usFormatter.format(5));
// Вывод: "5 km"
console.log(deFormatter.format(5));
// Вывод: "5 km"
console.log(frFormatter.format(5));
// Вывод: "5 km"
Хотя километры используют схожие сокращения в разных локалях, правила пробелов и разделителей могут отличаться. API Intl автоматически обрабатывает эти правила форматирования, зависящие от локали.
Настройка подробности отображения блока управления
Опция unitDisplay управляет тем, как единицы измерения отображаются: в сокращённой, полной или минимальной форме. Опция принимает три значения: "short" для сокращений, "long" для полных названий единиц и "narrow" для минимального отображения.
const shortFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer',
unitDisplay: 'short'
});
const longFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer',
unitDisplay: 'long'
});
const narrowFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer',
unitDisplay: 'narrow'
});
console.log(shortFormatter.format(5));
// Вывод: "5 km"
console.log(longFormatter.format(5));
// Вывод: "5 kilometers"
console.log(narrowFormatter.format(5));
// Вывод: "5km"
Формат short использует стандартные сокращения, такие как "km" или "lb". Формат long использует полные названия единиц, такие как "kilometers" или "pounds". Формат narrow использует минимальное отображение с уменьшенными или отсутствующими пробелами. По умолчанию используется short, если вы не указываете unitDisplay.
Локаль влияет на то, как отображаются полные названия единиц. Полные названия единиц переводятся и адаптируются к грамматическим правилам каждого языка.
const enFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer',
unitDisplay: 'long'
});
const deFormatter = new Intl.NumberFormat('de-DE', {
style: 'unit',
unit: 'kilometer',
unitDisplay: 'long'
});
const esFormatter = new Intl.NumberFormat('es-ES', {
style: 'unit',
unit: 'kilometer',
unitDisplay: 'long'
});
console.log(enFormatter.format(5));
// Вывод: "5 kilometers"
console.log(deFormatter.format(5));
// Вывод: "5 Kilometer"
console.log(esFormatter.format(5));
// Вывод: "5 kilómetros"
Каждая локаль предоставляет соответствующий перевод и грамматическую форму для названия единицы.
Форматирование измерений веса
Для измерений веса используются идентификаторы единиц, такие как pound, kilogram, ounce и gram. Эти идентификаторы работают так же, как и единицы расстояния.
const poundFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'pound'
});
const kilogramFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilogram'
});
console.log(poundFormatter.format(10));
// Вывод: "10 lb"
console.log(kilogramFormatter.format(10));
// Вывод: "10 kg"
Вы можете форматировать вес в полной форме для отображения полных названий единиц.
const formatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'pound',
unitDisplay: 'long'
});
console.log(formatter.format(1));
// Вывод: "1 pound"
console.log(formatter.format(10));
// Вывод: "10 pounds"
Форматировщик автоматически обрабатывает единственное и множественное число в зависимости от значения. Одна фунт используется в единственном числе, а десять фунтов — во множественном.
Форматирование измерений температуры
Измерения температуры используют идентификаторы единиц, такие как celsius и fahrenheit. Эти единицы форматируются с символами градусов в краткой форме.
const celsiusFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'celsius'
});
const fahrenheitFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'fahrenheit'
});
console.log(celsiusFormatter.format(20));
// Вывод: "20°C"
console.log(fahrenheitFormatter.format(68));
// Вывод: "68°F"
Длинная форма отображает полные названия температурных шкал.
const celsiusFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'celsius',
unitDisplay: 'long'
});
const fahrenheitFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'fahrenheit',
unitDisplay: 'long'
});
console.log(celsiusFormatter.format(20));
// Вывод: "20 градусов Цельсия"
console.log(fahrenheitFormatter.format(68));
// Вывод: "68 градусов Фаренгейта"
Форматирование температуры автоматически включает соответствующую терминологию для каждой шкалы.
Форматирование измерений объема
Измерения объема используют идентификаторы единиц, такие как liter, gallon, milliliter и fluid-ounce. Они работают так же, как и другие типы единиц.
const literFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'liter'
});
const gallonFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'gallon'
});
console.log(literFormatter.format(2));
// Вывод: "2 L"
console.log(gallonFormatter.format(2));
// Вывод: "2 gal"
Единицы объема также поддерживают отображение в длинной форме с учетом орфографии, специфичной для локали.
const usFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'liter',
unitDisplay: 'long'
});
const gbFormatter = new Intl.NumberFormat('en-GB', {
style: 'unit',
unit: 'liter',
unitDisplay: 'long'
});
console.log(usFormatter.format(2));
// Вывод: "2 литра"
console.log(gbFormatter.format(2));
// Вывод: "2 литра"
В британском английском используется "litres", а в американском английском — "liters".
Форматирование составных единиц
Составные единицы объединяют две простые единицы с отношением "на". Измерения скорости, такие как мили в час или километры в час, используют составные единицы. Измерения топливной эффективности, такие как литры на 100 километров, также используют составные единицы.
Идентификаторы составных единиц соединяют две простые единицы с помощью -per-. Например, mile-per-hour объединяет мили и часы, а kilometer-per-hour — километры и часы.
const mphFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'mile-per-hour'
});
const kphFormatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer-per-hour'
});
console.log(mphFormatter.format(60));
// Вывод: "60 миль/ч"
console.log(kphFormatter.format(100));
// Вывод: "100 км/ч"
Каждая составная единица форматируется с соответствующей аббревиатурой, объединяющей обе части единицы.
Длинная форма отображает составные единицы с полными названиями и предлогами, соответствующими локали.
const formatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'mile-per-hour',
unitDisplay: 'long'
});
console.log(formatter.format(60));
// Вывод: "60 миль в час"
Форматировщик автоматически создает фразу для составной единицы, используя правильную грамматику для локали.
Получение доступных идентификаторов единиц измерения
Метод Intl.supportedValuesOf() возвращает массив всех идентификаторов единиц измерения, поддерживаемых в вашей среде JavaScript. Этот метод принимает строку 'unit' в качестве аргумента.
const units = Intl.supportedValuesOf('unit');
console.log(units);
// Вывод: Массив идентификаторов единиц измерения, например:
// ["acre", "bit", "byte", "celsius", "centimeter", "day",
// "degree", "fahrenheit", "fluid-ounce", "foot", "gallon",
// "gram", "hectare", "hour", "inch", "kilogram", "kilometer",
// "liter", "meter", "mile", "millimeter", "ounce", "pound",
// "second", "stone", "week", "yard", ...]
Возвращаемый массив включает все простые единицы, доступные для форматирования. Вы можете использовать любой идентификатор из этого массива с опцией unit.
Этот метод полезен, если вам нужно проверить, поддерживается ли конкретная единица, или если вы хотите предоставить пользователям список доступных единиц.
const units = Intl.supportedValuesOf('unit');
const hasKilometer = units.includes('kilometer');
const hasPound = units.includes('pound');
console.log(hasKilometer);
// Вывод: true
console.log(hasPound);
// Вывод: true
Вы можете проверить наличие конкретных единиц перед созданием форматтеров для работы в средах с разным уровнем поддержки.
Комбинирование с опциями форматирования чисел
Форматтеры единиц поддерживают те же опции форматирования чисел, что и другие стили Intl.NumberFormat. Вы можете управлять количеством десятичных знаков, значимыми цифрами и другими числовыми свойствами.
const formatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer',
maximumFractionDigits: 2
});
console.log(formatter.format(5.123));
// Вывод: "5.12 км"
console.log(formatter.format(5.5));
// Вывод: "5.5 км"
Форматтер применяет правила округления и отображения десятичных знаков перед добавлением единицы измерения.
Вы можете форматировать большие числа с разделителями тысяч.
const formatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer'
});
console.log(formatter.format(12345.67));
// Вывод: "12,345.67 км"
Все стандартные функции форматирования чисел работают с форматированием единиц измерения.
Форматирование измерений для локали пользователя
Вместо жесткого указания конкретной локали вы можете использовать языковые предпочтения браузера пользователя. Свойство navigator.language возвращает предпочтительную локаль пользователя.
const userLocale = navigator.language;
const formatter = new Intl.NumberFormat(userLocale, {
style: 'unit',
unit: 'kilometer'
});
console.log(formatter.format(5));
// Вывод зависит от локали пользователя
Этот подход отображает измерения в соответствии с ожиданиями форматирования каждого пользователя. Разные пользователи видят одно и то же измерение, отформатированное в соответствии с их локальными стандартами.
Отображение измерений в приложениях
Вы можете использовать форматирование единиц измерения везде, где отображаете измерения пользователям. Это включает фитнес-приложения, показывающие расстояние или вес, погодные приложения, показывающие температуру, кулинарные приложения, показывающие объем, и навигационные приложения, показывающие скорость.
const distanceFormatter = new Intl.NumberFormat(navigator.language, {
style: 'unit',
unit: 'kilometer',
maximumFractionDigits: 1
});
const distance = 5.234;
document.getElementById('distance').textContent = distanceFormatter.format(distance);
// Отображает: "5.2 км" (или эквивалент для локали)
Отформатированные строки работают как любые другие строковые значения. Вы можете вставлять их в текстовый контент, атрибуты или любой другой контекст, где отображаете информацию пользователям.
Повторное использование форматировщиков единиц измерения
Создание нового экземпляра Intl.NumberFormat включает загрузку данных локали и обработку параметров. Когда вы форматируете несколько измерений с одной и той же локалью и единицей измерения, создайте форматировщик один раз и используйте его повторно.
const formatter = new Intl.NumberFormat('en-US', {
style: 'unit',
unit: 'kilometer'
});
const distances = [1.5, 3.2, 5.0, 10.8];
distances.forEach(distance => {
console.log(formatter.format(distance));
});
// Вывод:
// "1.5 км"
// "3.2 км"
// "5 км"
// "10.8 км"
Этот подход более эффективен, чем создание нового форматировщика для каждого значения. Разница в производительности становится значительной при форматировании массивов или списков с большим количеством измерений.