지원되는 달력, 통화, 시간대 목록을 가져오는 방법

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"는 지원되는 측정 단위를 반환합니다

반환된 배열은 항상 알파벳 오름차순으로 정렬되고, 중복 값이 없으며, 유니코드 표준에 따른 정규 식별자를 사용합니다.

잘못된 키를 전달하면 메서드는 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"]

통화 코드는 세 개의 대문자를 사용합니다. 일반적인 예는 다음과 같습니다:

  • 미국 달러의 경우 "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"]

이렇게 하면 요구 사항을 충족하고 브라우저에서 지원하는 통화만 제공할 수 있습니다.

통화 이름 표시

통화 선택기를 구축할 때는 세 글자 코드 대신 설명적인 이름을 표시하세요:

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"]

일반적인 숫자 체계는 다음과 같습니다:

  • 표준 라틴 숫자(0-9)의 경우 "latn"
  • 아랍-인도 숫자의 경우 "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");

이렇게 하면 필요할 때만 추가 코드가 로드됩니다.