Единицы измерения в timeago.js определяются через систему индексов в функции локали. Каждый индекс соответствует определённому временному интервалу. Пороги переключения между единицами жёстко заданы внутри библиотеки, но поведение можно изменить через кастомные рендеры или постобработку.
Функция локали вызывается с аргументом index,
определяющим текущую единицу:
| index | Единица | Диапазон разницы |
|---|---|---|
| 0 | прямо сейчас | < 45 секунд |
| 1 | секунды (ед. ч.) | 45–89 секунд |
| 2 | секунды (мн. ч.) | 89–2700 секунд (45 мин) |
| 3 | 1 минута | 2700–5400 секунд |
| 4 | минуты | 5400–64800 секунд |
| 5 | 1 час | 64800–129600 секунд |
| 6 | часы | 129600–77400 секунд |
| 7 | 1 день | ~21.5–35.5 ч |
| 8 | дни | ~35.5ч–25.5 дней |
| 9 | 1 неделя | ~25.5–45 дней |
| 10 | недели | — |
| 11 | 1 месяц | ~45–319 дней |
| 12 | месяцы | — |
| 13 | 1 год | ~319–547 дней |
| 14 | годы | > 547 дней |
Если требуется скрыть секунды или недели, можно «схлопнуть» соответствующие индексы в ближайшие:
import { register, format } from 'timeago.js';
register('ru_no_seconds', (number, index) => {
// Индексы 0-2 (секунды) → показываем "только что"
if (index <= 2) return ['только что', 'скоро'];
return [
null,
null,
null,
['1 минуту назад', 'через 1 минуту'],
['%s минут назад', 'через %s минут'],
['1 час назад', 'через 1 час'],
['%s часов назад', 'через %s часов'],
['1 день назад', 'через 1 день'],
['%s дней назад', 'через %s дней'],
['1 неделю назад', 'через 1 неделю'],
['%s недель назад', 'через %s недель'],
['1 месяц назад', 'через 1 месяц'],
['%s месяцев назад', 'через %s месяцев'],
['1 год назад', 'через 1 год'],
['%s лет назад', 'через %s лет'],
][index];
});
Если всегда нужно отображать только часы:
register('hours_only', (number, index) => {
const diff = /* логика расчёта */ 0;
const hours = Math.round(diff / 3600000);
if (hours === 0) return ['только что', 'скоро'];
if (hours === 1) return ['1 час назад', 'через 1 час'];
return [`${hours} часов назад`, `через ${hours} часов`];
});
По умолчанию библиотека переходит на недели после ~25 дней. Чтобы продолжать показывать дни:
register('ru_days_only', (number, index) => {
// Индексы 9-10 (недели) → переводим в дни
if (index === 9) return [`${Math.round(number * 7)} дней назад`, `через ${Math.round(number * 7)} дней`];
if (index === 10) return [`${Math.round(number * 7)} дней назад`, `через ${Math.round(number * 7)} дней`];
return defaultStrings[index]; // fallback для остальных
});
Для полного контроля над порогами создаётся собственная функция форматирования поверх timeago.js:
import { format } from 'timeago.js';
function customFormat(date, locale = 'ru') {
const diff = Date.now() - new Date(date).getTime();
const absSeconds = Math.abs(diff) / 1000;
if (absSeconds < 3600) {
// Показывать минуты, даже если timeago перейдёт на часы
const minutes = Math.round(absSeconds / 60);
const isPast = diff > 0;
if (minutes === 0) return 'только что';
return isPast ? `${minutes} мин. назад` : `через ${minutes} мин.`;
}
return format(date, locale);
}
import { format } from 'timeago.js';
function smartUnit(date, locale = 'ru') {
const diff = Date.now() - new Date(date).getTime();
const days = diff / (1000 * 60 * 60 * 24);
if (days < 1) return format(date, locale);
if (days < 7) {
return new Intl.DateTimeFormat('ru', { weekday: 'long' }).format(new Date(date));
}
return new Intl.DateTimeFormat('ru', { day: 'numeric', month: 'long' }).format(new Date(date));
}
register('ru_max_days', (number, index) => {
const allInDays = [
['только что', 'скоро'],
['%s сек. назад', 'через %s сек.'],
['%s сек. назад', 'через %s сек.'],
['1 мин. назад', 'через 1 мин.'],
['%s мин. назад', 'через %s мин.'],
['1 ч. назад', 'через 1 ч.'],
['%s ч. назад', 'через %s ч.'],
['1 д. назад', 'через 1 д.'],
['%s д. назад', 'через %s д.'],
['%s д. назад', 'через %s д.'], // недели → дни
['%s д. назад', 'через %s д.'], // недели
['%s д. назад', 'через %s д.'], // месяцы
['%s д. назад', 'через %s д.'], // месяцы
['%s д. назад', 'через %s д.'], // годы
['%s д. назад', 'через %s д.'], // годы
];
return allInDays[index];
});
let preferredUnit = 'auto'; // 'auto' | 'minutes' | 'hours'
function adaptiveFormat(date) {
if (preferredUnit === 'minutes') {
const diff = (Date.now() - new Date(date).getTime()) / 60000;
return `${Math.round(Math.abs(diff))} мин. назад`;
}
if (preferredUnit === 'hours') {
const diff = (Date.now() - new Date(date).getTime()) / 3600000;
return `${Math.round(Math.abs(diff))} ч. назад`;
}
return format(date, 'ru');
}