Настройка формата вывода

По умолчанию 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));
}

Использование форматтеров из Intl внутри локали

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.