로케일 식별자가 유효한지 확인하는 방법

날짜, 숫자 및 통화 형식을 지정하기 전에 로케일 식별자의 유효성을 검사하세요

소개

애플리케이션이 사용자 입력, API 응답 또는 구성 파일에서 로케일 식별자를 받을 때, 사용하기 전에 유효성을 확인해야 합니다. 잘못된 로케일 식별자는 형식 지정 함수에서 오류를 발생시키거나 예상치 못한 결과를 생성합니다.

유효성 검사는 en-US와 같은 문자열이 국제 표준에 따라 구조적으로 올바른지 확인합니다. 이를 통해 Intl API 또는 기타 국제화 라이브러리에 로케일 식별자를 전달할 때 런타임 오류를 방지합니다.

JavaScript는 로케일 식별자의 유효성을 검사하는 두 가지 내장 메서드를 제공합니다. 두 메서드 모두 언어 태그 형식을 정의하는 BCP 47 표준에 따라 식별자의 구조를 확인합니다.

로케일 식별자를 유효하게 만드는 요소

로케일 식별자는 언어 태그에 대한 BCP 47 표준을 따릅니다. 이 표준은 언어, 문자 체계, 지역 및 확장 구성 요소를 결합하기 위한 구조와 규칙을 정의합니다.

유효한 로케일 식별자는 구성 요소를 구분하기 위해 밑줄이나 다른 문자가 아닌 하이픈을 사용합니다. 언어 코드는 인정된 ISO 639 코드여야 하며, 지역 코드는 인정된 ISO 3166-1 코드여야 합니다.

유효한 로케일 식별자의 예:

  • en (영어)
  • en-US (미국 영어)
  • zh-Hans (중국어 간체)
  • zh-Hans-CN (중국에서 사용되는 중국어 간체)
  • en-US-u-ca-gregory (그레고리력을 사용하는 미국 영어)

잘못된 로케일 식별자의 예:

  • en_US (하이픈 대신 밑줄 사용)
  • english (인정되지 않는 언어 코드)
  • en-USA (지역 코드는 세 글자가 아닌 두 글자여야 함)
  • EN-us (언어 코드는 소문자여야 함)
  • abc-XY (존재하지 않는 언어 코드)

검증 메서드는 이러한 구조적 규칙을 확인하고 코드가 인정된 표준인지 검증합니다.

Intl.getCanonicalLocales를 사용한 검증

Intl.getCanonicalLocales() 메서드는 로케일 식별자를 검증하고 정규 형식으로 반환합니다. 이 메서드는 단일 로케일 식별자 또는 식별자 배열을 허용합니다.

const result = Intl.getCanonicalLocales("en-US");
console.log(result);
// Output: ["en-US"]

메서드는 입력을 표준 형식으로 변환하여 정규화합니다. 잘못된 대소문자로 로케일 식별자를 전달하더라도 올바른 정규 형식을 반환합니다.

const result = Intl.getCanonicalLocales("EN-us");
console.log(result);
// Output: ["en-US"]

유효하지 않은 로케일 식별자를 전달하면 메서드는 RangeError를 발생시킵니다.

try {
  Intl.getCanonicalLocales("en_US");
} catch (error) {
  console.error(error.name);
  // Output: "RangeError"
  console.error(error.message);
  // Output: "en_US is not a structurally valid language tag"
}

이 오류는 식별자가 BCP 47 구조를 따르지 않음을 나타냅니다. 이 오류를 포착하여 유효하지 않은 입력을 적절하게 처리할 수 있습니다.

여러 로케일 식별자 검증

Intl.getCanonicalLocales() 메서드는 여러 로케일 식별자를 한 번에 검증하기 위해 배열을 허용합니다. 메서드는 모든 유효한 식별자에 대한 정규 형식 배열을 반환합니다.

const locales = ["en-US", "fr-FR", "es-MX"];
const result = Intl.getCanonicalLocales(locales);
console.log(result);
// Output: ["en-US", "fr-FR", "es-MX"]

메서드는 결과에서 중복된 로케일 식별자도 제거합니다.

const locales = ["en-US", "EN-us", "en-US"];
const result = Intl.getCanonicalLocales(locales);
console.log(result);
// Output: ["en-US"]

세 개의 입력 값 모두 동일한 로케일을 나타내므로 메서드는 하나의 정규 형식만 반환합니다.

배열의 로케일 중 하나라도 유효하지 않으면 전체 메서드가 오류를 발생시킵니다.

try {
  Intl.getCanonicalLocales(["en-US", "invalid", "fr-FR"]);
} catch (error) {
  console.error(error.message);
  // Output: "invalid is not a structurally valid language tag"
}

사용자가 제공한 목록을 검증할 때는 각 로케일을 개별적으로 검증하여 어떤 특정 식별자가 유효하지 않은지 식별하십시오.

Intl.Locale 생성자를 사용한 검증

Intl.Locale 생성자는 로케일 식별자를 검증하는 또 다른 방법을 제공합니다. 유효하지 않은 식별자로 로케일 객체를 생성하면 생성자는 RangeError를 발생시킵니다.

{/* CODE_PLACEHOLDER_0f956c822f5cdb9a1e1afb0db21c74eb */

생성자는 잘못된 식별자에 대해 오류를 발생시킵니다:

try {
  const locale = new Intl.Locale("en_US");
  console.log("Valid locale");
} catch (error) {
  console.error("Invalid locale");
  console.error(error.message);
}
// Output: "Invalid locale"
// Output: "invalid language subtag: en_US"

Intl.getCanonicalLocales()와 달리 Intl.Locale 생성자는 대소문자를 정규화하지 않습니다. 식별자가 올바른 대소문자를 사용해야 합니다:

const locale1 = new Intl.Locale("en-US");
console.log(locale1.baseName);
// Output: "en-US"

const locale2 = new Intl.Locale("EN-US");
console.log(locale2.baseName);
// Output: "en-US"

대문자와 소문자 언어 코드가 모두 허용되며, 생성자는 이를 표준 형식으로 정규화합니다.

검증 방법 선택

두 검증 방법은 서로 다른 목적을 제공하며 다른 기능을 제공합니다.

Intl.getCanonicalLocales()는 다음이 필요할 때 사용하세요:

  • 로케일 식별자를 표준 형식으로 정규화
  • 로케일 식별자 목록 검증 및 중복 제거
  • 일관되지 않은 대소문자를 표준 형식으로 변환
  • 객체를 생성하지 않고 로케일 식별자 검증

Intl.Locale 생성자는 다음이 필요할 때 사용하세요:

  • 로케일 식별자를 검증하고 즉시 해당 속성으로 작업
  • 식별자에서 언어, 지역 또는 스크립트와 같은 구성 요소 추출
  • 다른 Intl API와 함께 사용할 로케일 객체 생성
  • 로케일 식별자를 함께 검증하고 조작

Intl.Locale 생성자는 쿼리하고 수정할 수 있는 객체를 생성하기 때문에 더 강력합니다. 그러나 검증과 정규화만 필요한 경우 Intl.getCanonicalLocales()가 더 간단합니다.

사용자 입력 검증

사용자 입력에서 로케일 식별자를 받을 때는 애플리케이션에서 사용하기 전에 검증하세요. 이렇게 하면 오류를 방지하고 사용자가 잘못된 값을 입력할 때 명확한 피드백을 제공합니다.

function validateUserLocale(input) {
  try {
    const canonicalLocales = Intl.getCanonicalLocales(input);
    return {
      valid: true,
      locale: canonicalLocales[0]
    };
  } catch (error) {
    return {
      valid: false,
      error: "Please enter a valid locale identifier like en-US or fr-FR"
    };
  }
}

const result1 = validateUserLocale("en-US");
console.log(result1);
// Output: { valid: true, locale: "en-US" }

const result2 = validateUserLocale("english");
console.log(result2);
// Output: { valid: false, error: "Please enter a valid locale..." }

이 함수는 입력을 검증하고 표준 로케일 또는 사용자 친화적인 오류 메시지를 반환합니다.

구성 데이터 검증

애플리케이션은 종종 구성 파일이나 환경 변수에서 로케일 식별자를 로드합니다. 애플리케이션이 시작될 때 이러한 값을 검증하여 구성 오류를 조기에 발견하세요.

function loadLocaleConfig(configLocales) {
  const validLocales = [];
  const invalidLocales = [];

  for (const locale of configLocales) {
    try {
      const canonical = Intl.getCanonicalLocales(locale);
      validLocales.push(canonical[0]);
    } catch (error) {
      invalidLocales.push(locale);
    }
  }

  if (invalidLocales.length > 0) {
    console.warn("Invalid locale identifiers found:", invalidLocales);
  }

  return validLocales;
}

const config = ["en-US", "fr-FR", "invalid", "es_MX", "de-DE"];
const locales = loadLocaleConfig(config);
console.log(locales);
// Output: ["en-US", "fr-FR", "de-DE"]
// Warning: Invalid locale identifiers found: ["invalid", "es_MX"]

이 함수는 잘못된 로케일 식별자를 필터링하고 경고를 기록하여 애플리케이션이 유효한 로케일로 계속 작동할 수 있도록 합니다.

API 응답 유효성 검사

외부 API에서 로케일 식별자를 받을 때는 애플리케이션에서 사용하기 전에 유효성을 검사하세요. API는 비표준 형식이나 오류가 있는 로케일 식별자를 반환할 수 있습니다.

function processApiLocale(apiResponse) {
  const locale = apiResponse.preferredLocale;

  try {
    const validated = new Intl.Locale(locale);
    return {
      success: true,
      language: validated.language,
      region: validated.region,
      baseName: validated.baseName
    };
  } catch (error) {
    console.error("API returned invalid locale:", locale);
    return {
      success: false,
      fallback: "en-US"
    };
  }
}

const response1 = { preferredLocale: "fr-CA" };
console.log(processApiLocale(response1));
// Output: { success: true, language: "fr", region: "CA", baseName: "fr-CA" }

const response2 = { preferredLocale: "invalid_locale" };
console.log(processApiLocale(response2));
// Output: { success: false, fallback: "en-US" }

이 함수는 API 응답의 유효성을 검사하고 로케일에 대한 구조화된 정보를 추출하거나, 로케일이 유효하지 않은 경우 대체 값을 제공합니다.