相対時間を短形式または長形式で表示する方法

styleオプションを使用して、相対時間を省略形、完全な単語、またはコンパクトな記号として表示するかどうかを制御する

はじめに

「2時間前」や「3ヶ月後」のような相対的な時間を表示する場合、そのフォーマットは異なるスペースを占めます。コンテンツの経過時間を示すタイムスタンプは、利用可能なスペースと必要な明確さに応じて、「2時間前」、「2時間前」、「2h前」などと表示されることがあります。各フォーマットは読みやすさと水平方向のスペースのバランスを取っています。

異なるコンテキストでは異なるフォーマットの選択が必要です。投稿のタイムスタンプを表示するソーシャルメディアフィードでは、「2時間前」のような明確なテキストが有益です。複数のアクティビティインジケータを表示するモバイルダッシュボードでは、「2h前」のようなコンパクトなテキストが必要です。タイムラインイベントを表示するデータ可視化では、画面上に情報を収めるために最も凝縮された形式を使用します。

JavaScriptのIntl.RelativeTimeFormatは、この選択を制御するためのstyleオプションを提供しています。スペルアウトされた単語による長い表示、標準的な略語による短い表示、または可能な限り最もコンパクトな表現を選択できます。このオプションにより、相対的な時間がユーザーにどのように表示されるかを正確に制御できます。

styleオプションが制御するもの

Intl.RelativeTimeFormatstyleオプションは、"long""short""narrow"の3つの値を受け付けます。各値は相対時間出力の異なる詳細レベルを生成します。

long値は「2時間前」のような完全な単語をスペルアウトします。short値は「2時間前」のような標準的な略語を使用します。narrow値は「2h前」のような最もコンパクトな表現を生成し、多くの場合スペースを削除し最小限の記号を使用します。

const longFormatter = new Intl.RelativeTimeFormat("en-US", {
  style: "long"
});

console.log(longFormatter.format(-2, "hour"));
// 出力: "2 hours ago"

const shortFormatter = new Intl.RelativeTimeFormat("en-US", {
  style: "short"
});

console.log(shortFormatter.format(-2, "hour"));
// 出力: "2 hr. ago"

const narrowFormatter = new Intl.RelativeTimeFormat("en-US", {
  style: "narrow"
});

console.log(narrowFormatter.format(-2, "hour"));
// 出力: "2h ago"

styleオプションを省略した場合、デフォルトは"long"になります。つまり、明示的に異なる表示スタイルを要求しない限り、相対時間フォーマットは完全な単語を使用します。

長いスタイルで相対時間をフォーマットする

長いスタイルは完全な単語を表示します。このフォーマットは水平方向のスペースを多く使用する代わりに、最大限の明確さを提供します。

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "long"
});

console.log(formatter.format(-2, "hour"));
// 出力: "2 hours ago"

console.log(formatter.format(3, "day"));
// 出力: "in 3 days"

フォーマッタは単数形と複数形を自動的に処理します。1時間の場合は単数形の「hour」を使用し、複数時間の場合は複数形の「hours」を使用します。どの形式を使用するかを手動で決定する必要はありません。

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "long"
});

console.log(formatter.format(-1, "hour"));
// 出力: "1 hour ago"

console.log(formatter.format(-2, "hour"));
// 出力: "2 hours ago"

console.log(formatter.format(1, "day"));
// 出力: "in 1 day"

console.log(formatter.format(5, "day"));
// 出力: "in 5 days"

使用する単位に関係なく、各時間単位は完全に綴られます。

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "long"
});

console.log(formatter.format(-30, "second"));
// 出力: "30 seconds ago"

console.log(formatter.format(-5, "minute"));
// 出力: "5 minutes ago"

console.log(formatter.format(-3, "month"));
// 出力: "3 months ago"

console.log(formatter.format(2, "year"));
// 出力: "in 2 years"

長いスタイルは、ユーザーが略語を解釈する必要なく、相対時間を即座に明確にします。時間の略語に慣れていないユーザーにとって、綴られた単語はより理解しやすくなります。

短いスタイルで相対時間をフォーマットする

短いスタイルは、ほとんどの人が認識できる標準的な略語を使用します。このフォーマットは読みやすさとスペース効率のバランスを取ります。

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "short"
});

console.log(formatter.format(-2, "hour"));
// 出力: "2 hr. ago"

console.log(formatter.format(3, "day"));
// 出力: "in 3 days"

フォーマッタは一般的に認識される略語を使用します。時間は「hr.」、分は「min.」、秒は「sec.」になります。これらの略語は文字数を減らしながら読みやすさを維持します。

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "short"
});

console.log(formatter.format(-30, "second"));
// 出力: "30 sec. ago"

console.log(formatter.format(-5, "minute"));
// 出力: "5 min. ago"

console.log(formatter.format(-3, "month"));
// 出力: "3 mo. ago"

console.log(formatter.format(2, "year"));
// 出力: "in 2 yr."

各時間単位はその標準的な略語を使用します。秒は「sec.」、分は「min.」、月は「mo.」、年は「yr.」を使用します。これらの略語は広く認識されており、ほとんどのコンテキストでうまく機能します。

短いスタイルで過去と未来の両方の時間をフォーマットできます。

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "short"
});

console.log(formatter.format(-7, "day"));
// 出力: "7 days ago"

console.log(formatter.format(2, "week"));
// 出力: "in 2 wk."

console.log(formatter.format(-1, "quarter"));
// 出力: "1 qtr. ago"

フォーマッタは両方の方向を一貫して処理します。過去の時間は「ago」を使用し、未来の時間は「in」を使用します。方向に関係なく、略語は同じままです。

ナロースタイルで相対時間をフォーマットする

ナロースタイルは可能な限り最もコンパクトな表現を生成します。このフォーマットはスペースを削除し、最小限の記号を使用して文字を節約します。

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "narrow"
});

console.log(formatter.format(-2, "hour"));
// 出力: "2h ago"

console.log(formatter.format(3, "day"));
// 出力: "in 3 days"

フォーマッターはほとんどの単位に対して一文字の省略形と最小限のスペースを使用します。時間は「h」、分は「m」、秒は「s」になります。出力はショートスタイルやロングスタイルよりもコンパクトです。

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "narrow"
});

console.log(formatter.format(-30, "second"));
// 出力: "30s ago"

console.log(formatter.format(-5, "minute"));
// 出力: "5m ago"

console.log(formatter.format(-3, "month"));
// 出力: "3mo ago"

console.log(formatter.format(2, "year"));
// 出力: "in 2y"

ナロースタイルはロケールと単位によって異なります。一部の単位は大幅に短い出力を生成しますが、他はショートスタイルと同様のままです。英語では「days」はスペルアウトされたままですが、時間、分、秒は一文字に省略されます。

const formatter = new Intl.RelativeTimeFormat("en-US", {
  style: "narrow"
});

console.log(formatter.format(-7, "day"));
// 出力: "7 days ago"

console.log(formatter.format(2, "week"));
// 出力: "in 2w"

console.log(formatter.format(-1, "quarter"));
// 出力: "1q ago"

ナロースタイルは、スペースが非常に限られていて、ユーザーが時間測定のコンテキストに慣れている場合に最適です。この凝縮されたフォーマットは、ユーザーが明示的な区切りや説明なしに単位を解釈できることを前提としています。

ロング、ショート、ナロースタイルの比較

3つのスタイルオプションの違いは、同じ相対時間をそれぞれのオプションでフォーマットすると明確になります。

const longFormatter = new Intl.RelativeTimeFormat("en-US", {
  style: "long"
});

const shortFormatter = new Intl.RelativeTimeFormat("en-US", {
  style: "short"
});

const narrowFormatter = new Intl.RelativeTimeFormat("en-US", {
  style: "narrow"
});

const value = -2;
const unit = "hour";

console.log("Long:   " + longFormatter.format(value, unit));
console.log("Short:  " + shortFormatter.format(value, unit));
console.log("Narrow: " + narrowFormatter.format(value, unit));

// 出力:
// Long:   2 hours ago
// Short:  2 hr. ago
// Narrow: 2h ago

ロングスタイルは完全な単語と明示的なスペースを使用します。ショートスタイルはピリオド付きの標準的な省略形を使用します。ナロースタイルは最小限のスペースで一文字を使用します。この進行は明確さとスペース効率のトレードオフを示しています。

異なる相対時間の値を比較して、各スタイルがさまざまな時間範囲をどのように処理するかを確認できます。

const times = [
  { value: -30, unit: "second" },
  { value: -5, unit: "minute" },
  { value: -2, unit: "hour" },
  { value: 3, unit: "day" },
  { value: 2, unit: "week" },
  { value: -3, unit: "month" }
];

times.forEach(time => {
  const long = new Intl.RelativeTimeFormat("en-US", {
    style: "long"
  }).format(time.value, time.unit);

  const short = new Intl.RelativeTimeFormat("en-US", {
    style: "short"
  }).format(time.value, time.unit);

  const narrow = new Intl.RelativeTimeFormat("en-US", {
    style: "narrow"
  }).format(time.value, time.unit);

  console.log(`${time.value} ${time.unit}:`);
  console.log(`  Long:   ${long}`);
  console.log(`  Short:  ${short}`);
  console.log(`  Narrow: ${narrow}`);
  console.log("");
});

// 出力:
// -30 second:
//   Long:   30 seconds ago
//   Short:  30 sec. ago
//   Narrow: 30s ago
//
// -5 minute:
//   Long:   5 minutes ago
//   Short:  5 min. ago
//   Narrow: 5m ago
//
// -2 hour:
//   Long:   2 hours ago
//   Short:  2 hr. ago
//   Narrow: 2h ago
//
// 3 day:
//   Long:   in 3 days
//   Short:  in 3 days
//   Narrow: in 3 days
//
// 2 week:
//   Long:   in 2 weeks
//   Short:  in 2 wk.
//   Narrow: in 2w
//
// -3 month:
//   Long:   3 months ago
//   Short:  3 mo. ago
//   Narrow: 3mo ago

文字数の差は複数のタイムスタンプにわたると顕著になります。多くの相対時間を表示するフィードやリストでは、ナロースタイルはロングスタイルと比較して水平方向のスペースを大幅に節約します。

言語間で相対時間のスタイルがどのように異なるか

3つのスタイルオプションはすべて、指定したロケールに適応します。異なる言語では、異なる略語、単語、間隔の規則が使用されます。

const locales = ["en-US", "de-DE", "fr-FR", "ja-JP"];

const value = -2;
const unit = "hour";

locales.forEach(locale => {
  const longFormatter = new Intl.RelativeTimeFormat(locale, {
    style: "long"
  });

  const shortFormatter = new Intl.RelativeTimeFormat(locale, {
    style: "short"
  });

  console.log(locale + ":");
  console.log("  Long:  " + longFormatter.format(value, unit));
  console.log("  Short: " + shortFormatter.format(value, unit));
});

// Output:
// en-US:
//   Long:  2 hours ago
//   Short: 2 hr. ago
// de-DE:
//   Long:  vor 2 Stunden
//   Short: vor 2 Std.
// fr-FR:
//   Long:  il y a 2 heures
//   Short: il y a 2 h
// ja-JP:
//   Long:  2 時間前
//   Short: 2 時間前

ロングスタイルはロケールによって大きく異なります。これは各言語が時間単位に独自の単語を持ち、語順も異なるためです。ドイツ語では時間量の前に「vor」を使用し、フランス語では量の前に「il y a」を使用し、日本語では数字の後に時間指示子を配置します。フォーマッタは語順を自動的に処理します。

ショートスタイルもロケールの慣習に適応します。ドイツ語では時間に「Std.」を使用し、フランス語では「h」を使用し、日本語ではロングスタイルと同じ形式を使用します。これらのロケール固有の略語は、各文化が省略形で相対時間をどのように表記するかを反映しています。

フォーマッタは文法的なバリエーションを自動的に処理します。各ロケールはその言語で自然に見える出力を生成します。

const locales = ["en-US", "es-ES", "pt-BR"];

const value = -3;
const unit = "month";

locales.forEach(locale => {
  const narrowFormatter = new Intl.RelativeTimeFormat(locale, {
    style: "narrow"
  });

  console.log(locale + ": " + narrowFormatter.format(value, unit));
});

// Output:
// en-US: 3mo ago
// es-ES: hace 3 m
// pt-BR: há 3 meses

ナロースタイルはロケール間で変化を示します。英語では月に「mo」を使用し、スペイン語では「m」を使用し、ポルトガル語では「meses」とつづります。これらの違いはコンパクトな時間表記のロケール固有の慣習を反映しています。

ロングスタイルを使用するタイミング

ロングスタイルは、スペースの効率性よりも明確さとアクセシビリティが重要な場合に最適です。この選択により、相対的な時間が解釈を必要とせず、すぐに理解できるようになります。

アクセシビリティを重視したインターフェースでは、スクリーンリーダーがスペルアウトされた単語をより自然に発音するため、ロングスタイルが有益です。スクリーンリーダーが「2 hours ago」と発表する方が、「2 hr. ago」と読むよりも自然に聞こえます。後者は不自然に読まれたり、特別な発音ルールが必要になったりする可能性があります。

教育コンテンツでは、学習者が時間の略語に慣れていない可能性があるため、ロングスタイルが有益です。タイムスタンプを説明する教材では、混乱を避けるために単位をスペルアウトする必要があります。

アクティビティフィードやタイムラインでは、明確で会話的なトーンを維持するためにロングスタイルを使用します。ソーシャルメディアの投稿で「3 hours ago」と表示する方が、流れるテキストの中で「3h ago」よりも自然に読めます。

公式レポートやドキュメントでは、一貫した文章基準を維持するためにロングスタイルを使用します。ビジネスレポート、監査ログ、公式文書では、通常、相対的な時間を略さずにスペルアウトします。

国際的な読者は、言語を学んでいる可能性がある場合、ロングスタイルの恩恵を受けます。「hours」や「days」などのスペルアウトされた単位名は、非ネイティブスピーカーにとって略語よりも理解しやすいです。

function formatActivityTimestamp(date, locale) {
  const formatter = new Intl.RelativeTimeFormat(locale, {
    style: "long",
    numeric: "auto"
  });

  const now = new Date();
  const diffInMs = date - now;
  const diffInHours = Math.round(diffInMs / (1000 * 60 * 60));

  return formatter.format(diffInHours, "hour");
}

const threeHoursAgo = new Date(Date.now() - 3 * 60 * 60 * 1000);

console.log("Activity: " + formatActivityTimestamp(threeHoursAgo, "en-US"));
// Output: "Activity: 3 hours ago"

ロングスタイルは簡潔さよりも理解を優先します。ユーザーが曖昧さや解釈の労力なしに相対的な時間を把握する必要がある場合は常に使用してください。

短縮スタイルを使用するタイミング

短縮スタイルは、スペースが重要だが略語が広く理解されているコンテキストで最も効果的です。このフォーマットは明確さと効率性のバランスを取ります。

モバイルインターフェースは画面幅が限られているため、短縮スタイルの恩恵を受けます。複数のタイムスタンプを表示するダッシュボードカードでは、情報を画面に収めるためにコンパクトな相対時間表示が必要です。「2時間前」の代わりに「2時間前」を使用することで、タイムスタンプごとに文字数を節約でき、複数の値にわたって効果が積み重なります。

コメントセクションでは、インターフェースを煩雑にすることなくコメントが投稿された時間を表示するために短縮スタイルを使用します。コメントの横に「5分前」と表示することは、「5分前」よりもコンパクトでありながら明確さを保ちます。

列にタイムスタンプを表示するデータテーブルでは、一貫した幅が必要です。「時間」、「分」、「秒」などの短い略語は列幅を管理しやすくします。「時間」、「分」、「秒」などの長い単位は不必要に列を広げてしまいます。

通知パネルでは、通知を確認するユーザーは時間の略語に慣れているため、短縮スタイルを使用します。「1時間前」と表示する通知は、表示スペースの効率的な使用と明確さのバランスを取ります。

メールクライアントでは、メッセージの経過時間を表示するために短縮スタイルを使用します。メッセージリストに「2日前」と表示することは、「2日前」よりも明確で、完全に綴られた「2日前」よりもコンパクトです。

function formatCommentTimestamp(date, locale) {
  const formatter = new Intl.RelativeTimeFormat(locale, {
    style: "short",
    numeric: "auto"
  });

  const now = new Date();
  const diffInMs = date - now;
  const diffInMinutes = Math.round(diffInMs / (1000 * 60));

  return formatter.format(diffInMinutes, "minute");
}

const fiveMinutesAgo = new Date(Date.now() - 5 * 60 * 1000);

console.log(formatCommentTimestamp(fiveMinutesAgo, "en-US"));
// 出力: "5 min. ago"

短縮スタイルは明確さと効率性のバランスを取ります。ほとんどのユーザーは混乱することなく標準的な略語を認識します。

ナロースタイルを使用するタイミング

ナロースタイルは、文字数が非常に制限された状況で、ユーザーが時間表記に十分慣れている場合に最適です。

単一のメトリクスを表示するコンパクトなウィジェットは、表示サイズが最小限の場合にナロースタイルを使用できます。「5分前」よりも「5m前」と小さなテキストで表示するタイマーウィジェットの方が適しています。

密度の高い情報を持つデータの可視化はナロースタイルの恩恵を受けます。チャートラベル、グラフの注釈、タイムラインマーカーは、基礎となる視覚的コンテンツを隠さないように最小限のテキストが必要です。「2時間前」の代わりに「2h前」を使用することで、文脈を理解するユーザーにとって読みやすさを維持しながら文字数を節約できます。

限られたスペースを持つモバイルホーム画面のウィジェットは、情報密度を最大化するためにナロースタイルを使用します。小さなタイル内に複数の最近のイベントを表示するアクティビティ追跡ウィジェットは、コンパクトな相対時間表記の恩恵を受けます。

スマートウォッチインターフェースは、画面スペースが非常に限られているため、ナロースタイルを使用します。小さな円形画面に「1h前」と表示する方が、より長い形式よりも適しています。

タイムスタンプを持つ多くのアイテムを表示するリストビューでは、各行をコンパクトに保つためにナロースタイルを使用できます。最近再生したトラックを表示する音楽アプリ、視聴履歴を表示する動画アプリ、またはワークアウト履歴を表示するフィットネスアプリはすべて、最小限のタイムスタンプ形式の恩恵を受けます。

function formatCompactTimestamp(date, locale) {
  const formatter = new Intl.RelativeTimeFormat(locale, {
    style: "narrow",
    numeric: "auto"
  });

  const now = new Date();
  const diffInMs = date - now;
  const diffInHours = Math.round(diffInMs / (1000 * 60 * 60));

  return formatter.format(diffInHours, "hour");
}

const twoHoursAgo = new Date(Date.now() - 2 * 60 * 60 * 1000);

console.log(formatCompactTimestamp(twoHoursAgo, "en-US"));
// Output: "2h ago"

ナロースタイルは、ユーザーが時間表記に慣れており、単位を補助なしで解釈できることを前提としています。このオプションは明確さと引き換えに、最大限のスペース効率を実現します。

スタイルと数値オプションの組み合わせ

styleオプションはnumericオプションと連携します。numericオプションは「昨日」のような自然言語表現にするか、「1日前」のような数値表現にするかを制御します。styleオプションは数値表現が表示される場合の詳細度を制御します。

const autoLong = new Intl.RelativeTimeFormat("en-US", {
  numeric: "auto",
  style: "long"
});

console.log(autoLong.format(-1, "day"));
// 出力: "yesterday"

console.log(autoLong.format(-2, "day"));
// 出力: "2 days ago"

const autoShort = new Intl.RelativeTimeFormat("en-US", {
  numeric: "auto",
  style: "short"
});

console.log(autoShort.format(-1, "day"));
// 出力: "yesterday"

console.log(autoShort.format(-2, "day"));
// 出力: "2 days ago"

numeric"auto"で、フォーマッタが「昨日」のような自然言語を使用する場合、スタイリングする数値出力がないためstyleオプションは効果がありません。フォーマッタはスタイルに関係なく同じ出力を生成します。

フォーマッタが数値出力を生成する場合、styleオプションは詳細度を制御します。

const alwaysLong = new Intl.RelativeTimeFormat("en-US", {
  numeric: "always",
  style: "long"
});

console.log(alwaysLong.format(-1, "day"));
// 出力: "1 day ago"

const alwaysShort = new Intl.RelativeTimeFormat("en-US", {
  numeric: "always",
  style: "short"
});

console.log(alwaysShort.format(-1, "day"));
// 出力: "1 day ago"

const alwaysNarrow = new Intl.RelativeTimeFormat("en-US", {
  numeric: "always",
  style: "narrow"
});

console.log(alwaysNarrow.format(-1, "day"));
// 出力: "1 day ago"

英語では、日数の場合、3つのスタイルすべてが似たような出力を生成します。スタイルの違いは他の時間単位でより明確に現れます。

const alwaysLong = new Intl.RelativeTimeFormat("en-US", {
  numeric: "always",
  style: "long"
});

const alwaysShort = new Intl.RelativeTimeFormat("en-US", {
  numeric: "always",
  style: "short"
});

const alwaysNarrow = new Intl.RelativeTimeFormat("en-US", {
  numeric: "always",
  style: "narrow"
});

console.log("Long:   " + alwaysLong.format(-2, "hour"));
console.log("Short:  " + alwaysShort.format(-2, "hour"));
console.log("Narrow: " + alwaysNarrow.format(-2, "hour"));

// 出力:
// Long:   2 hours ago
// Short:  2 hr. ago
// Narrow: 2h ago

この組み合わせにより、自然言語表現を使用するかどうかと、数値出力の表示方法の両方を完全に制御できます。

覚えておくべきこと

Intl.RelativeTimeFormatでフォーマットする際、styleオプションは相対時間の表示方法を制御します。「2時間前」のような完全な単語には"long"を、「2時間前」のような標準的な省略形には"short"を、「2h前」のようなコンパクトな形式には"narrow"を設定します。このオプションを省略した場合、デフォルトは"long"です。

明確さとアクセシビリティがスペースよりも重要な場合や、ユーザーが時間の省略形に慣れていない可能性がある場合は、longスタイルを使用してください。スペースが重要で、ユーザーが標準的な省略形を理解している汎用アプリケーションにはshortスタイルを使用してください。narrowスタイルは、ユーザーが時間表記に非常に精通している、極めてスペースが制限されたコンテキストでのみ使用してください。

フォーマッターは、異なる単語、省略形、語順、間隔の規則など、ロケール固有のバリエーションを自動的に処理します。stylenumericオプションを組み合わせることで、自然言語が表示されるかどうかと数値出力の表示方法の両方を制御できます。