Форматирование даты
Intl.DateTimeFormatиIntl.RelativeTimeFormat— нативное форматирование дат на русском без библиотек.
Задача
Нужно отображать даты в читаемом виде: «12 апреля 2026», «вчера», «3 часа назад», «Пн, 09.04.2026». Библиотеки типа date-fns или dayjs — избыточны для базовых задач.
Решение
Форматирование через Intl.DateTimeFormat:
const now = new Date();
// Полная дата на русском
const fullDate = new Intl.DateTimeFormat('ru-RU', {
day: 'numeric',
month: 'long',
year: 'numeric',
}).format(now);
// '9 апреля 2026 г.'
// Короткая дата
const short = new Intl.DateTimeFormat('ru-RU', {
day: '2-digit',
month: '2-digit',
year: 'numeric',
}).format(now);
// '09.04.2026'
// Дата + время
const dateTime = new Intl.DateTimeFormat('ru-RU', {
day: 'numeric',
month: 'short',
year: 'numeric',
hour: '2-digit',
minute: '2-digit',
}).format(now);
// '9 апр. 2026 г., 14:35'
// День недели
const withDay = new Intl.DateTimeFormat('ru-RU', {
weekday: 'short',
day: 'numeric',
month: 'short',
}).format(now);
// 'ср, 9 апр.'
Относительное время «N минут назад»:
const rtf = new Intl.RelativeTimeFormat('ru-RU', { numeric: 'auto' });
function timeAgo(date) {
const seconds = Math.round((date - Date.now()) / 1000);
const minutes = Math.round(seconds / 60);
const hours = Math.round(minutes / 60);
const days = Math.round(hours / 24);
const months = Math.round(days / 30);
const years = Math.round(days / 365);
if (Math.abs(seconds) < 60) return rtf.format(seconds, 'second');
if (Math.abs(minutes) < 60) return rtf.format(minutes, 'minute');
if (Math.abs(hours) < 24) return rtf.format(hours, 'hour');
if (Math.abs(days) < 30) return rtf.format(days, 'day');
if (Math.abs(months) < 12) return rtf.format(months, 'month');
return rtf.format(years, 'year');
}
timeAgo(new Date(Date.now() - 3 * 60 * 60 * 1000)); // '3 часа назад'
timeAgo(new Date(Date.now() - 24 * 60 * 60 * 1000)); // 'вчера'
timeAgo(new Date(Date.now() + 2 * 24 * 60 * 60 * 1000)); // 'послезавтра'
Парсинг ISO-строки из API:
// Правильный способ — ISO 8601 с часовым поясом
const date = new Date('2026-04-09T14:35:00Z');
// Опасно: 'YYYY-MM-DD' без времени парсится как UTC 00:00
// и может показать 'вчера' в часовых поясах UTC+X
const wrong = new Date('2026-04-09'); // может быть 8 апреля в UTC+0
const right = new Date('2026-04-09T00:00:00'); // локальное время
Ключевые моменты
Intl.DateTimeFormatиIntl.RelativeTimeFormat— встроены в браузер, не нужен импорт.- Кешируй экземпляр
Intl.DateTimeFormatпри форматировании массива дат — создание дорого. { numeric: 'auto' }вRelativeTimeFormat— «вчера»/«завтра» вместо «-1 день»/«1 день».- ISO 8601 с
Zили+HH:mm— единственный безопасный формат для парсинга дат из API.
Варианты
date-fns— функциональный, tree-shakeable, самый популярный.dayjs— Moment.js совместимый API, 2 KB.Temporal API— будущий стандарт, пока нужен polyfill.