Форматирование относительного времени

Отображение '2 дня назад' вместо временной метки

Проблема

Приложение отображает временную метку, например, "Опубликовано 2 дня назад". Хотя это понятно на английском, логика и грамматика для выражений "2 дня назад" и "через 2 дня" (прошлое vs. будущее) значительно различаются в разных языках. Простая конкатенация строк (например, '2' + ' ' + 'дня назад') не позволяет получить грамматически правильный результат.

Решение

Используйте специальный компонент, например, FormattedRelativeTime из react-intl. Этот компонент принимает числовое значение (например, -2) и единицу измерения (например, 'день') и автоматически форматирует его в локализованную, грамматически правильную строку, такую как "2 дня назад", "hace 2 días" или "gestern" (вчера).

Шаги

1. Создайте клиентский компонент для относительного времени

Компонент FormattedRelativeTime должен использоваться внутри клиентского компонента.

Создайте новый файл app/components/RelativeTime.tsx.

// app/components/RelativeTime.tsx
'use client';

import { FormattedRelativeTime } from 'react-intl';

type Props = {
  value: number;
  unit: Intl.RelativeTimeFormatUnit;
};

export default function RelativeTime({ value, unit }: Props) {
  return (
    <FormattedRelativeTime
      value={value}
      unit={unit}
      numeric="auto" // "auto" позволяет использовать "вчера" или "завтра"
      style="long"
    />
  );
}

2. Передайте параметры форматирования

Компонент FormattedRelativeTime принимает несколько ключевых свойств:

  • value: Количество единиц. Отрицательное значение (например, -2) указывает на прошлое ("2 дня назад"), а положительное значение (2) указывает на будущее ("через 2 дня").
  • unit: Единица времени, такая как 'день', 'час', 'минута' или 'секунда'.
  • numeric="auto": Это позволяет библиотеке использовать слова, такие как "вчера" или "завтра", вместо "1 день назад" или "через 1 день".

3. Используйте компонент на странице

Теперь вы можете использовать этот компонент на любой странице. Вы несёте ответственность за вычисление разницы во времени перед передачей свойств.

// app/[lang]/page.tsx
import RelativeTime from '@/app/components/RelativeTime';

export default function Home() {
  // Эти значения должны вычисляться динамически
  const daysSinceUpdate = -2;
  const hoursUntilEvent = 3;

  return (
    <div>
      <h1>Обновления</h1>
      <p>
        Файл обновлён: <RelativeTime value={daysSinceUpdate} unit="day" />
      </p>
      <p>
        Событие начнётся: <RelativeTime value={hoursUntilEvent} unit="hour" />
      </p>
    </div>
  );
}

Пользователь, посещающий /en, увидит "File updated: 2 days ago" и "Event starts: in 3 hours". Пользователь, посещающий /es, увидит "File updated: hace 2 días" и "Event starts: dentro de 3 horas".