フォーマッターが実際に使用しているロケールとオプションを確認する方法

resolvedOptions()メソッドを使用して、任意のIntlフォーマッターの実際の設定を検査する

はじめに

JavaScriptでIntlフォーマッターを作成する際、リクエストしたオプションが必ずしも取得されるオプションとは限りません。ブラウザはロケールネゴシエーションを実行し、デフォルト値を埋め、設定を正規化して最終的な構成を作成します。resolvedOptions()メソッドを使用すると、フォーマッターが実際に使用している内容を正確に検査できます。

Intl APIのすべてのフォーマッターにはresolvedOptions()メソッドがあります。これにはIntl.DateTimeFormatIntl.NumberFormatIntl.ListFormatIntl.PluralRulesIntl.Collatorなどが含まれます。このメソッドは、入力を処理した後にフォーマッターが最終的に使用したすべての設定詳細を含むオブジェクトを返します。

このメソッドは主にデバッグ、ブラウザの動作の理解、および現在の環境で利用可能な機能の検出に役立ちます。

基本構文

resolvedOptions()メソッドはパラメータを取りません。任意のフォーマッターインスタンスで呼び出すと、オブジェクトを返します。

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

console.log(options);
// {
//   locale: 'en-US',
//   calendar: 'gregory',
//   numberingSystem: 'latn',
//   timeZone: 'America/Los_Angeles',
//   ...
// }

返されるオブジェクトには、日付フォーマッターの場合は最低限localecalendarnumberingSystemプロパティが、数値フォーマッターの場合はlocalenumberingSystemが常に含まれます。追加のプロパティは、指定したオプションとフォーマッタータイプがサポートする内容によって異なります。

リクエストされたオプションが解決されたオプションと異なる理由

リクエストしたオプションが解決されたオプションと異なる主な理由は3つあります。

第一に、ロケールネゴシエーションは、正確なリクエストがサポートされていない場合に利用可能な最適なロケールを見つけます。de-ATをリクエストしたがブラウザにはdeしかない場合、解決されたロケールはdeになります。

const formatter = new Intl.DateTimeFormat('de-AT-u-ca-buddhist');
const options = formatter.resolvedOptions();

console.log(options.locale);
// Likely outputs: 'de-AT' or 'de'

console.log(options.calendar);
// Likely outputs: 'gregory' (if Buddhist calendar is not supported)

次に、ブラウザは指定されていないオプションにデフォルト値を設定します。これらのデフォルト値はロケール固有です。

const formatter = new Intl.NumberFormat('en-US');
const options = formatter.resolvedOptions();

console.log(options.style);
// Outputs: 'decimal'

console.log(options.minimumFractionDigits);
// Outputs: 0

console.log(options.maximumFractionDigits);
// Outputs: 3

3つ目として、ブラウザは特定のオプションを正規形式に正規化します。dateStyleまたはtimeStyleを使用した場合、ブラウザはこれらを解決されたオプションに含めません。代わりに、それらが展開される個別のコンポーネントオプションを含めます。

使用されている実際のロケールの確認

解決されたオプションのlocaleプロパティは、フォーマッタが使用している正確なロケールを示します。これはロケールネゴシエーションの結果です。

const formatter = new Intl.DateTimeFormat(['zh-TW', 'zh-CN', 'en-US']);
const options = formatter.resolvedOptions();

console.log(options.locale);
// Outputs the first supported locale from the list

Unicode拡張キーワードを含むロケールをリクエストした場合、それらがサポートされていないか、個別のオプションとして適用された場合、解決されたロケールにはそれらのキーワードが含まれない可能性があります。

const formatter = new Intl.NumberFormat('en-US-u-nu-arab');
const options = formatter.resolvedOptions();

console.log(options.locale);
// Might output: 'en-US'

console.log(options.numberingSystem);
// Might output: 'arab' or 'latn' depending on support

日付と時刻のフォーマットオプションの検査

Intl.DateTimeFormatの場合、解決されたオプションには、どの日付と時刻のコンポーネントが表示されるか、およびその表示方法に関する詳細が含まれます。

const formatter = new Intl.DateTimeFormat('en-US', {
  year: 'numeric',
  month: 'long',
  day: 'numeric',
  timeZone: 'America/New_York'
});

const options = formatter.resolvedOptions();

console.log(options.year);
// Outputs: 'numeric'

console.log(options.month);
// Outputs: 'long'

console.log(options.day);
// Outputs: 'numeric'

console.log(options.timeZone);
// Outputs: 'America/New_York'

console.log(options.calendar);
// Outputs: 'gregory'

dateStyleまたはtimeStyleを使用した場合、これらのショートカットは解決されたオプションに含まれません。ブラウザはロケールに基づいて、それらを個別のコンポーネントオプションに展開します。

const formatter = new Intl.DateTimeFormat('en-US', {
  dateStyle: 'full'
});

const options = formatter.resolvedOptions();

console.log(options.dateStyle);
// Outputs: undefined

console.log(options.weekday);
// Outputs: 'long'

console.log(options.year);
// Outputs: 'numeric'

console.log(options.month);
// Outputs: 'long'

console.log(options.day);
// Outputs: 'numeric'

オプションを一切指定せずに日付フォーマッタを作成した場合、解決されたオプションは、ブラウザがそのロケールのデフォルトとして選択した内容を示します。

const formatter = new Intl.DateTimeFormat('ja-JP');
const options = formatter.resolvedOptions();

console.log(options);
// Shows default date component options for Japanese locale

数値フォーマットオプションの検査

Intl.NumberFormatの場合、解決されたオプションは、スタイル、精度、グループ化、およびその他のフォーマット詳細を示します。

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

const options = formatter.resolvedOptions();

console.log(options.style);
// Outputs: 'currency'

console.log(options.currency);
// Outputs: 'USD'

console.log(options.currencyDisplay);
// Outputs: 'symbol'

console.log(options.minimumFractionDigits);
// Outputs: 2

console.log(options.maximumFractionDigits);
// Outputs: 2

通貨のみを指定した場合でも、ブラウザがcurrencyDisplayと小数桁数のデフォルト値を設定していることがわかります。

丸め処理オプションを使用すると、解決されたオプションによって数値がどのように丸められるかを正確に確認できます。

const formatter = new Intl.NumberFormat('en-US', {
  minimumSignificantDigits: 3,
  maximumSignificantDigits: 5
});

const options = formatter.resolvedOptions();

console.log(options.minimumSignificantDigits);
// Outputs: 3

console.log(options.maximumSignificantDigits);
// Outputs: 5

他のフォーマッタータイプの検査

resolvedOptions()メソッドは、すべてのIntlフォーマッターで同じように動作します。

Intl.ListFormatの場合、タイプとスタイルが表示されます。

const formatter = new Intl.ListFormat('en-US', {
  style: 'long',
  type: 'conjunction'
});

const options = formatter.resolvedOptions();

console.log(options.locale);
// Outputs: 'en-US'

console.log(options.style);
// Outputs: 'long'

console.log(options.type);
// Outputs: 'conjunction'

Intl.PluralRulesの場合、タイプと最小/最大桁数が表示されます。

const formatter = new Intl.PluralRules('en-US', {
  type: 'ordinal'
});

const options = formatter.resolvedOptions();

console.log(options.locale);
// Outputs: 'en-US'

console.log(options.type);
// Outputs: 'ordinal'

console.log(options.minimumIntegerDigits);
// Outputs: 1

resolvedOptions()の一般的な使用例

最も一般的な使用例はデバッグです。フォーマットされた出力が期待通りに表示されない場合、resolvedOptions()を使用することで、フォーマッターが実際に何を行っているかを理解できます。

const formatter = new Intl.DateTimeFormat('en-US', {
  dateStyle: 'medium'
});

console.log(formatter.format(new Date()));
// Check the output

console.log(formatter.resolvedOptions());
// See exactly which options produced that output

もう1つの使用例は機能検出です。特定のカレンダー、数値体系、またはその他の機能がサポートされているかどうかを、それをリクエストして実際に解決された内容を確認することで確認できます。

const formatter = new Intl.DateTimeFormat('en-US', {
  calendar: 'islamic'
});

const options = formatter.resolvedOptions();

if (options.calendar === 'islamic') {
  console.log('Islamic calendar is supported');
} else {
  console.log('Islamic calendar is not supported, using ' + options.calendar);
}

また、resolvedOptions()を使用して、ユーザーのロケール設定を取得することもできます。ロケール引数なしでフォーマッターを作成すると、ブラウザはユーザーの設定を使用します。

const formatter = new Intl.DateTimeFormat();
const options = formatter.resolvedOptions();

console.log(options.locale);
// Outputs: the user's preferred locale

console.log(options.timeZone);
// Outputs: the user's time zone

console.log(options.hourCycle);
// Outputs: the user's hour cycle preference (12 or 24 hour)

最後に、解決されたオプションを使用して、同一のフォーマッターを再作成できます。返されたオブジェクトは、コンストラクタに渡すことができます。

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

const options = formatter1.resolvedOptions();

const formatter2 = new Intl.NumberFormat(options.locale, options);

// formatter2 will format numbers identically to formatter1

重要なポイント

resolvedOptions()メソッドは、フォーマッターが使用している実際の設定を含むオブジェクトを返します。この設定は、ロケールネゴシエーション、デフォルト値、正規化により、リクエストした内容と異なる場合があります。

すべてのIntlフォーマッターにこのメソッドがあります。パラメータなしで呼び出すと、localecalendarnumberingSystem、およびフォーマッター固有のオプションなどのプロパティを持つオブジェクトを受け取ります。

resolvedOptions()は、主にフォーマッターの動作のデバッグ、利用可能な機能の検出、ブラウザがオプションをどのように解釈したかの理解に使用します。返されたオブジェクトは、同一のフォーマッターを再作成したり、ユーザー設定を検査したりするためにも使用できます。