По умолчанию timeago.js выводит строки в формате, определённом
функцией локали. Стандартный формат использует шаблон с плейсхолдером
%s для подстановки числа. Изменить формат вывода можно
через кастомные локали или создание собственных рендеров.
Функция локали принимает два аргумента: number
(количество единиц времени) и index (индекс интервала).
Возвращает массив из двух строк: [прошлое, будущее].
Стандартный формат:
(number, index) => {
return [
['только что', 'прямо сейчас'], // index 0
['%s секунду назад', 'через %s секунду'], // index 1
...
][index];
}
Плейсхолдер %s заменяется числом при формировании
итоговой строки.
Зарегистрировав собственную локаль, можно полностью переопределить строки:
import { register, format } from 'timeago.js';
register('ru_custom', (number, index) => {
const strings = [
['прямо сейчас', 'прямо сейчас'],
['%s с', 'через %s с'],
['1 мин', 'через 1 мин'],
['%s мин', 'через %s мин'],
['1 ч', 'через 1 ч'],
['%s ч', 'через %s ч'],
['1 д', 'через 1 д'],
['%s д', 'через %s д'],
['1 нед', 'через 1 нед'],
['%s нед', 'через %s нед'],
['1 мес', 'через 1 мес'],
['%s мес', 'через %s мес'],
['1 г', 'через 1 г'],
['%s л', 'через %s л'],
];
return strings[index];
});
format(Date.now() - 1000 * 60 * 45, 'ru_custom');
// → "45 мин"
Иногда нужен нестандартный формат, например, с предлогами в других позициях:
register('ru_alt', (number, index, isPast) => {
if (index === 0) return ['сейчас', 'сейчас'];
const units = [
'', 'секунд', 'минуту', 'минут', 'час', 'часов', 'день', 'дней',
'неделю', 'недель', 'месяц', 'месяцев', 'год', 'лет',
];
const unit = units[index];
if (isPast) {
return [`${number} ${unit} тому назад`, ''];
}
return ['', `через ${number} ${unit}`];
});
Для интерфейсов с упрощённым отображением можно вернуть строки без
%s:
register('ru_approx', (number, index) => {
return [
['только что', 'скоро'],
['только что', 'скоро'],
['недавно', 'скоро'],
['недавно', 'скоро'],
['сегодня', 'сегодня'],
['сегодня', 'сегодня'],
['вчера', 'завтра'],
['на этой неделе', 'на этой неделе'],
['на прошлой неделе', 'на следующей неделе'],
['на прошлой неделе', 'на следующей неделе'],
['в прошлом месяце', 'в следующем месяце'],
['в прошлом месяце', 'в следующем месяце'],
['в прошлом году', 'в следующем году'],
['давно', 'нескоро'],
][index];
});
format(Date.now() - 1000 * 60 * 60 * 5, 'ru_approx');
// → "сегодня"
По умолчанию строки начинаются со строчной буквы. Для заглавной:
function capitalizedFormat(date, locale = 'ru') {
const result = format(date, locale);
return result.charAt(0).toUpperCase() + result.slice(1);
}
capitalizedFormat(Date.now() - 60000, 'ru');
// → "1 Минуту назад"
Либо это реализуется прямо в локали:
register('ru_cap', (number, index) => {
const [past, future] = standardRuLocale(number, index);
return [
past.charAt(0).toUpperCase() + past.slice(1),
future.charAt(0).toUpperCase() + future.slice(1),
];
});
Если нужны тысячные разделители или нестандартная форматировка чисел:
register('ru_formatted', (number, index) => {
const formattedNumber = new Intl.NumberFormat('ru-RU').format(number);
return [
['только что', 'сейчас'],
[`${formattedNumber} сек. назад`, `через ${formattedNumber} сек.`],
// ...
][index];
});
Если не хочется менять локаль, результат можно трансформировать после вызова:
import { format } from 'timeago.js';
function decoratedFormat(date) {
const raw = format(date, 'ru');
return `[ ${raw} ]`;
}
decoratedFormat(Date.now() - 3600000);
// → "[ 1 час назад ]"
Иногда для близких дат нужен один формат, для далёких — другой:
import { format } from 'timeago.js';
function smartFormat(date) {
const diff = Date.now() - new Date(date).getTime();
const oneDa yMs = 1000 * 60 * 60 * 24;
if (diff < oneDayMs) {
return format(date, 'ru'); // Относительный
}
// Абсолютный для старых дат
return new Intl.DateTimeFormat('ru', {
day: 'numeric',
month: 'long',
year: 'numeric',
}).format(new Date(date));
}
const rtf = new Intl.RelativeTimeFormat('ru', { style: 'long' });
register('ru_intl', (number, index) => {
const units = ['second', 'second', 'minute', 'minute', 'hour', 'hour',
'day', 'day', 'week', 'week', 'month', 'month', 'year', 'year'];
const unit = units[index];
return [
rtf.format(-number, unit),
rtf.format(number, unit),
];
});
Этот подход объединяет встроенный Intl.RelativeTimeFormat с инфраструктурой обновления timeago.js.