🕰️

Temporal を使って丸めた相対時刻表示をする

2023/08/14に公開

SNS などでよく見かける、記事投稿時刻の「N時間前」「M日前」のような、ざっくりとした時刻の差分表示を JS の新しい日付型の Temporal を使って実装する方法の紹介です。

ベースとなる時刻は Temporal.ZonedDateTime 型で管理されているものとすると、以下のような関数で、最大単位に丸めた差分時刻表示をすることが出来ます。

function relative(date: ZonedDateTime): string {
  const d = date.until(Temporal.Now.zonedDateTimeISO());
  if (d.total("day") > 1) {
    return d.round({ smallestUnit: "day" }).days + "日前";
  }
  if (d.total("hour") > 1) {
    return d.round({ smallestUnit: "hour" }).hours + "時間前";
  }
  if (d.total("minute") > 1) {
    return d.round({ smallestUnit: "minute" }).minutes + "分前";
  }
  if (d.total("second") > 1) {
    return d.round({ smallestUnit: "second" }).seconds + "秒前";
  }
  return "今";
}

上から解説すると、

date.until(Temporal.Now.zonedDateTimeISO())

の部分で、基準となる date と現在時刻を表す Temporal.Now.zonedDateTimeISO()until() で比較して、差分をとっています。この呼び出しで、時刻の差分を表す Temporal.Duration オブジェクトが返ってきます。

次に if 文の条件の

d.total("day") > 1

という式で、差分が1日以上だったら、という条件を表しています。.total(単位) メソッドは、その単位で見た時の差分の量を number で返します。

次の式の

d.round({ smallestUnit: "day" }).days + "日前"

で、差分を年単位で丸めた年数に "日前" という接尾辞をつけて返しています。.round({ smallestUnit: "day" })smallestUnit 単位で丸めた差分 (Tempral.Duration) を返す関数です。.days でその差分の日数が取得できます。すなわち日で丸めた時の日数です。

上記をまとめると、差分が1日以上の時は、日で丸めた日数に "日前" という文字列をつけて返す、という処理になります。

以下は同様で、差分が1時間以上の時は、時間で丸めて "時間前" をつけて返す、1分以上の場合は、分で丸めて "分前" を付けて返す。秒単位まで同じ事を繰り返した後で、それでも if に引っかからない場合は、"今" という文字列を返しています(与えられた date は未来の時刻ではない事を仮定しています)。

上の relative 関数を色々な ZonedDateTime に対して呼んだ例は以下のようになります。

console.log(relative(Temporal.ZonedDateTime.from("2023-08-11T09:28:52+09:00[Asia/Tokyo]")))
console.log(relative(Temporal.ZonedDateTime.from("2023-08-12T09:28:52+09:00[Asia/Tokyo]")))
console.log(relative(Temporal.ZonedDateTime.from("2023-08-14T02:28:52+09:00[Asia/Tokyo]")))
console.log(relative(Temporal.ZonedDateTime.from("2023-08-14T05:28:52+09:00[Asia/Tokyo]")))
console.log(relative(Temporal.ZonedDateTime.from("2023-08-14T09:28:52+09:00[Asia/Tokyo]")))
console.log(relative(Temporal.ZonedDateTime.from("2023-08-14T09:58:52+09:00[Asia/Tokyo]")))
console.log(relative(Temporal.ZonedDateTime.from("2023-08-14T10:23:32+09:00[Asia/Tokyo]")))
console.log(relative(Temporal.ZonedDateTime.from("2023-08-14T10:23:42+09:00[Asia/Tokyo]")))
console.log(relative(Temporal.ZonedDateTime.from("2023-08-14T10:23:50+09:00[Asia/Tokyo]")))
3日前
2日前
8時間前
5時間前
55分前
25分前
18秒前
8秒前
今

まとめ

本記事では、Temporal を使って、時刻の丸め差分表示をする方法を紹介しました。

Discussion