Пользовательские форматы времени

Пользовательские форматы позволяют полностью изменить вид строки, которую возвращает библиотека. Это может быть сокращённый формат, описательный без чисел, смешанный — сначала относительное, потом абсолютное. Всё это реализуется через кастомные локали и обёртки над format.


Сокращённый формат

import { register, format } from 'timeago.js';

register('ru_abbr', (number, index) => {
  return [
    ['сейчас',     'сейчас'],
    ['%sс',        'ч/%sс'],
    ['%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л'],
  ][index];
});

format(Date.now() - 1000 * 60 * 45, 'ru_abbr');
// → "45м"

Смешанный формат: слова + числа

register('ru_mixed', (number, index) => {
  if (index === 0) return ['только что', 'скоро'];
  if (index <= 2) return ['несколько секунд назад', 'через несколько секунд'];
  if (index === 3) return ['минуту назад', 'через минуту'];
  if (index === 4 && number < 10) return [`${number} минут назад`, `через ${number} минут`];

  return [`${number} мин. назад`, `через ${number} мин.`];
});

Формат с указанием точного времени для старых дат

import { format } from 'timeago.js';

function richFormat(date, locale = 'ru') {
  const diff = Date.now() - new Date(date).getTime();
  const WEEK = 1000 * 60 * 60 * 24 * 7;

  if (diff > WEEK) {
    return new Intl.DateTimeFormat('ru', {
      day:   'numeric',
      month: 'long',
      year:  'numeric',
      hour:  '2-digit',
      minute:'2-digit',
    }).format(new Date(date));
  }

  return format(date, locale);
}

Вывод:

5 минут назад
4 часа назад
1 день назад
26 мая 2025 г., 10:00  ← для старых дат

Формат с подсказкой полного времени (tooltip)

function withTooltip(date, locale = 'ru') {
  const relative = format(date, locale);
  const absolute = new Intl.DateTimeFormat('ru', {
    dateStyle: 'medium',
    timeStyle: 'short',
  }).format(new Date(date));

  return { relative, absolute };
}

В HTML:

<time class="ago" title="{{ absolute }}">{{ relative }}</time>

Формат “X дней назад в HH:MM”

import { format } from 'timeago.js';

function formatWithTime(date, locale = 'ru') {
  const diff = Date.now() - new Date(date).getTime();
  const DAY  = 1000 * 60 * 60 * 24;

  if (diff < DAY) {
    return format(date, locale);
  }

  const time = new Intl.DateTimeFormat('ru', {
    hour:   '2-digit',
    minute: '2-digit',
  }).format(new Date(date));

  return `${format(date, locale)} в ${time}`;
}

formatWithTime(new Date(Date.now() - 1000 * 60 * 60 * 26), 'ru');
// → "1 день назад в 08:30"

Формат для уведомлений

register('ru_notify', (number, index) => {
  return [
    ['•',           '•'],
    ['только что',  'скоро'],
    ['только что',  'скоро'],
    ['1 мин',       'скоро'],
    ['%s мин',      'через %s мин'],
    ['1 ч',         'через 1 ч'],
    ['%s ч',        'через %s ч'],
    ['вчера',       'завтра'],
    ['%s дн',       'через %s дн'],
    ['нед',         'через нед'],
    ['%s нед',      'через %s нед'],
    ['мес',         'через мес'],
    ['%s мес',      'через %s мес'],
    ['год',         'через год'],
    ['%s л',        'через %s л'],
  ][index];
});

Формат для чата

В интерфейсах чата часто используется сокращённый стиль:

register('ru_chat', (number, index) => {
  return [
    ['сейч.', 'сейч.'],
    ['%дс',   '%дс'],
    ['%дс',   '%дс'],
    ['1м',    'ч1м'],
    ['%м',    'ч%м'],
    ['1ч',    'ч1ч'],
    ['%ч',    'ч%ч'],
    ['вчера', 'завтра'],
    ['%дн',   'ч%дн'],
    ['нед',   'чнед'],
    ['%нед',  'ч%нед'],
    ['мес',   'чмес'],
    ['%мес',  'ч%мес'],
    ['год',   'чгод'],
    ['%л',    'ч%л'],
  ][index];
});

Формат с префиксом “~” для приближённых значений

register('ru_approx', (number, index) => {
  const prefix = (index >= 3) ? '~' : '';

  const strs = [
    ['только что', 'скоро'],
    ['%s сек. назад', 'через %s сек.'],
    // ...
  ][index];

  return strs ? [prefix + strs[0], prefix + strs[1]] : strs;
});

Пользовательский формат через постобработку

Если не хочется менять локаль, форматирование можно модифицировать снаружи:

import { format } from 'timeago.js';

function formatDecorated(date, locale = 'ru') {
  const str = format(date, locale);
  const isPast = new Date(date).getTime() < Date.now();

  if (isPast) {
    return `? ${str}`; // только если допустимы эмодзи
  }

  return `⏳ ${str}`;
}

Шаблонный формат с интерполяцией

function templateFormat(date, template = '{time} назад', locale = 'ru') {
  const raw = format(date, locale);
  return template.replace('{time}', raw);
}

templateFormat(Date.now() - 3600000, 'Опубликовано {time}');
// → "Опубликовано 1 час назад"