相対時間を短縮形または完全形で表示する方法

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

はじめに

「2時間前」や「3か月後」のような相対時間を表示する場合、フォーマットによって占めるスペースが異なります。コンテンツの経過時間を示すタイムスタンプは、利用可能なスペースと必要な明確さに応じて、「2時間前」、「2時間前」、または「2時間前」として表示できます。各フォーマットは、可読性と水平スペースのトレードオフを行います。

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

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

styleオプションが制御する内容

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

長いスタイルは、ユーザーが略語を解釈する必要なく、相対時間を即座に明確にします。時間の略語に不慣れなユーザーにとって、完全に表記された単語の方がアクセスしやすくなります。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

console.log(formatter.format(-1, "quarter"));
// Output: "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));

// Output:
// Long:   2 hours ago
// Short:  2 hr. ago
// Narrow: 2h ago

長いスタイルは完全な単語と明示的なスペースを使用します。短いスタイルはピリオド付きの標準的な略語を使用します。狭いスタイルは最小限のスペースで1文字を使用します。この進行は、明確さとスペース効率のトレードオフを示しています。

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

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("");
});

// Output:
// -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時間前」と読み上げる方が、「2時間前」よりも自然に聞こえます。後者は不自然に読まれたり、特別な発音ルールが必要になる場合があります。

教育コンテンツは、学習者が時間の略語に慣れていない可能性があるため、長い形式の恩恵を受けます。タイムスタンプを説明する教材は、混乱を避けるために単位を綴る必要があります。

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

正式な報告書や文書では、一貫した記述基準を維持するために長い形式を使用します。業務報告書、監査ログ、公式文書では、通常、相対時間を省略せずに完全に表記します。

国際的な利用者にとって、言語を学習中の場合、長い形式が有益です。「時間」や「日」のように単位名を完全に表記することで、非ネイティブスピーカーにとって省略形よりも理解しやすくなります。

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"));
// Output: "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"));
// Output: "yesterday"

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

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

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

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

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

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

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

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

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

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

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

console.log(alwaysNarrow.format(-1, "day"));
// Output: "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"));

// Output:
// Long:   2 hours ago
// Short:  2 hr. ago
// Narrow: 2h ago

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

覚えておくべきこと

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

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

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