По умолчанию timeago.js форматирует любые даты без ограничений — от нескольких секунд до десятков лет. Однако в реальных приложениях часто нужно ограничить диапазон: показывать относительное время только для свежих дат, а для старых — абсолютное.
import { format } from 'timeago.js';
function pastOnly(date, locale = 'ru') {
if (new Date(date).getTime() > Date.now()) {
return 'скоро';
}
return format(date, locale);
}
import { format } from 'timeago.js';
const MAX_RELATIVE_MS = 7 * 24 * 60 * 60 * 1000; // 7 дней
function limitedFormat(date, locale = 'ru') {
const diff = Math.abs(Date.now() - new Date(date).getTime());
if (diff > MAX_RELATIVE_MS) {
return new Intl.DateTimeFormat('ru', {
day: 'numeric',
month: 'long',
year: 'numeric',
}).format(new Date(date));
}
return format(date, locale);
}
Вывод:
5 минут назад ← относительное
26 мая 2025 г. ← абсолютное для дат старше 7 дней
Не показывать “только что” если дата старше 1 минуты:
import { format } from 'timeago.js';
function minOneMinute(date, locale = 'ru') {
const diff = Date.now() - new Date(date).getTime();
if (diff < 60000) {
return 'только что';
}
return format(date, locale);
}
import { format } from 'timeago.js';
const RANGES = [
{ max: 30 * 1000, label: () => 'только что' },
{ max: 24 * 60 * 60 * 1000, label: (d) => format(d, 'ru') },
{ max: 7 * 24 * 60 * 60 * 1000, label: (d) => `${Math.round((Date.now() - new Date(d).getTime()) / 86400000)} дн. назад` },
{ max: Infinity, label: (d) => new Intl.DateTimeFormat('ru', { day: 'numeric', month: 'long', year: 'numeric' }).format(new Date(d)) },
];
function rangedFormat(date) {
const diff = Date.now() - new Date(date).getTime();
for (const range of RANGES) {
if (diff < range.max) return range.label(date);
}
}
import { format } from 'timeago.js';
function deadlineFormat(date, locale = 'ru') {
const diff = new Date(date).getTime() - Date.now();
if (diff < 0) {
return 'просрочено';
}
if (diff < 60000) {
return 'менее минуты';
}
if (diff > 30 * 24 * 60 * 60 * 1000) {
return new Intl.DateTimeFormat('ru', {
day: 'numeric',
month: 'long',
}).format(new Date(date));
}
return format(date, locale);
}
import { format } from 'timeago.js';
function feedFormat(date) {
const ageMs = Date.now() - new Date(date).getTime();
const ageDays = ageMs / (1000 * 60 * 60 * 24);
if (ageDays > 30) {
return new Intl.DateTimeFormat('ru', {
day: 'numeric',
month: 'short',
year: 'numeric',
}).format(new Date(date));
}
return format(date, 'ru');
}
import { format } from 'timeago.js';
function createFormatter({ maxRelativeMs = Infinity, minRelativeMs = 0, locale = 'ru' } = {}) {
return function(date) {
const diff = Math.abs(Date.now() - new Date(date).getTime());
if (diff < minRelativeMs) {
return 'только что';
}
if (diff > maxRelativeMs) {
return new Intl.DateTimeFormat(locale, {
dateStyle: 'medium',
}).format(new Date(date));
}
return format(date, locale);
};
}
const formatPost = createFormatter({ maxRelativeMs: 7 * 24 * 60 * 60 * 1000, locale: 'ru' });
const formatComment = createFormatter({ maxRelativeMs: 24 * 60 * 60 * 1000, locale: 'ru' });
import { format } from 'timeago.js';
function formatWithFallback(date, fallback = 'давно', locale = 'ru') {
const MAX = 365 * 24 * 60 * 60 * 1000; // 1 год
const diff = Math.abs(Date.now() - new Date(date).getTime());
if (diff > MAX) return fallback;
return format(date, locale);
}
import { format } from 'timeago.js';
const MAX_DAYS = 30;
function PostDate({ date }: { date: string }) {
const ageMs = Date.now() - new Date(date).getTime();
const ageDays = ageMs / (1000 * 60 * 60 * 24);
if (ageDays > MAX_DAYS) {
return (
<time dateTime={date}>
{new Intl.DateTimeFormat('ru', { dateStyle: 'long' }).format(new Date(date))}
</time>
);
}
return (
<time dateTime={date}>
{format(date, 'ru')}
</time>
);
}