1. 導入
Webアプリケーションで「3分前」「2時間後」といった相対時間を表示する際、標準的なIntl.RelativeTimeFormatのformatメソッドだけでは、出力された文字列全体を装飾したり、特定の単位だけ色を変えたりすることが困難です。formatToPartsメソッドを使用すれば、結果が構造化された配列として取得できるため、ReactやVueなどのコンポーネント指向の開発環境において、より柔軟かつ型安全なUI構築が可能になります。
2. 基礎知識
Intl.RelativeTimeFormatは、言語ごとの文法規則に基づき、相対的な時間を生成する組み込みオブジェクトです。通常、formatメソッドは「3日前」のような文字列を返しますが、formatToPartsはそれを構成する部品(リテラルや値)に分割して返します。これにより、例えば「3」という数値部分だけにCSSクラスを適用するといった制御が容易になります。
3. 実装/解決策
formatToPartsメソッドを呼び出すと、各部品が { type, value } というオブジェクトで構成された配列が返されます。typeプロパティには “integer”(整数)、”literal”(文字)、”unit”(単位)といった情報が含まれます。この配列をマップ(map)処理することで、任意のHTMLタグでラップして描画することができます。
4. サンプルプログラム
以下のコードは、相対時間を生成し、数値部分のみに独自のスタイルを適用するReact風のレンダリング例です。
// 1. 日本語環境でRelativeTimeFormatを初期化
const rtf = new Intl.RelativeTimeFormat('ja', { numeric: 'auto' });
// 2. 2時間前という情報をパーツに分解
const parts = rtf.formatToParts(-2, 'hour');
// 3. 配列を処理して、数値のみを強調するような構造を生成
const renderedParts = parts.map((part) => {
// 数値部分(integer)の場合は、spanタグで囲んでクラスを付与
if (part.type === 'integer') {
return `${part.value}`;
}
// それ以外のリテラルや単位はそのまま返す
return part.value;
}).join('');
// 結果: "2時間前" となる
console.log(renderedParts);
5. 応用・注意点
注意点1:ブラウザの対応状況
主要なモダンブラウザではサポートされていますが、古いブラウザや特定の環境ではポリフィルが必要になる場合があります。実務ではCan I Useなどでターゲットブラウザの対応状況を必ず確認してください。
注意点2:アクセシビリティ
数値だけをspanで囲む際、スクリーンリーダーが読み上げ順序を正しく解釈できるように注意が必要です。必要に応じてaria-labelを指定するなど、アクセシビリティを損なわない設計を心がけましょう。
応用:多言語対応
formatToPartsを使用することで、英語環境(”2 hours ago”)と日本語環境(”2時間前”)で語順が異なる場合でも、プログラム側で条件分岐を書くことなく、言語ごとの構成に合わせた柔軟な装飾が可能になります。グローバル展開するアプリケーションでは特に有用な手法です。