Форматирование временных интервалов отличается от форматирования одиночных значений даты и времени тем, что требуется корректно отобразить не одну точку во времени, а диапазон между двумя моментами. В зависимости от локали, продолжительности интервала и совпадения компонентов даты (год, месяц, день, время) результат может существенно меняться.
Вместо простого объединения двух отформатированных дат используется специализированная логика, учитывающая правила сокращения повторяющихся частей и локальные особенности записи диапазонов.
Базой для интервалов в Globalize выступает CLDR (Unicode Common Locale Data Repository), где для каждой локали определены правила форматирования диапазонов дат и времени.
Ключевой элемент — intervalFormats, описывающий, как
должны выглядеть интервалы для разных частей даты:
Каждый тип интервала описывается набором шаблонов, зависящих от совпадения частей даты.
Пример логики CLDR:
Такое поведение позволяет получить компактное, но однозначное представление интервала.
Работа с форматированием интервалов в Globalize невозможна без загрузки соответствующих CLDR-ресурсов.
Обычно подключаются следующие группы данных:
cldr-corecldr-dates-fullcldr-numbers-fullru, en,
de)Инициализация базовой среды:
import Globalize from "globalize";
import likelySubtags from "cldr-core/supplemental/likelySubtags.json";
import timeData from "cldr-core/supplemental/timeData.json";
import weekData from "cldr-core/supplemental/weekData.json";
import dateFields from "cldr-dates-full/main/ru/dateFields.json";
import timeZoneNames from "cldr-dates-full/main/ru/timeZoneNames.json";
import caGregorian from "cldr-dates-full/main/ru/ca-gregorian.json";
Globalize.load(
likelySubtags,
timeData,
weekData,
dateFields,
timeZoneNames,
caGregorian
);
Globalize.locale("ru");
Без загрузки ca-gregorian и связанных структур работа с
датами и интервалами будет неполной, поскольку именно там содержатся
шаблоны форматирования.
В основе лежит функция форматирования диапазона между двумя датами:
Обобщённая модель:
Globalize.formatDateRange(startDate, endDate, options);
Где options определяет стиль форматирования (short,
medium, long, full) и тип вывода.
const start = new Date(2026, 4, 27, 10, 0);
const end = new Date(2026, 4, 27, 14, 0);
Globalize.formatDateRange(start, end, {
datetime: "short"
});
Результат для русской локали обычно сокращает повторяющуюся дату и оставляет различающиеся компоненты времени:
Здесь дата выводится один раз, а диапазон применяется только к времени.
Одной из ключевых особенностей является автоматическое устранение дублирования.
Если начало и конец интервала находятся в одном дне, форматирование сводится к диапазону времени:
const start = new Date(2026, 4, 27, 9, 30);
const end = new Date(2026, 4, 27, 18, 45);
Результат:
Если даты различаются днями, но находятся в одном месяце:
const start = new Date(2026, 4, 10);
const end = new Date(2026, 4, 27);
Результат:
Здесь месяц и год выводятся один раз, а диапазон применяется только к дню.
const start = new Date(2025, 11, 30);
const end = new Date(2026, 0, 2);
Результат сохраняет обе границы:
CLDR использует механизм skeletons — абстрактных шаблонов, описывающих желаемую структуру даты без привязки к конкретному формату.
Skeleton определяет:
Globalize использует skeleton как вход для выбора подходящего шаблона интервала.
Пример логики:
yMd → год + месяц + деньHm → часы + минутыНа основе skeleton выбирается правило из
intervalFormats.
Одна и та же пара дат может отображаться по-разному в разных локалях.
Пример:
Globalize.locale("en");
Globalize.formatDateRange(start, end, { datetime: "medium" });
Результат может выглядеть как:
При форматировании интервалов важно учитывать временные зоны, поскольку два момента времени могут отображаться по-разному в зависимости от контекста.
Globalize опирается на CLDR timeZoneNames и системные настройки среды выполнения.
Особенности:
Пример интервала с потенциальным DST-переходом:
const start = new Date("2026-03-28T23:00:00Z");
const end = new Date("2026-03-29T03:00:00Z");
Форматирование учитывает локальные правила перехода времени.
Если начало и конец интервала совпадают, система может:
Пример:
const start = new Date(2026, 4, 27, 10, 0);
const end = new Date(2026, 4, 27, 10, 0);
Результат обычно сводится к:
Форматирование интервалов является относительно дорогой операцией из-за:
Поэтому Globalize использует кэширование форматтеров:
Рекомендуется:
const start = new Date(2026, 0, 28);
const end = new Date(2026, 1, 2);
Форматирование раскрывает месяц полностью для обеих границ.
const start = new Date(2025, 11, 31);
const end = new Date(2026, 0, 1);
Год отображается на обеих сторонах, так как сокращение невозможно без потери смысла.
При интервалах в пределах минут или секунд система сохраняет максимальную точность:
const start = new Date(2026, 4, 27, 10, 0, 0);
const end = new Date(2026, 4, 27, 10, 0, 45);
Результат:
Форматирование интервалов тесно связано с обычным форматированием дат:
Это обеспечивает визуальную согласованность между: