Метод formatRangeToParts расширяет возможности
форматирования дат в рамках API интернационализации, предоставляя
структурированное представление результата форматирования диапазона дат.
В отличие от formatRange, который возвращает строку, данный
метод возвращает массив частей, каждая из которых описывает отдельный
сегмент итогового отображения: числа, разделители, названия месяцев,
временные зоны и другие элементы.
Основная цель метода — обеспечить точный контроль над тем, как именно интернационализированная строка диапазона дат разбивается на логические компоненты, пригодные для кастомного рендеринга интерфейсов.
Intl.DateTimeFormat.prototype.formatRangeToParts(startDate, endDate)
startDate — начальная дата диапазона (объект
Date или значение, приводимое к нему)endDate — конечная дата диапазона (объект
Date или значение, приводимое к нему)Возвращается массив объектов, где каждый объект имеет структуру:
{
type: string,
value: string,
source: "startRange" | "endRange" | "shared"
}
Каждый элемент результата представляет отдельный фрагмент форматированного диапазона.
typeОпределяет роль части:
year — годmonth — месяцday — деньhour — часminute — минутыsecond — секундыliteral — разделители (например, «.», «/», «–»)timeZoneName — название временной зоныweekday — день неделиera — эраvalueСтроковое представление части, уже локализованное согласно выбранной локали.
sourceУказывает происхождение части:
startRange — часть относится к начальной датеendRange — часть относится к конечной датеshared — часть общая для обеих дат и не
дублируетсяПри форматировании диапазона дат движок стремится:
Например, диапазон внутри одного месяца может отображать общий месяц только один раз.
const formatter = new Intl.DateTimeFormat("ru-RU", {
year: "numeric",
month: "long",
day: "numeric"
});
const parts = formatter.formatRangeToParts(
new Date(2024, 0, 1),
new Date(2024, 0, 10)
);
console.log(parts);
Результат может быть представлен примерно так:
[
{ type: "day", value: "1", source: "startRange" },
{ type: "literal", value: "–", source: "shared" },
{ type: "day", value: "10", source: "endRange" },
{ type: "month", value: "января", source: "shared" },
{ type: "year", value: "2024", source: "shared" }
]
Метод formatRange возвращает готовую строку:
"1–10 января 2024"
Метод formatRangeToParts возвращает структурированный
результат, который позволяет:
Формирование частей полностью зависит от настроек
Intl.DateTimeFormat, включая:
localetimeZonecalendardateStyletimeStyleНапример, при смене локали изменяются не только значения, но и порядок частей:
new Intl.DateTimeFormat("en-US", { year: "numeric", month: "long", day: "numeric" })
и
new Intl.DateTimeFormat("de-DE", { year: "numeric", month: "long", day: "numeric" })
дадут разные последовательности частей, даже при одинаковых датах.
При использовании времени поведение расширяется за счёт дополнительных токенов:
hourminutesecondtimeZoneNameПример:
const formatter = new Intl.DateTimeFormat("en-GB", {
hour: "2-digit",
minute: "2-digit"
});
formatter.formatRangeToParts(
new Date(2024, 0, 1, 10, 0),
new Date(2024, 0, 1, 12, 30)
);
Результат будет содержать разделённые части времени с возможными общими компонентами даты.
Одной из ключевых особенностей является автоматическое подавление дублирования.
Если диапазон:
то эти части помечаются как shared и не повторяются.
Пример логики:
Год и месяц будут shared, день — разделён.
Структура результата позволяет строить гибкие шаблоны отображения.
Каждый элемент можно:
Пример логики рендеринга:
parts.map(part => {
if (part.type === "literal") return part.value;
return `<span class="${part.type}">${part.value}</span>`;
}).join("");
При переходах между:
структура частей меняется:
startRange/endRange и становиться
sharedliteral) могут меняться в зависимости от
локалиВ зависимости от calendar в Intl,
форматирование может использовать:
Каждый календарь влияет на:
erayearМетод formatToParts работает с одной датой, а
formatRangeToParts — с диапазоном.
Ключевое различие:
formatToParts(date) — разбор одной точки времениformatRangeToParts(start, end) — разбор интервала с
логикой объединения и различения частейЧасти позволяют визуально выделять начало и конец диапазона.
Используется для построения календарей с поддержкой разных языков без ручного форматирования.
Каждый компонент может иметь собственный стиль, зависящий от
type.
Если startDate и endDate совпадают:
formatToPartssource может содержать только shared и
элементы одной стороныЕсли переданы некорректные даты:
DateRangeErrorПример:
formatter.formatRangeToParts("invalid", new Date());
может привести к исключению в зависимости от реализации движка.
Параметры Intl.DateTimeFormat напрямую влияют на
разбиение:
dateStyle: "full" увеличивает количество частей
(добавляется weekday)timeStyle: "short" сокращает набор временных
компонентовhourCycle влияет на формат часовtimeZone изменяет timeZoneName и смещает
значения времениНесмотря на гибкость локализации, структура parts
сохраняет:
type для семантических
компонентовОднако порядок между разными локалями не фиксирован и зависит от правил конкретного языка и региона.