ユーザーのロケールで日付をフォーマットする方法

JavaScriptを使用して、各ユーザーの地域規則に従って日付を表示する

はじめに

日付は世界中で異なる表記がされます。アメリカ人は2025年3月15日を3/15/2025と書きますが、ヨーロッパ人は同じ日付を15/03/2025と書き、日本のユーザーは2025/3/15を期待します。日付フォーマットをハードコードすると、すべてのユーザーが同じ規則に従うと仮定することになります。

馴染みのない形式で日付を表示すると、混乱が生じます。15/03/2025を期待しているユーザーが3/15/2025を見ると、その日付が3月15日を表すのか、それとも存在しない15月の日付を表すのかを判断するために一時停止する必要があります。この認知的負荷は、アプリケーション内のすべての日付で積み重なります。

JavaScriptは、日付フォーマットを自動的に処理するためのIntl.DateTimeFormat APIを提供しています。このレッスンでは、日付フォーマットが文化によって異なる理由、APIの仕組み、そしてあらゆるロケールに対して日付を正しくフォーマットする方法を説明します。

日付フォーマットがロケールによって異なる理由

異なる地域では、日付を書くための異なる規則が発展してきました。これらの規則は、歴史的慣行、教育システム、文化的嗜好を反映しています。普遍的な単一のフォーマットは存在しません。

アメリカ合衆国では、日付は月-日-年のパターンに従います。2025年3月15日は3/15/2025と表示されます。

イギリス、ドイツ、フランス、スペインを含むほとんどのヨーロッパ諸国では、日付は日-月-年のパターンに従います。同じ日付は15/03/2025と表示されます。

日本、中国、韓国では、日付は年-月-日のパターンに従います。日付は2025/3/15と表示されます。

異なるロケールでは、異なる区切り文字も使用されます。アメリカ人はスラッシュを使用し、ドイツ人はピリオドを使用し、一部のロケールではハイフンやスペースを使用します。

月名も言語によって異なります。3月は、英語では「March」、ドイツ語では「März」、フランス語では「mars」、スペイン語では「marzo」、日本語では「3月」と表示されます。

日付を表示する際は、構成要素の順序と特定の書式規則の両方について、ユーザーの期待に合わせる必要があります。

Intl.DateTimeFormatを使用した日付の書式設定

Intl.DateTimeFormatコンストラクタは、ロケール固有の規則を適用する日付フォーマッタを作成します。最初の引数としてロケール識別子を渡し、次にDateオブジェクトを使用してformat()メソッドを呼び出します。

const formatter = new Intl.DateTimeFormat('en-US');
const date = new Date('2025-03-15');
console.log(formatter.format(date));
// Output: "3/15/2025"

これにより、スラッシュを使用した月-日-年のパターンを使用する米国英語のフォーマッタが作成されます。format()メソッドは、Dateオブジェクトを適切な書式の文字列に変換します。

Dateコンストラクタは、2025-03-15のようなISO 8601日付文字列を受け入れます。これにより、2025年3月15日午前0時(UTC)を表すDateオブジェクトが作成されます。その後、フォーマッタはこれをロケール固有の文字列に変換します。

異なるロケールでの同じ日付の書式設定

コンストラクタに渡すロケール識別子を変更することで、異なるロケールで同じ日付を書式設定できます。

const date = new Date('2025-03-15');

const usFormatter = new Intl.DateTimeFormat('en-US');
console.log(usFormatter.format(date));
// Output: "3/15/2025"

const gbFormatter = new Intl.DateTimeFormat('en-GB');
console.log(gbFormatter.format(date));
// Output: "15/03/2025"

const deFormatter = new Intl.DateTimeFormat('de-DE');
console.log(deFormatter.format(date));
// Output: "15.3.2025"

const jpFormatter = new Intl.DateTimeFormat('ja-JP');
console.log(jpFormatter.format(date));
// Output: "2025/3/15"

各フォーマッタは異なる規則を適用します。米国のフォーマッタはスラッシュを使用した月-日-年を使用します。英国のフォーマッタはスラッシュを使用した日-月-年を使用します。ドイツのフォーマッタはピリオドを使用した日-月-年を使用します。日本のフォーマッタはスラッシュを使用した年-月-日を使用します。

各ロケールがどのパターンや区切り文字を使用するかを知る必要はありません。APIはロケール識別子に基づいて、これらの詳細を自動的に処理します。

ユーザーのロケールでの日付の書式設定

特定のロケールをハードコーディングする代わりに、ブラウザからユーザーの優先言語を使用できます。navigator.languageプロパティは、ユーザーの最優先言語設定を返します。

const userLocale = navigator.language;
const formatter = new Intl.DateTimeFormat(userLocale);
const date = new Date('2025-03-15');

console.log(formatter.format(date));
// Output varies by user's locale
// For en-US: "3/15/2025"
// For en-GB: "15/03/2025"
// For de-DE: "15.3.2025"
// For ja-JP: "2025/3/15"

このアプローチでは、ユーザーが手動でロケールを選択する必要なく、各ユーザーの期待に応じて日付を表示します。ブラウザが言語設定を提供し、Intl APIが適切な書式規則を適用します。

優先言語の配列全体を渡して、フォールバック動作を有効にすることもできます。

const formatter = new Intl.DateTimeFormat(navigator.languages);
const date = new Date('2025-03-15');
console.log(formatter.format(date));

APIは配列からサポートする最初のロケールを使用します。これにより、ユーザーの最優先設定が利用できない場合に、より適切なフォールバック処理が提供されます。

APIが書式設定する内容の理解

Intl.DateTimeFormat APIはJavaScriptのDateオブジェクトを書式設定します。Dateオブジェクトは、日付、時刻、タイムゾーン情報を含む特定の時点を表します。

Dateオブジェクトを書式設定すると、APIはロケールの規則に従って文字列に変換します。デフォルトでは、APIは日付部分のみを書式設定し、時刻は省略します。

const formatter = new Intl.DateTimeFormat('en-US');

const dateWithTime = new Date('2025-03-15T14:30:00');
console.log(formatter.format(dateWithTime));
// Output: "3/15/2025"

Dateオブジェクトには時刻情報が含まれていますが、デフォルトのフォーマッターはそれを無視します。後のレッスンでは、日付と時刻を一緒に書式設定する方法、または時刻のみを書式設定する方法について説明します。

書式設定する日付の作成

Dateオブジェクトはいくつかの方法で作成できます。最も信頼性の高いアプローチは、ISO 8601日付文字列を使用することです。

const date1 = new Date('2025-03-15');
const date2 = new Date('2025-12-31');
const date3 = new Date('2025-01-01');

const formatter = new Intl.DateTimeFormat('en-US');

console.log(formatter.format(date1));
// Output: "3/15/2025"

console.log(formatter.format(date2));
// Output: "12/31/2025"

console.log(formatter.format(date3));
// Output: "1/1/2025"

ISO 8601文字列はYYYY-MM-DD形式を使用します。この形式は明確であり、すべてのロケールとタイムゾーンで一貫して機能します。

タイムスタンプからの日付の書式設定

UnixタイムスタンプからDateオブジェクトを作成することもできます。Unixタイムスタンプは、1970年1月1日UTCからのミリ秒数を表します。

const timestamp = 1710489600000; // March 15, 2025
const date = new Date(timestamp);

const formatter = new Intl.DateTimeFormat('en-US');
console.log(formatter.format(date));
// Output: "3/15/2025"

このアプローチは、API、データベース、または日付を数値として表す他のシステムからタイムスタンプを受け取る場合に機能します。

Date オブジェクトを最初に作成せずに、タイムスタンプを format() メソッドに直接渡すこともできます。

const formatter = new Intl.DateTimeFormat('en-US');
const timestamp = 1710489600000;

console.log(formatter.format(timestamp));
// Output: "3/15/2025"

API は Date オブジェクトとタイムスタンプの両方を受け入れます。コードに適した方法を使用してください。

現在の日付のフォーマット

現在の日付をフォーマットするには、引数なしで Date オブジェクトを作成します。これにより、現在の時刻を表す Date オブジェクトが作成されます。

const formatter = new Intl.DateTimeFormat('en-US');
const now = new Date();

console.log(formatter.format(now));
// Output: "10/15/2025" (or current date when run)

Date.now() を直接渡すこともできます。これは現在のタイムスタンプを数値として返します。

const formatter = new Intl.DateTimeFormat('en-US');

console.log(formatter.format(Date.now()));
// Output: "10/15/2025" (or current date when run)

どちらの方法でも同じ結果が得られます。

パフォーマンスのためのフォーマッターの再利用

新しい Intl.DateTimeFormat インスタンスを作成するには、ロケールデータの読み込みとオプションの処理が必要です。同じロケールと設定で複数の日付をフォーマットする必要がある場合は、フォーマッターを一度作成して再利用してください。

const formatter = new Intl.DateTimeFormat('en-US');

const dates = [
  new Date('2025-01-01'),
  new Date('2025-06-15'),
  new Date('2025-12-31')
];

dates.forEach(date => {
  console.log(formatter.format(date));
});
// Output:
// "1/1/2025"
// "6/15/2025"
// "12/31/2025"

この方法は、日付ごとに新しいフォーマッターを作成するよりも効率的です。数百または数千の日付を含む配列をフォーマットする場合、パフォーマンスの差が顕著になります。

テンプレート内での日付のフォーマット

Intl.DateTimeFormat は、ユーザーに日付を表示する任意の場所で使用できます。これには、HTML テンプレートへのフォーマット済み日付の挿入、テーブルでの日付の表示、またはユーザーインターフェースでのタイムスタンプの表示が含まれます。

const formatter = new Intl.DateTimeFormat(navigator.language);

const publishedDate = new Date('2025-03-15');
const updatedDate = new Date('2025-04-20');

document.getElementById('published').textContent = formatter.format(publishedDate);
document.getElementById('updated').textContent = formatter.format(updatedDate);

フォーマットされた文字列は、他の文字列値と同様に機能します。テキストコンテンツ、属性、またはユーザーに情報を表示するその他のコンテキストに挿入できます。