Часовые форматы в JavaScript через Intl.DateTimeFormat
определяются комбинацией локали и параметров форматирования, среди
которых ключевую роль играют hour12 и
hourCycle. Эти опции управляют тем, отображается ли время в
12-часовом или 24-часовом виде, а также каким образом интерпретируется
переход между полуночью и полуднем.
Intl.DateTimeFormat работает на основе локали и набора
опций, формируя строковое представление даты и времени в соответствии с
культурными нормами.
Базовый пример:
const formatter = new Intl.DateTimeFormat('ru-RU', {
hour: '2-digit',
minute: '2-digit'
});
console.log(formatter.format(new Date()));
В данном случае формат времени определяется локалью
ru-RU, которая по умолчанию использует 24-часовую
систему.
Ключевые поля, влияющие на время:
hour — отображение часовminute — минутыsecond — секундыhour12 — переключатель 12/24-часового форматаhourCycle — более точная настройка цикла часовhour12 задаёт бинарное поведение:
true — 12-часовой формат (AM/PM)false — 24-часовой форматПример 12-часового формата:
const f12 = new Intl.DateTimeFormat('en-US', {
hour: '2-digit',
minute: '2-digit',
hour12: true
});
console.log(f12.format(new Date()));
Пример 24-часового формата:
const f24 = new Intl.DateTimeFormat('en-GB', {
hour: '2-digit',
minute: '2-digit',
hour12: false
});
console.log(f24.format(new Date()));
Особенность hour12 заключается в том, что он не всегда
является единственным источником истины. В ряде локалей он игнорируется,
если явно задан hourCycle.
hourCycle — более низкоуровневая и точная настройка
часового цикла. Он определяет, как именно интерпретируется диапазон
часов.
Доступные значения:
h11 — 0–11 (с полуночью 0)h12 — 1–12 (с полуднем 12)h23 — 0–23 (классический 24-часовой формат)h24 — 1–24 (редко используемый вариант)Пример использования:
const fmt = new Intl.DateTimeFormat('en-US', {
hour: '2-digit',
minute: '2-digit',
hourCycle: 'h23'
});
console.log(fmt.format(new Date()));
hourCycle имеет приоритет над hour12. Если
оба указаны, используется именно hourCycle.
hour12 — абстракция высокого уровня, ориентированная на
удобство.
hourCycle — точное описание математической модели
времени.
Сопоставление:
| hour12 | hourCycle | Поведение |
|---|---|---|
| true | h12 / h11 | 12-часовой формат |
| false | h23 / h24 | 24-часовой формат |
В современных реализациях рекомендуется использовать
hourCycle, поскольку он исключает неоднозначность.
Локаль может переопределять поведение форматирования даже без явного
указания hour12.
Пример:
const a = new Intl.DateTimeFormat('en-US', {
hour: '2-digit',
minute: '2-digit'
});
const b = new Intl.DateTimeFormat('ru-RU', {
hour: '2-digit',
minute: '2-digit'
});
en-US → обычно 12-часовой форматru-RU → обычно 24-часовой форматЕсли не задано явно, движок выбирает формат по культурным правилам BCP 47.
В 12-часовом формате появляется дополнительная семантика:
const fmt = new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
minute: 'numeric',
hour12: true
});
console.log(fmt.format(new Date()));
Результат включает AM/PM, который формируется через
dayPeriod:
В некоторых локалях вместо AM/PM используются текстовые периоды:
Метод formatToParts позволяет получить структурированное
представление времени, включая компоненты цикла часов.
const fmt = new Intl.DateTimeFormat('en-US', {
hour: '2-digit',
minute: '2-digit',
hour12: true
});
console.log(fmt.formatToParts(new Date()));
Выход:
[
{ type: 'hour', value: '07' },
{ type: 'literal', value: ':' },
{ type: 'minute', value: '30' },
{ type: 'literal', value: ' ' },
{ type: 'dayPeriod', value: 'PM' }
]
Это особенно важно при построении кастомных UI-компонентов часов, где требуется контроль над каждым элементом строки.
Часовой формат тесно связан с временной зоной:
const fmt = new Intl.DateTimeFormat('en-GB', {
hour: '2-digit',
minute: '2-digit',
timeZone: 'UTC',
hourCycle: 'h23'
});
console.log(fmt.format(new Date()));
timeZone не влияет на выбор 12/24-часового формата
напрямую, но изменяет исходное значение времени, к которому применяется
форматирование.
Разные циклы часов по-разному трактуют критические значения:
h11: 0–11, где 0 — полночьh12: 1–12, где 12 используется для полудняh23: 0–23, стандартный 24-часовой циклh24: 1–24, где 24 соответствует полуночи следующего
дняПример различий:
const d = new Date('2024-01-01T00:00:00');
console.log(new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
hourCycle: 'h12'
}).format(d));
console.log(new Intl.DateTimeFormat('en-US', {
hour: 'numeric',
hourCycle: 'h23'
}).format(d));
Алгоритм определения формата времени:
hourCyclehour12Это важно при создании кросс-региональных приложений, где поведение должно быть предсказуемым независимо от окружения.
Часовой формат редко используется изолированно. Обычно он комбинируется:
const fmt = new Intl.DateTimeFormat('de-DE', {
weekday: 'long',
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hourCycle: 'h23'
});
Комбинация позволяет формировать полные временные метки с локализованным представлением.
Поведение по регионам:
en-US) → 12-часовой формат по умолчаниюen-GB) → 24-часовой формат в
большинстве случаевde-DE) → 24-часовой форматen-IN) → часто 12-часовой формат с AM/PMru-RU) → 24-часовой форматЭти различия критичны при разработке интерфейсов, где время должно соответствовать ожиданиям пользователя.
Для полного контроля используется комбинация:
hourCycleformatToPartsПример:
const fmt = new Intl.DateTimeFormat('en-US', {
hour: '2-digit',
minute: '2-digit',
hourCycle: 'h12'
});
const parts = fmt.formatToParts(new Date());
const result = parts
.map(p => p.value)
.join('');
console.log(result);
Такой подход позволяет полностью управлять отображением, не теряя локализации.
Различия могут проявляться в:
Intl опирается на ICU (International Components for
Unicode), поэтому поддержка hourCycle и локалей зависит от
версии ICU в среде выполнения.