ロケール固有の記号を使用した通貨のフォーマット方法

任意のロケールに対して、正しい通貨記号、位置、フォーマットで価格を表示する

はじめに

通貨記号は、価格がどの通貨を表しているかを識別します。ドル記号は米ドルを示し、ユーロ記号はユーロを示し、ポンド記号は英ポンドを示します。これらの記号は国際的なアプリケーションにとって不可欠です。なぜなら、ユーザーはどの通貨を閲覧または使用しているかを知る必要があるからです。

国によって通貨金額のフォーマット方法は異なります。アメリカ人は記号を金額の前に置いて$1,234.56と書きます。ドイツ人は記号を金額の後に置き、異なる区切り文字を使用して1.234,56 €と書きます。フランス語のフォーマットでは、桁グループ間にスペースを入れて1 234,56 €と書きます。"$" + amountのように通貨フォーマットをハードコーディングすると、すべてのユーザーが同じ規則に従うと仮定することになります。

JavaScriptはIntl.NumberFormat APIを提供しており、ロケールに適した記号と規則で通貨金額をフォーマットできます。このレッスンでは、通貨フォーマットがロケールによってどのように異なるか、また任意の言語や地域に対して価格を正しくフォーマットする方法について説明します。

通貨記号はロケールによって異なる

通貨によって使用される記号は異なります。米ドルは$を使用し、ユーロは€を使用し、英ポンドは£を使用し、日本円は¥を使用し、スイスフランは文脈に応じてFr.またはCHFを使用します。各記号は、ユーザーがどの通貨を閲覧しているかを素早く識別するのに役立ちます。

一部の記号は複数の通貨を表します。ドル記号$は、米ドル、カナダドル、オーストラリアドル、メキシコペソ、その他いくつかの通貨に使用されます。追加の文脈がなければ、ユーザーは価格がどのドル通貨を表しているかを判断できません。

通貨記号の位置はロケールによって異なります。英語圏の国々では通常、$100のように記号を金額の前に置きます。多くのヨーロッパ諸国では、100 €のように記号を金額の後に置きます。金額と記号の間にスペースを入れる国もあれば、入れない国もあります。

これらの違いは、記号と数値を単純に連結できないことを意味します。表示される通貨とそれを閲覧するユーザーのロケールの両方を理解する書式設定ロジックが必要です。

Intl.NumberFormatで通貨を書式設定する

Intl.NumberFormatコンストラクタは、オプションでstyle: 'currency'を渡すと通貨フォーマッタを作成します。また、ISO 4217通貨コードを使用してcurrencyオプションで書式設定する通貨を指定する必要があります。

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

console.log(formatter.format(1234.56));
// Output: "$1,234.56"

これにより、米ドルで金額を表示する米国英語用のフォーマッタが作成されます。format()メソッドは、数値をドル記号、桁区切り記号、小数点以下2桁を含む文字列に変換します。

currencyオプションには、3文字のISO 4217コードが必要です。一般的なコードには、米ドルのUSD、ユーロのEUR、英ポンドのGBP、日本円のJPY、カナダドルのCADなどがあります。

const usdFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

const eurFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'EUR'
});

const gbpFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'GBP'
});

console.log(usdFormatter.format(100));
// Output: "$100.00"

console.log(eurFormatter.format(100));
// Output: "€100.00"

console.log(gbpFormatter.format(100));
// Output: "£100.00"

各フォーマッタは、適切な通貨記号を自動的に挿入します。各通貨コードに対応する記号を知る必要はありません。

ロケールが記号の位置と書式を決定する

ロケールパラメータは、記号の位置、桁のグループ化、小数点記号など、通貨金額の書式設定方法を制御します。同じ通貨コードでも、ロケールによって異なる出力が生成されます。

const usFormatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'EUR'
});

const deFormatter = new Intl.NumberFormat('de-DE', {
  style: 'currency',
  currency: 'EUR'
});

const frFormatter = new Intl.NumberFormat('fr-FR', {
  style: 'currency',
  currency: 'EUR'
});

console.log(usFormatter.format(1234.56));
// Output: "€1,234.56"

console.log(deFormatter.format(1234.56));
// Output: "1.234,56 €"

console.log(frFormatter.format(1234.56));
// Output: "1 234,56 €"

3つのフォーマッタはすべてユーロを表示しますが、それぞれ異なる規則を使用します。米国英語のフォーマッタは、記号を金額の前に配置し、小数点記号としてピリオドを使用します。ドイツ語のフォーマッタは、記号を金額の後にスペースを空けて配置し、桁区切り記号としてピリオドを使用し、小数点記号としてコンマを使用します。フランス語のフォーマッタは、桁区切り記号としてスペースを使用します。

Intl APIは、指定されたロケールに基づいてこれらの違いを自動的に処理します。各ロケールの書式設定ルールを知る必要はありません。

通貨の書式設定には小数点以下の桁数が含まれます

通貨フォーマッターは、通貨に基づいて適切な小数点以下の桁数を自動的に決定します。ほとんどの通貨は、セントまたは同等の端数に対して小数点以下2桁を使用します。

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

console.log(formatter.format(100));
// Output: "$100.00"

console.log(formatter.format(100.5));
// Output: "$100.50"

console.log(formatter.format(100.567));
// Output: "$100.57"

フォーマッターは常に米ドルに対して小数点以下2桁を表示し、必要に応じてゼロで埋め、入力がより高い精度を持つ場合は丸めます。

一部の通貨は小数点以下の桁数がゼロです。日本円には端数単位がないため、金額は小数点以下なしで表示されます。

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'JPY'
});

console.log(formatter.format(1234.56));
// Output: "¥1,235"

円の金額には端数単位が含まれないため、フォーマッターは最も近い整数に丸めます。Intl APIは各通貨の小数点精度を認識し、自動的に適用します。

ユーザーのロケールに合わせて通貨を書式設定する

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

const userLocale = navigator.language;

const formatter = new Intl.NumberFormat(userLocale, {
  style: 'currency',
  currency: 'USD'
});

console.log(formatter.format(1234.56));
// Output varies by user's locale
// For en-US: "$1,234.56"
// For de-DE: "1.234,56 $"
// For fr-FR: "1 234,56 $US"

このアプローチは、各ユーザーの書式設定の期待に従って通貨金額を表示します。ドイツのユーザーには金額の後に記号がドイツの区切り文字とともに表示され、アメリカのユーザーには金額の前に記号がアメリカの区切り文字とともに表示されます。

また、navigator.languages配列全体を渡して、ユーザーの最優先設定が利用できない場合のフォールバック動作を有効にすることもできます。

const formatter = new Intl.NumberFormat(navigator.languages, {
  style: 'currency',
  currency: 'USD'
});

console.log(formatter.format(1234.56));

APIは配列からサポートする最初のロケールを使用し、自動的なフォールバック処理を提供します。

通貨フォーマッターの再利用

新しいIntl.NumberFormatインスタンスの作成には、ロケールデータの読み込みとオプションの処理が含まれます。同じロケールと通貨で複数の価格を書式設定する場合は、フォーマッターを一度作成して再利用してください。

const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD'
});

const prices = [19.99, 29.99, 49.99, 99.99];

prices.forEach(price => {
  console.log(formatter.format(price));
});
// Output:
// "$19.99"
// "$29.99"
// "$49.99"
// "$99.99"

このパターンは、価格ごとに新しいフォーマッターを作成するよりも効率的です。配列や多数の値を含むリストをフォーマットする際に、パフォーマンスの差が顕著になります。

アプリケーションでの価格表示

通貨フォーマッターは、ユーザーに価格を表示するあらゆる場所で使用できます。これには、商品一覧、ショッピングカート、チェックアウトページ、請求書、財務ダッシュボードなどが含まれます。

const formatter = new Intl.NumberFormat(navigator.language, {
  style: 'currency',
  currency: 'USD'
});

const productPrice = 29.99;
const taxAmount = 2.40;
const totalPrice = productPrice + taxAmount;

document.getElementById('product-price').textContent = formatter.format(productPrice);
document.getElementById('tax-amount').textContent = formatter.format(taxAmount);
document.getElementById('total-price').textContent = formatter.format(totalPrice);

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

複数通貨の処理

複数の通貨をサポートするアプリケーションでは、通貨ごとに個別のフォーマッターを作成する必要があります。通貨コードは表示される記号を決定し、ロケールは金額のフォーマット方法を決定します。

const locale = navigator.language;

const usdFormatter = new Intl.NumberFormat(locale, {
  style: 'currency',
  currency: 'USD'
});

const eurFormatter = new Intl.NumberFormat(locale, {
  style: 'currency',
  currency: 'EUR'
});

const gbpFormatter = new Intl.NumberFormat(locale, {
  style: 'currency',
  currency: 'GBP'
});

console.log(usdFormatter.format(100));
console.log(eurFormatter.format(100));
console.log(gbpFormatter.format(100));

各フォーマッターは適切な記号を表示し、その通貨に対するユーザーのロケール規則に従います。これにより、使用される通貨とロケールの組み合わせに関係なく、価格が正確かつ読みやすくなります。