Day.jsで相対日時を厳密に表示する(thresholds)

2 min read読了の目安(約1800字

僕が作るWebアプリでは、日付の表示にだいたいDay.jsを使っています。Day.jsを使えば相対日時の表示も簡単です。例えば、以下のようにして相対日時を出力できます。

import dayjs from "dayjs"

// 相対日時のプラグインを有効化
import relativeTime from "dayjs/plugin/relativeTime"
dayjs.extend(relativeTime)

// 日本語で ◯日前 のように表示する場合
import 'dayjs/locale/ja';
dayjs.locale('ja');

// 指定時刻から現在時刻との相対時間を取得
dayjs('2021-01-24T01:00:00').fromNow() // => 1時間前

「days ago」や「hours ago」の基準

ドキュメントのList of breakdown range - from-nowを見ると、この◯ days ago(日前)や◯ hours ago(時間前)などの表示のされ方は以下のような基準で分かれているようです。


デフォルトの範囲設定

「◯時間前」は「21時間前」までで、「22時間前」という表示はされません(「1日前」になります)。また「1日前」となるのは「22〜35時間前」ということが分かります。

相対日時の基準(thresholds)を厳密にする

プロジェクトによっては、この基準をより厳密にしたくなることもあると思います(23時間前の日時なら「1日前」ではなく「23時間前」と表示したい)。

ちょっと調べてみるとドキュメントにちゃんと書かれていました。

https://day.js.org/docs/en/customization/relative-time#relative-time-thresholds-and-rounding

以下のようにオプションを渡せばOKです。

// strict thresholds
const thresholds = [
  { l: 's', r: 1 },
  { l: 'm', r: 1 },
  { l: 'mm', r: 59, d: 'minute' },
  { l: 'h', r: 1 },
  { l: 'hh', r: 23, d: 'hour' },
  { l: 'd', r: 1 },
  { l: 'dd', r: 29, d: 'day' },
  { l: 'M', r: 1 },
  { l: 'MM', r: 11, d: 'month' },
  { l: 'y' },
  { l: 'yy', d: 'year' },
];
dayjs.extend(relativeTime, {
  thresholds,
});

ちなみにthresholdsオプション内のlrdは何を表しているのかは今のところドキュメントに書かれていません。型定義にも特に具体的な説明は書かれていません。

より細かくカスタマイズをしたい方はソースコードの該当の処理の部分を読むのが良いと思います(少し複雑ですが)。

ざっと見た感じ、カスタマイズする場合にもrの数字だけを変えるのが良さそうです。例えば「10ヶ月以上前なら1年前と表示したい」なら{ l: 'MM', r: 10, d: 'month' }とするといった感じですね。