【初心者向け】date-fns formatRelativeで時間をスマートに表現する方法


具体的な動作

  1. 現在時刻と比較対象となる時刻の差を計算します。
  2. 差の絶対値に基づいて、適切な表現を選択します。
  3. 選択された表現必要な情報フォーマットして、結果を返却します。

  • 現在時刻比較対象となる時刻より1週間以上であれば、"2024年7月7日"のように日付で表現されます。
  • 現在時刻比較対象となる時刻より1週間以内であれば、**"先週""今週"**のように表現されます。
  • 現在時刻比較対象となる時刻より1日以内であれば、**"昨日""今日"**のように表現されます。
  • 現在時刻比較対象となる時刻より1時間以内であれば、**"数分前""30分前"**のように表現されます。
  • 現在時刻比較対象となる時刻より1分以内であれば、**"数秒前""1分前"**のように表現されます。

カスタマイズ

formatRelative関数は、オプションを使用して表現をカスタマイズすることができます。

  • formatDistance: 距離のフォーマットを設定することで、**"2時間前""120分前"**のように表現されるようになります。
  • baseDate: 基準となる日付を設定することで、**"先週""先週の日曜日~土曜日"**のように表現されるようになります。
  • locale: ロケールを設定することで、表現を言語に合わせることができます。
import { formatRelative, en } from 'date-fns';

const now = new Date();
const past = new Date(now.getTime() - 3600000); // 1時間前

const formattedDate = formatRelative(past, now, { locale: en });
console.log(formattedDate); // 出力: 1時間前


import { formatRelative, en } from 'date-fns';

const now = new Date();
const past = new Date(now.getTime() - 3600000); // 1時間前
const future = new Date(now.getTime() + 3600000); // 1時間後

const formattedPast = formatRelative(past, now, { locale: en });
const formattedFuture = formatRelative(future, now, { locale: en });

console.log(formattedPast); // 出力: 1時間前
console.log(formattedFuture); // 出力: 1時間後

ロケールを変更する

import { formatRelative, ja } from 'date-fns';

const now = new Date();
const past = new Date(now.getTime() - 3600000); // 1時間前

const formattedDate = formatRelative(past, now, { locale: ja });
console.log(formattedDate); // 出力: 1時間前

基準となる日付を設定する

import { formatRelative, en } from 'date-fns';

const now = new Date();
const past = new Date(now.getTime() - 86400000); // 1日前

const baseDate = new Date();
baseDate.setDate(baseDate.getDate() - 7); // 1週間前

const formattedDate = formatRelative(past, now, { locale: en, baseDate });
console.log(formattedDate); // 出力: 先週

距離のフォーマットを設定する

import { formatRelative, en } from 'date-fns';

const now = new Date();
const past = new Date(now.getTime() - 7200000); // 2時間前

const formattedDate = formatRelative(past, now, { locale: en, formatDistance: (token, value) => `${value}分` });
console.log(formattedDate); // 出力: 120分前
import { formatRelative, en } from 'date-fns';

const now = new Date();
const past = new Date(now.getTime() - 86400000); // 1日前

const baseDate = new Date();
baseDate.setDate(baseDate.getDate() - 7); // 1週間前

const formattedDate = formatRelative(past, now, {
  locale: en,
  baseDate,
  formatDistance: (token, value) => `${value}分`,
});
console.log(formattedDate); // 出力: 先週 120分前


代替方法

  1. Moment.jsLuxon などのライブラリを使用する
  2. 手動でフォーマットする

Moment.js や Luxon などのライブラリを使用する

Moment.jsLuxon などのライブラリは、date-fns と同様に時間操作やフォーマット機能を提供しています。これらのライブラリには、formatRelative 関数に似た機能が用意されている場合があり、date-fns では実現できない表現を実現できる可能性があります。

例:Moment.js

import moment from 'moment';

const now = moment();
const past = moment(now.subtract(1, 'hours'));
const future = moment(now.add(1, 'hours'));

const formattedPast = past.fromNow();
const formattedFuture = future.fromNow();

console.log(formattedPast); // 出力: 1時間前
console.log(formattedFuture); // 出力: 1時間後

手動でフォーマットする

formatRelative 関数の代わりに、手動でフォーマット することも可能です。これは、より柔軟な表現を実現したい場合や、特定のライブラリを使用したくない場合に役立ちます。

const now = new Date();
const past = new Date(now.getTime() - 3600000); // 1時間前

const formattedDate = getFormattedDate(past, now);

function getFormattedDate(past, now) {
  const seconds = Math.abs((now - past) / 1000);
  const minutes = Math.floor(seconds / 60);
  const hours = Math.floor(minutes / 60);
  const days = Math.floor(hours / 24);

  if (seconds < 60) {
    return `${seconds}秒前`;
  } else if (minutes < 60) {
    return `${minutes}分前`;
  } else if (hours < 24) {
    return `${hours}時間前`;
  } else if (days === 1) {
    return '昨日';
  } else {
    return `${days}日前`;
  }
}

console.log(formattedDate); // 出力: 1時間前