Intl.DateTimeFormat: локаль, часовой пояс и формат даты в JavaScript

Intl.DateTimeFormat: локаль, часовой пояс и формат даты в JavaScript
Содержание статьи

Intl.DateTimeFormat форматирует дату по правилам выбранной локали. Чтобы результат не зависел от часового пояса устройства, задайте timeZone явно. Локаль определяет представление, а часовой пояс определяет, какие местные дата и время соответствуют исходному моменту.

В разборе Mentoring.digital используем момент 27 октября 2026 года, 22:30 UTC. Для Москвы он уже относится к следующему календарному дню. Это удобный пример для проверки ошибок на границе суток.

Явно задаём исходный момент и формат

const instant = new Date("2026-10-27T22:30:00Z");
const formatter = new Intl.DateTimeFormat("ru-RU", {
  timeZone: "Europe/Moscow",
  year: "numeric",
  month: "2-digit",
  day: "2-digit",
  hour: "2-digit",
  minute: "2-digit",
  hourCycle: "h23",
});

console.log(formatter.format(instant));

Суффикс Z обозначает UTC. Московские части даты для этого момента: 28 октября, 01:30. Порядок элементов и разделители выбирает механизм локализации; не стоит строить проверку на одном жёстко заданном пробеле.

Если форматтер нужен для целого списка, создайте его один раз и используйте для каждой записи. Так настройки будут одинаковыми, а код не будет повторять создание объекта в каждой строке интерфейса.

Локаль не заменяет часовой пояс

Значение ru-RU само по себе не означает московское время. Без timeZone используется часовой пояс среды. Поэтому один и тот же серверный timestamp может выглядеть по-разному на компьютерах пользователей.

Сначала определите требование: время события в месте проведения, личный часовой пояс пользователя или UTC для технического журнала. Затем передайте соответствующую зону. Простое прибавление трёх часов к Date меняет момент и не является универсальной заменой часового пояса.

Получаем части даты без разбора готовой строки

const parts = formatter.formatToParts(instant);
const values = Object.fromEntries(
  parts.filter(part => part.type !== "literal")
       .map(part => [part.type, part.value])
);

console.log(values.day, values.hour, values.minute);

В этом формате каждому нужному типу соответствует одна часть. Такой подход подходит, например, чтобы отдельно оформить день и время. Не разбивайте локализованную строку через split по запятой: состав разделителей зависит от локали и настроек.

Для обычной подписи используйте format целиком. Сборка собственной строки из частей перекладывает на вас выбор порядка элементов и пунктуации. Форматированный текст также не следует сохранять вместо исходного timestamp.

Что проверить перед выпуском интерфейса

  • Один момент возле полуночи в UTC и целевой зоне.
  • Пустое или некорректное значение даты до форматирования.
  • Выбор зоны, отличной от зоны устройства.
  • Локаль и формат, реально доступные в целевой среде.

Intl.DateTimeFormat не является парсером пользовательского ввода. Для поля «дата рождения» сначала определите модель календарной даты: превращать её в произвольную полночь UTC и затем показывать в любой зоне может быть ошибкой.

Работу с данными интерфейса можно отработать на курсах JavaScript. Сложный случай с датами и серверным API разберите с наставником по JavaScript.

Похожие статьи по данной теме