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

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

Проблема

Приложение отображает временную метку, например: «Опубликовано 2 дня назад». Хотя это понятно по-английски, логика и грамматика выражений «2 дня назад» и «через 2 дня» (прошедшее и будущее время) сильно различаются в разных языках. Простая конкатенация строк (например, '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" allows "yesterday" or "tomorrow"
      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() {
  // You would calculate these values dynamically
  const daysSinceUpdate = -2;
  const hoursUntilEvent = 3;

  return (
    <div>
      <h1>Updates</h1>
      <p>
        File updated: <RelativeTime value={daysSinceUpdate} unit="day" />
      </p>
      <p>
        Event starts: <RelativeTime value={hoursUntilEvent} unit="hour" />
      </p>
    </div>
  );
}

Пользователь, который зайдёт на /en, увидит «Файл обновлён: 2 дня назад» и «Событие начнётся: через 3 часа». Пользователь, который зайдёт на /es, увидит «Файл обновado: hace 2 días» и «Событие начнётся: dentro de 3 horas».