date-fnsで日付間の距離を分かりやすく表現する「formatDistance」関数


基本的な使い方

import { formatDistance } from 'date-fns';

const baseDate = new Date(2024, 5, 15, 13, 45, 0); // 基準となる日付
const otherDate = new Date(2024, 5, 16, 1, 23, 45); // 比較対象となる日付

const distance = formatDistance(baseDate, otherDate);
console.log(distance); // 結果: "1 日 9 時間 38 分"

上記の例では、baseDateotherDate の間の距離が "1 日 9 時間 38 分" であることを示しています。

"formatDistance" 関数は、以下の引数を受け取ります。

  1. baseDate
    基準となる日付オブジェクト
  2. otherDate
    比較対象となる日付オブジェクト
  3. options (オプション)
    フォーマット設定をカスタマイズするためのオプションオブジェクト

オプションの詳細

  • round
    小数点の丸め方を指定します。有効な値は以下の通りです。
    • 'floor' (切り捨て)
    • 'ceil' (切り上げ)
    • 'round' (四捨五入)
  • unit
    結果の単位を指定します。有効な値は以下の通りです。
    • 'years'
    • 'quarters'
    • 'months'
    • 'weeks'
    • 'days'
    • 'hours'
    • 'minutes'
    • 'seconds'
  • addSuffix
    true に設定すると、期間の後に接尾辞 (例: "前", "後") を追加します。
  • locale
    表示言語を指定します。デフォルトは現在のロケール設定となります。

フォーマット例

以下の例は、"formatDistance" 関数を使用して様々なフォーマットを出力する方法を示しています。

import { formatDistance } from 'date-fns';

const baseDate = new Date(2024, 5, 15, 13, 45, 0);
const otherDate = new Date(2024, 5, 16, 1, 23, 45);

console.log(formatDistance(baseDate, otherDate, { addSuffix: true })); // 結果: "1 日 9 時間 38 分後"
console.log(formatDistance(baseDate, otherDate, { unit: 'hours' })); // 結果: "25.83"
console.log(formatDistance(baseDate, otherDate, { unit: 'minutes', round: 'ceil' })); // 結果: "1549"


import { formatDistance } from 'date-fns';

const baseDate = new Date(2024, 5, 15, 13, 45, 0);
const otherDate = new Date(2024, 5, 16, 1, 23, 45);

const distance = formatDistance(baseDate, otherDate);
console.log(distance); // 結果: "1 日 9 時間 38 分"

言語の設定

import { formatDistance } from 'date-fns';

const baseDate = new Date(2024, 5, 15, 13, 45, 0);
const otherDate = new Date(2024, 5, 16, 1, 23, 45);

const japaneseDistance = formatDistance(baseDate, otherDate, { locale: ja });
console.log(japaneseDistance); // 結果: "1 日 9 時間 38 分"

const englishDistance = formatDistance(baseDate, otherDate, { locale: en });
console.log(englishDistance); // 結果: "1 day 9 hours 38 minutes"

単位の指定

import { formatDistance } from 'date-fns';

const baseDate = new Date(2024, 5, 15, 13, 45, 0);
const otherDate = new Date(2024, 5, 16, 1, 23, 45);

const hoursDistance = formatDistance(baseDate, otherDate, { unit: 'hours' });
console.log(hoursDistance); // 結果: "25.83"

const minutesDistance = formatDistance(baseDate, otherDate, { unit: 'minutes' });
console.log(minutesDistance); // 結果: "1549"

小数点の丸め方

import { formatDistance } from 'date-fns';

const baseDate = new Date(2024, 5, 15, 13, 45, 0);
const otherDate = new Date(2024, 5, 16, 1, 23, 45);

const floorDistance = formatDistance(baseDate, otherDate, { unit: 'hours', round: 'floor' });
console.log(floorDistance); // 結果: "25"

const ceilDistance = formatDistance(baseDate, otherDate, { unit: 'hours', round: 'ceil' });
console.log(ceilDistance); // 結果: "26"

const roundDistance = formatDistance(baseDate, otherDate, { unit: 'hours', round: 'round' });
console.log(roundDistance); // 結果: "26"
import { formatDistance } from 'date-fns';

const baseDate = new Date(2024, 5, 15, 13, 45, 0);
const otherDate = new Date(2024, 5, 16, 1, 23, 45);

const distanceWithSuffix = formatDistance(baseDate, otherDate, { addSuffix: true });
console.log(distanceWithSuffix); // 結果: "1 日 9 時間 38 分後"


手動計算

単純な距離計算であれば、手動で計算することも可能です。例えば、2つの日付間の差をミリ秒単位で取得し、それを適切な単位に変換することで表現できます。

const baseDate = new Date(2024, 5, 15, 13, 45, 0);
const otherDate = new Date(2024, 5, 16, 1, 23, 45);

const millisecondDiff = otherDate.getTime() - baseDate.getTime();

const days = Math.floor(millisecondDiff / (1000 * 60 * 60 * 24));
const hours = Math.floor((millisecondDiff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((millisecondDiff % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((millisecondDiff % (1000 * 60)) / 1000);

const distanceString = `${days}${hours} 時間 ${minutes}${seconds} 秒`;
console.log(distanceString); // 結果: "1 日 9 時間 38 秒"

利点

  • コードがシンプルで分かりやすい
  • ライブラリを導入する必要がない

欠点

  • 言語化に手間がかかる
  • 複雑なフォーマットやオプションに対応していない

Moment.js

Moment.js は、date-fns と同様に JavaScript における日付操作を簡素化するためのライブラリです。"formatDistance" 関数と同様の機能を提供しており、オプションも豊富です。

import moment from 'moment';

const baseDate = moment(2024, 5, 15, 13, 45, 0);
const otherDate = moment(2024, 5, 16, 1, 23, 45);

const distance = moment(otherDate).diff(baseDate, 'days', true);
console.log(distance); // 結果: "1 日 9 時間 38 分"

利点

  • 多くのユーザーに利用されており、情報やライブラリが豊富
  • date-fns と同様の使い方で、様々なフォーマットやオプションに対応している

欠点

  • 今後開発が終了する可能性がある
  • date-fns と比べて動作が重い

Lodash

Lodash は、JavaScript における様々なユーティリティを提供するライブラリです。"date-fns""Moment.js" ほど特化ではありませんが、_.since() 関数を使用して類似の機能を実現できます。

import _ from 'lodash';

const baseDate = new Date(2024, 5, 15, 13, 45, 0);
const otherDate = new Date(2024, 5, 16, 1, 23, 45);

const distance = _.since(baseDate, otherDate, { units: ['d', 'h', 'm', 's'] });
console.log(distance); // 結果: "1d 9h 38m"

利点

  • Lodash をすでに利用している場合は追加のライブラリを導入する必要がない
  • 軽量で読みやすいコード

欠点

  • 単位名のカスタマイズが難しい
  • date-fns や Moment.js ほどフォーマットやオプションが豊富ではない

時間経過を表示するライブラリ

Timeago.js や relative-time など、時間経過を自然な表現で表示するライブラリも存在します。これらのライブラリは、単に距離を計算するだけでなく、"X分前" や "Y秒後" のような表現に変換することができます。

import timeago from 'timeago.js';

const baseDate = new Date(2024, 5, 15, 13, 45, 0);