相対時刻のフォーマット

timestampを「3時間前」「5分後」のように相対時刻で表示する方法。Intl.RelativeTimeFormat、ライブラリ、実装戦略を網羅的に解説。

Format

3 hours ago

詳細な説明

相対時刻フォーマットは、絶対的なtimestampを「3時間前」「たった今」「昨日」「2週間後」のような人間にとって分かりやすい表現に変換します。このフォーマットは、ソーシャルメディアのフィード、通知リスト、アクティビティログなどに広く使われています。

ブラウザネイティブAPI — Intl.RelativeTimeFormat:

const rtf = new Intl.RelativeTimeFormat("ja", { numeric: "auto" });

rtf.format(-1, "day")      // "昨日"
rtf.format(-3, "hour")     // "3 時間前"
rtf.format(2, "week")      // "再来週"
rtf.format(-1, "minute")   // "1 分前"
rtf.format(0, "second")    // "今"  (numeric: "auto" の場合)

Intl.RelativeTimeFormat APIはローカライゼーションを自動的に処理します。日本語には「ja」、フランス語には「fr」を渡すだけです。numeric: "auto"オプションは、「1日前」の代わりに「昨日」のような自然なテキストを生成します。

適切な単位の計算:

APIでは単位と値を自分で決定する必要があります。以下は実用的な関数です:

function relativeTime(timestamp) {
  const now = Date.now();
  const diff = timestamp - now;
  const seconds = Math.round(diff / 1000);
  const minutes = Math.round(diff / 60000);
  const hours = Math.round(diff / 3600000);
  const days = Math.round(diff / 86400000);

  const rtf = new Intl.RelativeTimeFormat("ja", { numeric: "auto" });

  if (Math.abs(seconds) < 60) return rtf.format(seconds, "second");
  if (Math.abs(minutes) < 60) return rtf.format(minutes, "minute");
  if (Math.abs(hours) < 24) return rtf.format(hours, "hour");
  if (Math.abs(days) < 30) return rtf.format(days, "day");
  // 月、年のために拡張可能
}

よくある落とし穴:

相対時刻はユーザーがページを閲覧するにつれて変化します。動的な更新にはsetIntervalを使用して再計算しますが、不要な再レンダリングを避けるためにデバウンスしてください。サーバーレンダリングページの場合、サーバーで計算された相対時刻はクライアントが見る時点では古くなっている可能性があります。実際のtimestampでハイドレートし、クライアント側で計算するようにしましょう。

絶対時刻 vs. 相対時刻の使い分け: 最近のイベント(過去1週間以内)には相対時刻を使用してください。それより古いイベントには「2024年1月15日」のような絶対フォーマットに切り替えましょう。「387日前」のような分かりにくいラベルを防ぎます。

ユースケース

ソーシャルメディアのフィードや通知パネルでは、「2024-01-15T09:25:00Z」では暗算が必要なのに対し、「5分前」は即座に理解できるため、相対timestampが使用されています。

Try It — Timestamp Converter

フルツールを開く