ユーザーのロケールに合わせた日付のフォーマット方法

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));
// 出力: "3/15/2025"

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

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

同じ日付を異なるロケールでフォーマットする

コンストラクタに渡すロケール識別子を変更することで、同じ日付を異なるロケール用にフォーマットできます。

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

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

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

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

const jpFormatter = new Intl.DateTimeFormat('ja-JP');
console.log(jpFormatter.format(date));
// 出力: "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));
// 出力はユーザーのロケールによって異なります
// en-US の場合: "3/15/2025"
// en-GB の場合: "15/03/2025"
// de-DE の場合: "15.3.2025"
// 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));
// 出力: "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));
// 出力: "3/15/2025"

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

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

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

タイムスタンプからの日付フォーマット

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

const timestamp = 1710489600000; // 2025年3月15日
const date = new Date(timestamp);

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

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

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

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

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

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

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

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

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

console.log(formatter.format(now));
// 出力: "10/15/2025"(実行時の現在の日付)

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

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

console.log(formatter.format(Date.now()));
// 出力: "10/15/2025"(実行時の現在の日付)

両方のアプローチは同一の結果を生成します。

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

新しい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));
});
// 出力:
// "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);

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