Объект Date — один из трёх форматов, которые принимает
функция format. Он является нативным для JavaScript и
наиболее удобен в проектах с TypeScript или строгой типизацией,
поскольку тип Date однозначно определён и не допускает
двусмысленности.
import { format } from 'timeago.js';
const date = new Date('2025-05-26T08:00:00Z');
format(date, 'ru');
// → "4 часа назад"
Из строки ISO 8601:
const date = new Date('2025-05-26T10:30:00.000Z');
format(date, 'ru');
Из числа (timestamp):
const date = new Date(1716720000000);
format(date, 'ru');
Из компонентов:
// Год, месяц (0-11), день, часы, минуты, секунды
const date = new Date(2025, 4, 26, 10, 30, 0);
format(date, 'ru');
Текущий момент:
const now = new Date();
format(now, 'ru');
// → "только что"
Часто требуется вычислить дату, отстоящую на определённый промежуток:
const date = new Date();
date.setHours(date.getHours() - 3);
format(date, 'ru');
// → "3 часа назад"
Аналогично для будущего:
const future = new Date();
future.setDate(future.getDate() + 7);
format(future, 'ru');
// → "через 1 неделю"
Объект Date хранит время в UTC, но методы
getHours(), getDay() и т.д. возвращают
значения в локальном часовом поясе устройства.
Функция format вычисляет разницу между
.getTime() (UTC-timestamp) входной даты и
Date.now() (также UTC). Поэтому часовой пояс не влияет на
вычисление разницы:
// Эти два вызова дадут одинаковый результат,
// несмотря на разные строковые представления
format(new Date('2025-05-26T10:00:00Z'));
format(new Date('2025-05-26T13:00:00+03:00'));
const local = new Date(2025, 4, 26, 10, 0, 0); // локальное время
const utc = new Date('2025-05-26T10:00:00Z'); // UTC
// Если UTC-смещение не ноль, getTime() вернёт разные значения
console.log(local.getTime() !== utc.getTime()); // вероятно true
При получении дат из API всегда уточняйте, в каком часовом поясе они переданы.
const ts1 = Date.now(); // число (мс)
const ts2 = new Date(); // объект Date
// Оба эквивалентны для timeago.js
format(ts1);
format(ts2);
Оба варианта корректны. Date.now() предпочтительнее,
когда дата нужна только для вычисления разницы — он не создаёт
объект.
В TypeScript тип Date обеспечивает статическую
проверку:
import { format } from 'timeago.js';
function formatDate(date: Date): string {
return format(date, 'ru');
}
const created = new Date(apiResponse.createdAt);
const label = formatDate(created);
TypeScript не допустит передачи string туда, где
ожидается Date, — это предотвращает распространённые
ошибки.
const dates = [
new Date('2025-05-26T10:00:00Z'),
new Date('2025-05-25T08:00:00Z'),
new Date('2025-05-20T15:00:00Z'),
];
dates.map(d => format(d, 'ru'));
// → ["4 часа назад", "1 день назад", "6 дней назад"]
Функция render() работает с DOM-элементами через атрибут
datetime. Перед записью объект Date нужно
конвертировать в строку:
const date = new Date('2025-05-26T10:00:00Z');
const el = document.getElementById('time');
el.setAttribute('datetime', date.toISOString());
render(el, 'ru');
Метод toISOString() всегда возвращает строку в UTC с
суффиксом Z, что гарантирует однозначность.
Передача невалидного объекта Date приводит к непредсказуемому результату:
const invalid = new Date('not-a-date');
console.log(invalid.getTime()); // NaN
format(invalid); // NaN years ago или ошибка
Защита от Invalid Date:
function isValidDate(date) {
return date instanceof Date && !isNaN(date.getTime());
}
function safeFormat(date, locale = 'ru') {
if (!isValidDate(date)) return '';
return format(date, locale);
}
timeago.js принимает любой объект с интерфейсом, совместимым с
Date. Это работает с Moment.js, Day.js, Luxon при явной
конвертации:
// Moment.js
import moment from 'moment';
const m = moment('2025-05-26');
format(m.toDate(), 'ru');
// Day.js
import dayjs from 'dayjs';
const d = dayjs('2025-05-26');
format(d.toDate(), 'ru');
// Luxon
import { DateTime } from 'luxon';
const l = DateTime.fromISO('2025-05-26');
format(l.toJSDate(), 'ru');
Создание объекта Date — дешёвая операция. Для единичных
вызовов нет причин оптимизировать. При обработке тысяч записей в цикле
лучше использовать timestamp напрямую:
// Чуть эффективнее для больших объёмов
posts.map(p => format(p.timestamp, 'ru'));