格式化相对时间

显示“2 天前”而不是时间戳

问题

一个应用程序显示类似“2 天前发布”的时间戳。虽然这在英语中很清楚,但“2 天前”与“2 天后”(过去与未来)的逻辑和语法在不同语言中差异很大。简单的字符串拼接(例如 '2' + ' ' + '天前')无法生成语法正确的输出。

解决方案

使用像 react-intl 中的 FormattedRelativeTime 这样的专用组件。该组件接受一个数值(例如 -2)和一个单位(例如 'day'),并自动将其格式化为符合本地语言习惯的语法正确的字符串,例如“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:时间单位,例如 'day'、'hour'、'minute' 或 'second'。
  • numeric="auto":允许库使用诸如“昨天”或“明天”这样的词,而不是“1 天前”或“1 天后”。

3. 在页面中使用该组件

现在,您可以在任何页面上使用此组件。在传递 props 之前,您需要负责计算时间差。

// 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”。