Day.js で「〇〇分間」のような期間の日時を扱う

2022/02/05に公開

はじめに

「24時間」や「5分間」などのように、ある期間のような日時を扱いたいことがあります。

そのような場合は1日 = 24 * 60 * 60 * 1000 のようなミリ秒で保持していたりします。
計算するうえではミリ秒を使うと便利ですが、これを画面の表示などに使うとすると「日時分秒」などの単位を求める必要があります。

このようなケースでも Day.js は Plugin で対応してくれます。
前回に続き Day.js の Tips を紹介します。
Day.js で「〇〇分前」のような相対日時を扱う

解決したい課題

  • 時間が絶対表記で分かりにくい
  • 期間の時間表記の実装がたいへん
  • 時間の丸目処理がたいへん

動作環境

本記事は以下の環境で動作を確認しています。

  • Node.js 16
  • Day.js 1.10.7
  • TypeScript: 4.5
  • Ubuntu 18.04 LTS (WSL1)

Day.js の Duration plugin

公式の Duration プラグインを使うことで簡単に実装できます。
https://day.js.org/docs/en/plugin/duration

12ヶ月の期間を表現するシンプルなコード例です。

TypeScript
import dayjs, { extend } from 'dayjs';
import duration from 'dayjs/plugin/duration';

extend(duration);

dayjs.duration({ months: 12 });

期間を扱うプラグイン duration をインポートします。
extend(duration); で dayjs がプラグインを使えるように登録します。

dayjs.duration() で扱いたい期間を作ります。
引数は上記例のように期間を表すオブジェクトのほかに、ミリ秒、文字列などを受け取ります。
よく使われるケースとしてはミリ秒(e.g. 24 * 60 * 60 * 1000)でしょうか。

変換もサポートされていますが、ミリ秒で指定しないと若干ずれるようです。

実行例
> dayjs.duration({ months: 12 }).asYears();
0.9863013698630136

> dayjs.duration({ months: 12 }).asDays();
360

> dayjs.duration(365 * 24 * 60 * 60 * 1000).asYears();
1

> dayjs.duration(365 * 24 * 60 * 60 * 1000).asDays();
365

ヒューマナイズ表記

期間の値だけでしたらエポック・ミリ秒(UNIX ミリ秒)で扱うでもよいでしょう。
Day.js は人間にとって読みやすい単位に丸めてくれるところです。素晴らしい!
https://day.js.org/docs/en/durations/humanize

TypeScript
import dayjs, { extend } from 'dayjs';
import duration from 'dayjs/plugin/duration';
import relativeTime from 'dayjs/plugin/relativeTime';

extend(duration);
extend(relativeTime);

dayjs.duration({ months: 12 }).humanize();

RelativeTimeに依存しているので、Duration に加えて RelativeTime も読み込みます。
Duration のインスタンスに対して .humanize() を呼び出します。

実行例
> dayjs.duration({ months: 12 }).humanize();
'a year'

> dayjs.duration(365 * 24 * 60 * 60 * 1000).humanize();
'a year'

引数 withSuffix を受け取り、「in」を付ける場合は true で、デフォルト false。

実行例
> dayjs.duration({ months: 12 }).humanize();
'a year'

> dayjs.duration({ months: 12 }).humanize(true);
'in a year'

また、負の数も扱えます。

実行例
> dayjs.duration({ months: -12 }).humanize();
'a year'

> dayjs.duration({ months: -12 }).humanize(true);
'a year ago'

日本語の表記

Day.js の i18n に対応しているため、通常の日本語対応で表記が変わります。

TypeScript
import 'dayjs/locale/ja';
import dayjs, { locale, extend } from 'dayjs';
import duration from 'dayjs/plugin/duration';
import relativeTime from 'dayjs/plugin/relativeTime';

locale('ja');
extend(duration);
extend(relativeTime);

dayjs.duration({ months: 12 }).humanize();
実行例
dayjs.duration({ months: 12 }).humanize();
'1年'

dayjs.duration({ months: 12 }).humanize(true);
'1年後'

dayjs.duration({ months: -12 }).humanize(true);
'1年前'

まとめ

Day.js を使うことで、期間を表す時間の表記が簡単に扱えます。
そして Day.js が i18n 対応しているため、相対表記も設定に合わせて表記言語が変わります。

期間自体はエポックでも十分ですが、表示に必要な丸め処理は Day.js が助けてくれます。

参考サイト

GitHubで編集を提案

Discussion