В международных интерфейсах диапазоны значений используются для
компактного представления интервалов чисел, дат, денежных сумм и других
упорядоченных величин. Вместо перечисления «от 1 до 10» применяется
локализованная форма, зависящая от языка, правил типографики и
соглашений конкретной локали. В экосистеме FormatJS работа с диапазонами
строится поверх возможностей Intl и расширяется API
библиотеки react-intl.
Современные реализации ECMAScript Internationalization API
поддерживают метод форматирования диапазонов чисел через
Intl.NumberFormat.prototype.formatRange. FormatJS
использует этот механизм через собственные обёртки и полифилы.
const nf = new Intl.NumberFormat('ru-RU');
nf.formatRange(1, 10);
// "1–10"
Для локали en-US результат будет отличаться:
const nf = new Intl.NumberFormat('en-US');
nf.formatRange(1, 10);
// "1–10"
Несмотря на одинаковый визуальный результат в некоторых локалях, внутренние правила форматирования зависят от языка: пробелы, тип тире, группировка чисел и сокращения могут изменяться.
В FormatJS диапазоны чисел доступны через API
formatNumberRange в react-intl:
import { useIntl } from 'react-intl';
function Component() {
const intl = useIntl();
const value = intl.formatNumberRange(1000, 5000, {
style: 'decimal'
});
return value;
}
Поведение метода наследует возможности
Intl.NumberFormat, включая настройки:
style: 'decimal' | 'currency' | 'percent'Форматирование денежных интервалов требует сохранения валютного контекста для обеих границ диапазона. FormatJS обеспечивает корректную локализацию валютных диапазонов:
intl.formatNumberRange(100, 500, {
style: 'currency',
currency: 'USD'
});
В зависимости от локали возможны варианты:
$100–$500100–500 $ (в некоторых европейских локалях)Важная особенность заключается в том, что валюта не дублируется для каждой границы, если это допускается правилами локали.
Работа с датами и временем реализуется через
formatDateTimeRange в react-intl. Это один из
наиболее часто используемых типов диапазонов в интерфейсах календарей,
логов и аналитики.
intl.formatDateTimeRange(
new Date(2026, 0, 1),
new Date(2026, 0, 10),
{
year: 'numeric',
month: 'short',
day: 'numeric'
}
);
Результат зависит от локали:
1–10 янв. 2026 (ru)Jan 1 – Jan 10, 2026 (en-US)Библиотека автоматически:
Ключевая особенность форматирования диапазонов — устранение дублирования информации. Например, если обе даты находятся в одном месяце, месяц может быть указан один раз:
// вход
2026-01-01 → 2026-01-10
// выход (en-US)
Jan 1–10, 2026
Если диапазон пересекает месяцы:
2026-01-28 → 2026-02-03
// результат
Jan 28 – Feb 3, 2026
Такая оптимизация реализуется внутри Intl и не требует
ручной логики.
В разных языках используется различный тип разделителя диапазона:
–FormatJS не фиксирует символ напрямую, а делегирует выбор ICU-слою.
Числовые диапазоны могут применяться к процентам:
intl.formatNumberRange(0.1, 0.25, {
style: 'percent'
});
Результаты:
10–25 % (ru)10%–25% (en-US)Особенность заключается в том, что форматтер применяет процентное преобразование к каждой границе диапазона.
Диапазоны подчиняются правилам округления
Intl.NumberFormat:
intl.formatNumberRange(1.234, 5.678, {
maximumFractionDigits: 1
});
Результат может быть:
1.2–5.7Если включено компактное представление:
intl.formatNumberRange(1000, 5000, {
notation: 'compact'
});
Возможный вывод:
1K–5KОбе границы форматируются независимо, но по одинаковым правилам.
В react-intl диапазоны часто применяются в
UI-компонентах без явного вызова intl:
import { FormattedNumberRange } from 'react-intl';
function PriceRange() {
return (
<FormattedNumberRange
valueStart={100}
valueEnd={500}
style="currency"
currency="EUR"
/>
);
}
Компонент обеспечивает:
react-intlFormatJS различает несколько семантических категорий диапазонов:
NumberFormat)DateTimeFormat)Каждый тип использует собственный форматтер ICU, но интерфейс API остаётся единообразным.
Форматирование диапазонов зависит от поддержки среды:
formatRange используют полифилТакже важно учитывать, что:
Диапазоны могут комбинироваться с единицами:
intl.formatNumberRange(1, 10, {
style: 'unit',
unit: 'kilometer'
});
Результат:
1–10 км1–10 kmВ таких случаях единица применяется к диапазону как к единому логическому объекту, а не к отдельным числам.
Хотя ICU MessageFormat не имеет специального синтаксиса диапазонов, они могут внедряться через аргументы:
{
"range": "{start}–{end} км"
}
intl.formatMessage(message, {
start: intl.formatNumber(1),
end: intl.formatNumber(10)
});
Такой подход используется, когда требуется полный контроль над отображением, но без автоматической локализации разделителя.
Диапазоны требуют двух независимых вызовов форматирования:
При массовом рендеринге списков диапазонов это может влиять на производительность. В таких случаях применяются стратегии:
Intl.NumberFormatЕсли границы диапазона совпадают:
intl.formatNumberRange(5, 5);
Результат может быть:
5или в некоторых локалях:
5–5Поведение зависит от реализации ICU и настроек форматтера.