Проверка покрытия локалей

Globalize опирается на данные CLDR (Unicode Common Locale Data Repository), поэтому понятие «поддерживаемая локаль» в контексте этой библиотеки не является фиксированным списком, встроенным в рантайм. Поддержка локалей определяется исключительно тем, какие наборы данных были загружены и зарегистрированы в процессе инициализации.

Архитектура локализации строится вокруг принципа «данные отдельно от логики». Это означает:

  • библиотека не содержит локали «из коробки»
  • каждая локаль активируется загрузкой CLDR-файлов
  • доступность форматов зависит от полноты загруженных данных

Таким образом, проверка покрытия локалей — это проверка состояния загруженного CLDR-контекста.


Базовая концепция проверки доступности локали

Состояние покрытия локали в Globalize определяется наличием следующих групп данных:

  • core CLDR данные (numbers, currencies, dates)
  • supplemental данные (likelySubtags, timeData, weekData)
  • локализованные ресурсы для конкретного языка/региона

Если хотя бы один критический набор отсутствует, локаль считается неполноценной.


Загрузка CLDR как индикатор покрытия

Перед проверкой локалей необходимо понимать, что они становятся «доступными» только после загрузки:

import Globalize from "globalize";

import likelySubtags from "cldr-core/supplemental/likelySubtags.json";
import numbers from "cldr-numbers-full/main/ru/numbers.json";
import currencies from "cldr-numbers-full/main/ru/currencies.json";
import caGregorian from "cldr-dates-full/main/ru/ca-gregorian.json";
import timeZoneNames from "cldr-dates-full/main/ru/timeZoneNames.json";

Globalize.load(
  likelySubtags,
  numbers,
  currencies,
  caGregorian,
  timeZoneNames
);

Globalize.locale("ru");

Фактически, наличие локали «ru» в системе означает, что соответствующие CLDR-данные загружены.


Проверка текущей активной локали

Текущая локаль отражает только выбранный контекст, а не покрытие:

Globalize.locale(); // "ru"

Этот вызов полезен для диагностики, но не подтверждает наличие всех необходимых данных.


Косвенная проверка покрытия через выполнение форматирования

Наиболее надёжный способ проверки покрытия локали — попытка выполнить операции форматирования. Если данные отсутствуют, библиотека выбросит ошибку.

Проверка числового формата

const formatNumber = Globalize.numberFormatter();

formatNumber(12345.67);

Если локаль не покрыта, ошибка возникает на этапе инициализации formatter.


Проверка валют

const formatCurrency = Globalize.currencyFormatter("USD");

formatCurrency(100);

Отсутствие currencies.json или связанных данных делает форматирование невозможным.


Проверка дат

const formatDate = Globalize.dateFormatter({ datetime: "medium" });

formatDate(new Date());

Недостаток ca-gregorian или timeZoneNames приводит к исключениям.


Использование CLDR metadata для анализа покрытия

CLDR содержит вспомогательные структуры, которые позволяют определить потенциально поддерживаемые локали.

На практике используется следующий подход:

  • анализ списка доступных файлов cldr-data
  • сопоставление с загруженными ресурсами
  • формирование реестра активных локалей

Пример ручного реестра:

const loadedLocales = new Set(["ru", "en", "de"]);

function isLocaleSupported(locale) {
  return loadedLocales.has(locale);
}

Это упрощённая модель, применяемая в приложениях поверх Globalize.


Проверка покрытия через вероятностные subtags

CLDR содержит механизм likelySubtags, который позволяет определять расширенные локали (например, enen-Latn-US).

Если данные likelySubtags загружены, можно проверить расширяемость локали:

import Globalize from "globalize";

Globalize.load(require("cldr-core/supplemental/likelySubtags.json"));

const resolved = Globalize.locale("en").locale;

Это позволяет оценить, может ли локаль быть корректно «развернута» в полноценный набор правил.


Использование Intl как дополнительного слоя проверки

Хотя это не часть Globalize, часто применяется как вспомогательный механизм:

Intl.DateTimeFormat.supportedLocalesOf(["ru", "fr", "xx"]);

Результат:

  • возвращаются только локали, поддерживаемые движком
  • не гарантирует наличие CLDR-данных Globalize
  • полезно для предварительной фильтрации

Практическая модель оценки покрытия

В реальных приложениях покрытие локали оценивается по трём уровням:

1. Наличие базовой локали

  • загружены numbers
  • загружены currencies
  • установлена locale

2. Полнота форматирования

  • даты работают без ошибок
  • валюты корректно отображаются
  • числа форматируются согласно правилам

3. Поддержка расширенных данных

  • likelySubtags присутствует
  • timeZoneNames доступны
  • supplemental CLDR загружен

Диагностика неполного покрытия

Типичные симптомы отсутствия данных:

  • ошибки при создании formatter’ов
  • fallback на дефолтные форматы
  • некорректные разделители чисел
  • отсутствие локализованных названий валют и временных зон

Пример защитной проверки:

function assertLocaleReady(locale) {
  try {
    Globalize.locale(locale);

    Globalize.numberFormatter()(1);
    Globalize.dateFormatter()(new Date());

    return true;
  } catch (e) {
    return false;
  }
}

Стратегия построения карты покрытия локалей

В крупных системах формируется таблица поддержки:

  • список локалей продукта
  • список загруженных CLDR модулей
  • матрица «локаль → доступные функции»

Пример структуры:

const localeCoverage = {
  ru: { numbers: true, dates: true, currencies: true },
  en: { numbers: true, dates: true, currencies: true },
  fr: { numbers: true, dates: false, currencies: true }
};

Это позволяет управлять деградацией интерфейса без ошибок выполнения.


Поведение при частичном покрытии

Globalize не реализует автоматическую «магическую» подмену локалей. При неполных данных поведение выражается в:

  • исключениях при форматировании
  • необходимости ручного fallback
  • использовании базовых английских форматов как резервных

Контроль покрытия в сборке приложения

В сборочных пайплайнах часто применяется проверка:

  • наличие всех CLDR JSON файлов
  • соответствие списка локалей конфигурации приложения
  • отсутствие «висячих» локалей без данных

Пример псевдологики:

const requiredLocales = ["ru", "en", "de"];

requiredLocales.forEach(locale => {
  if (!isLocaleSupported(locale)) {
    throw new Error(`Locale missing: ${locale}`);
  }
});

Итоговая модель понимания покрытия

Покрытие локалей в Globalize — это не свойство библиотеки, а характеристика загруженного набора данных CLDR. Проверка строится вокруг:

  • анализа загруженных ресурсов
  • пробного выполнения форматирования
  • контроля supplemental-данных
  • сопоставления с ожидаемыми локалями приложения