timeago.js поддерживает форматирование не только прошедших, но и будущих дат. Если переданная дата позже текущего момента, библиотека автоматически использует вторую форму строки из локали (futureString).
Внутри библиотека определяет направление:
const diff = new Date(input).getTime() - Date.now();
if (diff > 0) {
// Будущее — использует futureString из [past, future]
} else {
// Прошлое — использует pastString
}
import { format } from 'timeago.js';
// Через 5 минут
format(Date.now() + 1000 * 60 * 5, 'ru'); // → "через 5 минут"
// Через 2 часа
format(Date.now() + 1000 * 60 * 60 * 2, 'ru'); // → "через 2 часа"
// Через 1 день
format(Date.now() + 1000 * 60 * 60 * 24, 'ru'); // → "через 1 день"
// Через 3 недели
format(Date.now() + 1000 * 60 * 60 * 24 * 21, 'ru'); // → "через 3 недели"
// Через 6 месяцев
format(Date.now() + 1000 * 60 * 60 * 24 * 180, 'ru'); // → "через 6 месяцев"
import { format } from 'timeago.js';
const deadline = new Date('2025-06-15T23:59:59Z');
format(deadline, 'ru'); // → "через 20 дней"
Это удобно для:
<time id="event-time" datetime="2025-06-15T23:59:59Z"></time>
import { render } from 'timeago.js';
const node = document.getElementById('event-time');
render(node, 'ru');
По мере приближения дедлайна значение обновляется автоматически:
через 20 дней
→ через 19 дней
→ через 18 часов
→ через 5 минут
→ только что
→ 1 минуту назад
После наступления момента вывод плавно переключается на прошедшее время.
import { format } from 'timeago.js';
function formatDeadline(date, locale = 'ru') {
const diff = new Date(date).getTime() - Date.now();
if (diff < 0) {
const overdue = Math.abs(diff);
const days = Math.floor(overdue / (1000 * 60 * 60 * 24));
if (days === 0) return 'просрочено сегодня';
return `просрочено на ${days} ${days === 1 ? 'день' : 'дней'}`;
}
return format(date, locale);
}
import { format } from 'timeago.js';
function urgencyClass(date) {
const diff = new Date(date).getTime() - Date.now();
if (diff < 0) return 'overdue';
if (diff < 3600000) return 'critical'; // < 1 часа
if (diff < 86400000) return 'warning'; // < 1 дня
if (diff < 7 * 86400000) return 'soon'; // < 1 недели
return 'normal';
}
import { useEffect, useState } from 'react';
import { format } from 'timeago.js';
function Deadline({ date }: { date: string }) {
const [label, setLabel] = useState(() => format(date, 'ru'));
useEffect(() => {
const id = setInterval(() => {
setLabel(format(date, 'ru'));
}, 60000);
return () => clearInterval(id);
}, [date]);
const isPast = new Date(date).getTime() < Date.now();
return (
<span className={isPast ? 'overdue' : 'upcoming'}>
{label}
</span>
);
}
import { format } from 'timeago.js';
const scheduledPosts = [
{ title: 'Анонс', publishAt: '2025-05-27T09:00:00Z' },
{ title: 'Статья', publishAt: '2025-05-28T14:00:00Z' },
{ title: 'Вебинар', publishAt: '2025-06-05T18:00:00Z' },
];
scheduledPosts.forEach(post => {
const relative = format(post.publishAt, 'ru');
console.log(`"${post.title}" — ${relative}`);
});
Вывод:
"Анонс" — через 1 день
"Статья" — через 2 дня
"Вебинар" — через 10 дней
Убедиться, что локаль корректно обрабатывает будущее:
import { register, format } from 'timeago.js';
register('test_locale', (number, index) => {
const pairs = [
['только что', 'прямо сейчас'],
['%s сек. назад', 'через %s сек.'],
// ...
];
return pairs[index];
});
// Проверка будущего
format(Date.now() + 30000, 'test_locale'); // → "через 30 сек."
format(Date.now() + 90000, 'test_locale'); // → "прямо сейчас" (index 0) или "через X сек."
Если дата “в будущем” передана по ошибке (неверный формат или часовой пояс), функция всё равно вернёт строку с “через…”. Для отладки можно добавить проверку:
function debugFormat(date, locale = 'ru') {
const diff = new Date(date).getTime() - Date.now();
if (diff > 0) {
console.debug('[timeago] Future date detected:', date, `(+${Math.round(diff / 1000)}s)`);
}
return format(date, locale);
}
const schedule = [
{ event: 'Встреча', time: new Date(Date.now() + 1000 * 60 * 30) }, // через 30 мин
{ event: 'Созвон', time: new Date(Date.now() + 1000 * 60 * 90) }, // через 1.5 ч
{ event: 'Презент.', time: new Date(Date.now() + 1000 * 60 * 60 * 5) }, // через 5 ч
];
schedule.forEach(({ event, time }) => {
console.log(`${event}: ${format(time, 'ru')}`);
});