1. 導入:なぜIntl.RelativeTimeFormatが重要なのか
Webアプリケーションで「投稿から3分前」「あと1時間で終了」といった日時表示を行うことは非常に一般的です。従来は、ミリ秒を計算して文字列を手動で連結する方法が一般的でしたが、言語ごとの文法や複数形の扱いに苦労していました。Intl.RelativeTimeFormat APIを使えば、ブラウザ標準機能だけで、多言語対応を含めた自然な相対時間を生成でき、複雑な条件分岐から解放されます。
2. 基礎知識:Intl.RelativeTimeFormatとは?
これはECMAScript国際化API(Intl)の一部で、相対的な時間を特定の言語に合わせて整形するための機能です。
・ロケール(locale): どの言語で表示するか(’ja-JP’ や ‘en-US’ など)。
・数値と単位: 経過時間の数値と、単位(’second’, ‘minute’, ‘hour’, ‘day’, ‘week’, ‘month’, ‘quarter’, ‘year’)を指定します。
これらを組み合わせることで、自動的にその言語にとって最も自然な「~前」「~後」という表現を作成してくれます。
3. 実装と解決策
実装の基本ステップは以下の通りです。
1. コンストラクタで言語ロケールを設定したインスタンスを作成する。
2. format()メソッドに数値と単位を渡して文字列を取得する。
これだけで、ライブラリに頼らずに国際化対応の相対時間表示が完結します。
4. サンプルプログラム
以下のコードは、日本語環境での相対時間表示の例です。コピーしてブラウザのコンソールで実行してみてください。
// 日本語ロケールでインスタンスを作成
const rtf = new Intl.RelativeTimeFormat('ja-JP', { numeric: 'auto' });
// 3日前を表示
console.log(rtf.format(-3, 'day')); // 出力: "3日前"
// 5分後を表示
console.log(rtf.format(5, 'minute')); // 出力: "5分後"
// 0秒前(現在)を表示する場合
console.log(rtf.format(0, 'second')); // 出力: "今"
// 英語環境に切り替えてみる
const rtfEn = new Intl.RelativeTimeFormat('en-US', { numeric: 'auto' });
console.log(rtfEn.format(-2, 'hour')); // 出力: "2 hours ago"
5. 応用・注意点
注意点1:numericオプションの活用
オプションの{ numeric: ‘auto’ }を指定すると、値が1の場合に「1日前」ではなく「昨日」と自動で変換してくれます(言語による)。より人間味のあるUIを作りたい場合に必須のオプションです。
注意点2:計算ロジックとの分離
このAPIはあくまで「整形」を行うためのものです。「現在時刻」と「対象日時」の差分を計算するロジック(ミリ秒を日や時間に変換する処理)は別途必要です。実務では、このAPIと組み合わせるために、差分計算用のユーティリティ関数を一つ用意しておくと非常に効率的です。
バグ回避のヒント:
単位を渡す際は、Intl.RelativeTimeFormatがサポートしている正確な文字列(単数形)を渡す必要があります。誤った文字列を渡すとエラーになるため、TypeScriptを使用している場合は型定義で単位を絞り込むのが安全です。