サポートされているカレンダー、通貨、タイムゾーンのリストを取得する方法

JavaScript環境がサポートする国際化の値を確認する

はじめに

国際化されたアプリケーションを構築する際、ユーザーがカレンダー、通貨、タイムゾーン、その他のローカライゼーションオプションを選択できるドロップダウン、セレクター、フォームなどのユーザーインターフェース要素を作成する必要があることがよくあります。これらのコンポーネントを構築するには、JavaScript環境がサポートする値を知る必要があります。

古くなったり、ブラウザがサポートしていない値を含むハードコードされたリストを維持するのではなく、JavaScriptは実行時にサポートされている値を検出する方法を提供します。これにより、アプリケーションはユーザーの環境で正しく動作する選択肢のみを提供できます。

Intl.supportedValuesOf()メソッドは、サポートされている国際化の値のリストを返します。このメソッドをクエリして、JavaScript環境がサポートするカレンダー、通貨、タイムゾーン、数値システム、照合タイプ、測定単位を取得できます。

Intl.supportedValuesOfが返すもの

Intl.supportedValuesOf()メソッドは、返す値のタイプを指定する単一の文字列パラメータを受け取ります。そのタイプでサポートされている値を表す文字列の配列を返します。

const calendars = Intl.supportedValuesOf("calendar");
console.log(calendars);
// Output: ["buddhist", "chinese", "coptic", "dangi", ...]

このメソッドは6つの異なるキータイプをサポートしています。

  • "calendar"はサポートされているカレンダーシステムを返します
  • "currency"はサポートされている通貨コードを返します
  • "timeZone"はサポートされているタイムゾーン識別子を返します
  • "numberingSystem"はサポートされている数値システムを返します
  • "collation"はサポートされている照合タイプを返します
  • "unit"はサポートされている測定単位を返します

返される配列は常にアルファベット昇順でソートされ、重複する値を含まず、Unicode標準に従った正規識別子を使用します。

無効なキーを渡すと、メソッドはRangeErrorをスローします:

try {
  Intl.supportedValuesOf("invalid");
} catch (error) {
  console.error(error.name);
  // Output: "RangeError"
}

このエラーは、メソッドが認識しないキーを使用したことを示しています。

サポートされている暦の取得

暦システムは、日付の計算方法と表示方法を定義します。異なる文化圏では異なる暦システムを使用しており、JavaScriptはIntl APIを通じて多くの暦システムをサポートしています。

"calendar"キーは、JavaScript環境でサポートされているすべての暦システムを返します:

const calendars = Intl.supportedValuesOf("calendar");
console.log(calendars);
// Output: ["buddhist", "chinese", "coptic", "dangi", "ethioaa",
//          "ethiopic", "gregory", "hebrew", "indian", "islamic",
//          "islamic-civil", "islamic-rgsa", "islamic-tbla",
//          "islamic-umalqura", "iso8601", "japanese", "persian",
//          "roc"]

最も一般的な暦は"gregory"で、世界のほとんどの地域で使用されているグレゴリオ暦を表します。その他の暦には以下が含まれます:

  • "buddhist"はタイ仏暦用
  • "chinese"は伝統的な中国暦用
  • "islamic"はイスラム暦(ヒジュラ暦)用
  • "hebrew"はヘブライ暦用
  • "japanese"は元号を含む日本の暦用

各暦は、日付のフォーマット方法と計算方法に影響を与えます。特定の暦でIntl.DateTimeFormatを使用すると、その暦のルールに従って日付が表示されます:

const date = new Date("2025-10-15");

const gregorianFormat = new Intl.DateTimeFormat("en-US", {
  calendar: "gregory",
  year: "numeric",
  month: "long",
  day: "numeric"
});

const islamicFormat = new Intl.DateTimeFormat("en-US", {
  calendar: "islamic",
  year: "numeric",
  month: "long",
  day: "numeric"
});

console.log(gregorianFormat.format(date));
// Output: "October 15, 2025"

console.log(islamicFormat.format(date));
// Output: "Rabi' II 13, 1447 AH"

同じJavaScriptの日付でも、異なる暦でフォーマットすると異なる表示になります。

サポートされている暦を使用してセレクターを構築する

ユーザーインターフェースで暦セレクターを構築する場合、サポートされている暦を照会し、それぞれのオプションを作成します:

const calendars = Intl.supportedValuesOf("calendar");

const select = document.createElement("select");

calendars.forEach(calendar => {
  const option = document.createElement("option");
  option.value = calendar;
  option.textContent = calendar;
  select.appendChild(option);
});

document.body.appendChild(select);

これにより、現在の環境で動作する暦のみを含むドロップダウンが作成されます。

Intl.DisplayNamesを使用して、人間が読みやすい暦の名前を表示することで、このセレクターを強化できます:

const calendars = Intl.supportedValuesOf("calendar");
const displayNames = new Intl.DisplayNames(["en-US"], { type: "calendar" });

calendars.forEach(calendar => {
  const option = document.createElement("option");
  option.value = calendar;
  option.textContent = displayNames.of(calendar);
  // Creates options like "Gregorian Calendar", "Islamic Calendar", etc.
});

これにより、技術的な識別子ではなく、説明的な名前が表示されます。

サポートされている通貨の取得

通貨コードは、世界中で使用されている通貨システムを識別します。JavaScriptは、ISO 4217標準に基づいて数百の通貨コードをサポートしています。

"currency"キーは、JavaScript環境でサポートされているすべての通貨コードを返します。

const currencies = Intl.supportedValuesOf("currency");
console.log(currencies.length);
// Output: typically over 300

console.log(currencies.slice(0, 10));
// Output: ["ADP", "AED", "AFA", "AFN", "ALK", "ALL", "AMD", "ANG", "AOA", "AOK"]

通貨コードは3文字の大文字を使用します。一般的な例には次のものがあります。

  • "USD":米ドル
  • "EUR":ユーロ
  • "GBP":英ポンド
  • "JPY":日本円
  • "CNY":中国人民元

このリストには、現在使用されている通貨と、既に流通していない一部の歴史的な通貨の両方が含まれています。

通貨値をフォーマットする際は、使用する通貨を指定する必要があります。

const amount = 1234.56;

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

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

console.log(usdFormat.format(amount));
// Output: "$1,234.56"

console.log(eurFormat.format(amount));
// Output: "€1,234.56"

通貨コードによって、表示される記号と値のフォーマット方法が決まります。

ユーザー選択用の通貨のフィルタリング

ほとんどのアプリケーションでは、現在使用されている一般的な通貨のみを表示する必要があります。サポートされている通貨リストをフィルタリングして、ユーザーに関連するもののみを含めることができます。

const allCurrencies = Intl.supportedValuesOf("currency");
const commonCurrencies = ["USD", "EUR", "GBP", "JPY", "CNY", "INR", "CAD", "AUD"];

const availableCurrencies = commonCurrencies.filter(currency =>
  allCurrencies.includes(currency)
);

console.log(availableCurrencies);
// Output: ["USD", "EUR", "GBP", "JPY", "CNY", "INR", "CAD", "AUD"]

これにより、要件を満たし、かつブラウザでサポートされている通貨のみを提供できます。

通貨名の表示

通貨セレクターを構築する際は、3文字のコードではなく、わかりやすい名前を表示します。

const currencies = ["USD", "EUR", "GBP", "JPY"];
const displayNames = new Intl.DisplayNames(["en-US"], { type: "currency" });

currencies.forEach(currency => {
  const name = displayNames.of(currency);
  console.log(`${currency}: ${name}`);
});
// Output:
// USD: US Dollar
// EUR: Euro
// GBP: British Pound
// JPY: Japanese Yen

これにより、各コードが何を表しているかを示すことで、より良いユーザーエクスペリエンスを提供できます。

サポートされているタイムゾーンの取得

タイムゾーンは、同じ標準時を使用する地理的地域を表します。JavaScriptは、IANAタイムゾーンデータベースに基づいて数百のタイムゾーン識別子をサポートしています。

"timeZone"キーは、JavaScript環境でサポートされているすべてのタイムゾーン識別子を返します。

const timeZones = Intl.supportedValuesOf("timeZone");
console.log(timeZones.length);
// Output: typically over 400

console.log(timeZones.slice(0, 10));
// Output: ["Africa/Abidjan", "Africa/Accra", "Africa/Addis_Ababa",
//          "Africa/Algiers", "Africa/Asmara", "Africa/Bamako",
//          "Africa/Bangui", "Africa/Banjul", "Africa/Bissau", "Africa/Blantyre"]

タイムゾーン識別子はContinent/Cityの形式に従い、"America/New_York""Europe/London"のようになります。一部の識別子には"America/Indiana/Indianapolis"のような追加コンポーネントが含まれます。

日付と時刻をフォーマットする際、タイムゾーンは表示される現地時刻に影響します。

const date = new Date("2025-10-15T12:00:00Z");

const newYorkFormat = new Intl.DateTimeFormat("en-US", {
  timeZone: "America/New_York",
  year: "numeric",
  month: "long",
  day: "numeric",
  hour: "numeric",
  minute: "numeric",
  timeZoneName: "short"
});

const tokyoFormat = new Intl.DateTimeFormat("en-US", {
  timeZone: "Asia/Tokyo",
  year: "numeric",
  month: "long",
  day: "numeric",
  hour: "numeric",
  minute: "numeric",
  timeZoneName: "short"
});

console.log(newYorkFormat.format(date));
// Output: "October 15, 2025, 8:00 AM EDT"

console.log(tokyoFormat.format(date));
// Output: "October 15, 2025, 9:00 PM JST"

同じ時点が、タイムゾーンによって異なる現地時刻として表示されます。

タイムゾーンセレクターの構築

タイムゾーンセレクターは、ユーザーが理解できる方法で数百のオプションを提示する必要があります。地域ごとにタイムゾーンをグループ化することで、選択が容易になります。

const timeZones = Intl.supportedValuesOf("timeZone");

const grouped = timeZones.reduce((groups, tz) => {
  const [region] = tz.split("/");
  if (!groups[region]) {
    groups[region] = [];
  }
  groups[region].push(tz);
  return groups;
}, {});

console.log(Object.keys(grouped));
// Output: ["Africa", "America", "Antarctica", "Arctic", "Asia",
//          "Atlantic", "Australia", "Europe", "Indian", "Pacific", "Etc"]

この構成により、タイムゾーンが大陸ごとにグループ化され、ユーザーが自分の場所を見つけやすくなります。

各タイムゾーンの現在のオフセットを表示することで、ユーザーエクスペリエンスをさらに向上させることができます。

function getTimeZoneOffset(timeZone) {
  const date = new Date();
  const formatter = new Intl.DateTimeFormat("en-US", {
    timeZone,
    timeZoneName: "shortOffset"
  });
  const parts = formatter.formatToParts(date);
  const offsetPart = parts.find(part => part.type === "timeZoneName");
  return offsetPart ? offsetPart.value : "";
}

const timeZones = ["America/New_York", "Europe/London", "Asia/Tokyo"];

timeZones.forEach(tz => {
  const offset = getTimeZoneOffset(tz);
  console.log(`${tz}: ${offset}`);
});
// Output:
// America/New_York: GMT-4
// Europe/London: GMT+1
// Asia/Tokyo: GMT+9

オフセットを表示することで、ユーザーはゾーン間の時差を理解しやすくなります。

サポートされている数字体系の取得

数字体系は、数字の表示方法を定義します。ほとんどのアプリケーションは標準的なアラビア数字(0-9)を使用しますが、多くの言語には独自の伝統的な数字体系があります。

"numberingSystem"キーは、JavaScript環境でサポートされているすべての数字体系を返します。

const numberingSystems = Intl.supportedValuesOf("numberingSystem");
console.log(numberingSystems.slice(0, 10));
// Output: ["adlm", "ahom", "arab", "arabext", "armn", "armnlow",
//          "bali", "beng", "bhks", "brah"]

一般的な数字体系には以下が含まれます。

  • "latn"は標準的なラテン数字(0-9)用
  • "arab"はアラビア・インド数字用
  • "thai"はタイ数字用
  • "deva"はヒンディー語で使用されるデーヴァナーガリー数字用

異なる数字体系では、同じ数値が異なる形で表示されます。

const number = 12345;

const latinFormat = new Intl.NumberFormat("en-US", {
  numberingSystem: "latn"
});

const arabFormat = new Intl.NumberFormat("en-US", {
  numberingSystem: "arab"
});

const thaiFormat = new Intl.NumberFormat("en-US", {
  numberingSystem: "thai"
});

console.log(latinFormat.format(number));
// Output: "12,345"

console.log(arabFormat.format(number));
// Output: "١٢٬٣٤٥"

console.log(thaiFormat.format(number));
// Output: "๑๒,๓๔๕"

同じ数値が異なる数字の形状で表示されます。

サポートされている照合タイプの取得

照合タイプは、文字列のソートと比較方法を定義します。言語によってアルファベット順の規則が異なります。

"collation"キーは、JavaScript環境でサポートされているすべての照合タイプを返します。

const collations = Intl.supportedValuesOf("collation");
console.log(collations.slice(0, 10));
// Output: ["big5han", "compat", "dict", "direct", "ducet", "emoji",
//          "eor", "gb2312", "phonebk", "phonetic"]

一般的な照合タイプには以下が含まれます。

  • "standard":各言語のデフォルト照合
  • "phonetic":音声順序
  • "pinyin":中国語のピンイン順序
  • "emoji":絵文字のソート

照合は文字列配列のソート方法に影響します。

const words = ["ä", "z", "a"];

const standardCollator = new Intl.Collator("de-DE", {
  collation: "standard"
});

const phoneticCollator = new Intl.Collator("de-DE", {
  collation: "phonetic"
});

console.log(words.sort(standardCollator.compare));
// Output: ["a", "ä", "z"]

console.log(words.sort(phoneticCollator.compare));
// Output: ["a", "ä", "z"]

異なる照合タイプは、同じ入力に対して異なるソート順序を生成する可能性があります。

サポートされている単位の取得

単位識別子は、メートル、ガロン、摂氏度などの測定単位を表します。JavaScriptは測定値のフォーマットのために多くの単位タイプをサポートしています。

"unit"キーは、JavaScript環境でサポートされているすべての単位識別子を返します。

const units = Intl.supportedValuesOf("unit");
console.log(units.slice(0, 10));
// Output: ["acre", "bit", "byte", "celsius", "centimeter", "day",
//          "degree", "fahrenheit", "fluid-ounce", "foot"]

一般的な単位には以下が含まれます。

  • 長さ:"meter""kilometer""mile""foot"
  • 重量:"gram""kilogram""pound""ounce"
  • 温度:"celsius""fahrenheit"
  • 体積:"liter""gallon"
  • デジタル:"byte""kilobyte""megabyte"

測定値をフォーマットする際は、使用する単位を指定します。

const distance = 1000;

const meterFormat = new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "meter"
});

const kilometerFormat = new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "kilometer"
});

console.log(meterFormat.format(distance));
// Output: "1,000 m"

console.log(kilometerFormat.format(1));
// Output: "1 km"

単位によって、数値と共に表示される略語または記号が決まります。

"unit1-per-unit2"の形式を使用して単位を組み合わせることができます。

const speed = 100;

const speedFormat = new Intl.NumberFormat("en-US", {
  style: "unit",
  unit: "kilometer-per-hour"
});

console.log(speedFormat.format(speed));
// Output: "100 km/h"

これにより、時速キロメートルやガロンあたりのマイルなどの複合単位が作成されます。

動的なユーザーインターフェースの構築

Intl.supportedValuesOf()の主な使用例は、現在のJavaScript環境に適応するユーザーインターフェースの構築です。オプションをハードコーディングするのではなく、実行時にサポートされている値をクエリします。

この例では、ユーザーが希望するカレンダー、通貨、タイムゾーンを選択できる設定フォームを作成します。

function buildSettingsForm() {
  const form = document.createElement("form");

  // Calendar selector
  const calendarSelect = buildSelector(
    "calendar",
    Intl.supportedValuesOf("calendar")
  );
  form.appendChild(createFormGroup("Calendar", calendarSelect));

  // Currency selector
  const currencies = ["USD", "EUR", "GBP", "JPY", "CNY"];
  const currencySelect = buildSelector("currency", currencies);
  form.appendChild(createFormGroup("Currency", currencySelect));

  // Time zone selector
  const timeZones = Intl.supportedValuesOf("timeZone");
  const timeZoneSelect = buildSelector("timeZone", timeZones);
  form.appendChild(createFormGroup("Time Zone", timeZoneSelect));

  return form;
}

function buildSelector(name, values) {
  const select = document.createElement("select");
  select.name = name;

  values.forEach(value => {
    const option = document.createElement("option");
    option.value = value;
    option.textContent = value;
    select.appendChild(option);
  });

  return select;
}

function createFormGroup(label, input) {
  const group = document.createElement("div");
  const labelElement = document.createElement("label");
  labelElement.textContent = label;
  group.appendChild(labelElement);
  group.appendChild(input);
  return group;
}

document.body.appendChild(buildSettingsForm());

これにより、ブラウザがサポートする値のみを使用した完全な設定インターフェースが作成されます。

機能検出のためのサポート値の使用

Intl.supportedValuesOf()を使用して、特定の値を使用する前にサポートされているかどうかを検出できます。これにより、プログレッシブエンハンスメントとフォールバック戦略の実装が可能になります。

特定のカレンダーがサポートされているかどうかを確認します。

function isCalendarSupported(calendar) {
  const supported = Intl.supportedValuesOf("calendar");
  return supported.includes(calendar);
}

if (isCalendarSupported("islamic")) {
  console.log("Islamic calendar is supported");
} else {
  console.log("Islamic calendar is not supported");
}

このパターンは、あらゆる値タイプに対して機能します。

function isValueSupported(type, value) {
  try {
    const supported = Intl.supportedValuesOf(type);
    return supported.includes(value);
  } catch (error) {
    return false;
  }
}

console.log(isValueSupported("currency", "USD"));
// Output: true

console.log(isValueSupported("timeZone", "America/New_York"));
// Output: true

try-catchブロックは、Intl.supportedValuesOf()が利用できない環境を処理します。

これを使用して、ポリフィルの条件付き読み込みを行うことができます。

async function ensureCalendarSupport(calendar) {
  if (!isValueSupported("calendar", calendar)) {
    console.log(`Loading polyfill for ${calendar} calendar`);
    await import("./calendar-polyfill.js");
  }
}

await ensureCalendarSupport("persian");

これにより、必要な場合にのみ追加のコードが読み込まれます。