Версии CLDR

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

CLDR представляет собой крупнейшее хранилище локализационных данных, поддерживаемое консорциумом Unicode. В него входят:

  • правила форматирования чисел;
  • локализованные названия месяцев и дней;
  • сведения о валютах;
  • шаблоны дат и времени;
  • правила сортировки;
  • правила множественного числа;
  • данные календарей;
  • сведения о системах письма и языках.

Globalize не содержит встроенного полного набора локализационных данных. Вместо этого библиотека использует внешние JSON-файлы CLDR, подключаемые отдельно.


Архитектура версий CLDR

Каждая версия CLDR содержит:

  • обновлённые локали;
  • новые языки;
  • исправленные шаблоны;
  • актуальные валютные данные;
  • изменения правил форматирования.

Версии CLDR выходят независимо от версий Globalize. Это означает, что:

  • одна версия Globalize может работать с несколькими версиями CLDR;
  • обновление CLDR не всегда требует обновления Globalize;
  • несовместимости между версиями всё же возможны.

Структурно данные CLDR распространяются через набор npm-пакетов:

cldr-core
cldr-dates-modern
cldr-numbers-modern
cldr-units-modern
cldr-cal-buddhist-modern

Каждый пакет соответствует отдельному разделу локализационной информации.


Основные поколения CLDR

Ранние версии

Первые версии CLDR содержали ограниченное количество локалей и сравнительно простую структуру данных. В старых релизах:

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

Globalize 0.x работал преимущественно с ранними XML-структурами CLDR.


CLDR 25–30

Период активной стандартизации структуры JSON-данных.

Основные изменения:

  • улучшение plural rules;
  • развитие календарных данных;
  • расширение coverage локалей;
  • внедрение modern/full пакетов.

Именно в этот период Globalize начал переходить к более стабильной интеграции с JSON-данными CLDR.


CLDR 31–35

Наиболее важный этап развития для современных приложений.

Появились:

  • улучшенные правила unit formatting;
  • расширенные timezone patterns;
  • обновлённые currency fractions;
  • улучшенная поддержка RTL-языков;
  • оптимизация plural categories.

Многие современные версии Globalize ориентированы именно на эти поколения CLDR.


CLDR 36+

Новые версии CLDR сосредоточены на:

  • точности региональных различий;
  • обновлениях геополитических данных;
  • улучшении гендерных правил;
  • поддержке новых Unicode-стандартов;
  • расширении locale aliases.

Для приложений с долгосрочной поддержкой рекомендуется использовать актуальные версии CLDR.


Совместимость Globalize и CLDR

Globalize 0.x

Старые версии Globalize:

  • имели собственную систему локализации;
  • использовали устаревшие структуры;
  • плохо совместимы с современными пакетами CLDR.

Поддержка таких версий сегодня практически отсутствует.


Globalize 1.x

Globalize 1.x полностью перешёл на архитектуру CLDR JSON.

Для корректной работы требуется:

Globalize.load(require("cldr-data").entireSupplemental());
Globalize.load(require("cldr-data").entireMainFor("en"));

В этой архитектуре:

  • Globalize отвечает за API;
  • CLDR отвечает за данные;
  • разработчик отвечает за загрузку нужных JSON-файлов.

Структура версий npm-пакетов CLDR

Пакеты CLDR обычно публикуются отдельно от Globalize.

Пример:

npm install cldr-data

Или:

npm install cldr-core
npm install cldr-dates-modern
npm install cldr-numbers-modern

Версии могут выглядеть так:

{
  "cldr-core": "^43.1.0",
  "globalize": "^1.7.0"
}

Важно понимать, что:

  • версия Globalize не обязана совпадать с версией CLDR;
  • слишком новые версии CLDR иногда ломают старые сборки;
  • некоторые данные могут менять структуру.

Пакеты modern и full

CLDR распространяется в двух основных вариантах.

modern

Содержит:

  • наиболее используемые локали;
  • популярные языки;
  • сокращённый набор данных.

Пример:

cldr-dates-modern

Преимущества:

  • меньший размер;
  • быстрее загрузка;
  • удобно для браузера.

Недостаток — отсутствие редких локалей.


full

Содержит полный набор локалей.

Пример:

cldr-dates-full

Особенности:

  • значительно больший объём;
  • максимальное покрытие языков;
  • подходит для enterprise-систем.

Изменения структуры между версиями

Одной из главных проблем при обновлении CLDR являются изменения структуры JSON.

Например, путь:

main.en.numbers

может сохраняться, но внутренние свойства изменяются.

Некоторые версии CLDR:

  • переименовывают категории;
  • изменяют plural rules;
  • обновляют timezone aliases;
  • меняют currency metadata.

Из-за этого старые приложения могут неожиданно ломаться после обновления данных.


Проверка версии CLDR

Версию CLDR можно определить несколькими способами.

Через package.json

{
  "dependencies": {
    "cldr-core": "43.1.0"
  }
}

Через Node.js

const pkg = require("cldr-core/package.json");

console.log(pkg.version);

Через npm

npm list cldr-core

Типичные проблемы при обновлении CLDR

Несовместимость plural rules

Plural rules могут изменяться между версиями.

Пример:

const pluralGenerator =
    Globalize("ru").pluralGenerator();

console.log(pluralGenerator(1));

Результат может отличаться между версиями CLDR.


Изменения валют

CLDR регулярно обновляет:

  • символы валют;
  • количество дробных знаков;
  • названия валют;
  • устаревшие валюты.

Например:

const formatter =
    Globalize("en").currencyFormatter("USD");

console.log(formatter(10));

Формат отображения может измениться после обновления CLDR.


Изменения timezone data

Некоторые временные зоны:

  • переименовываются;
  • получают новые aliases;
  • обновляют правила DST.

Это особенно критично для:

  • календарей;
  • систем бронирования;
  • финансовых приложений.

Стратегии обновления CLDR

Фиксация версии

Наиболее безопасный подход:

{
  "cldr-core": "43.1.0"
}

Вместо:

{
  "cldr-core": "^43.1.0"
}

Фиксированная версия предотвращает неожиданные изменения после установки зависимостей.


Тестирование локализации

После обновления CLDR необходимо проверять:

  • форматирование валют;
  • plural rules;
  • форматирование дат;
  • timezone formatting;
  • relative time messages.

Особенно важно тестировать:

  • арабские локали;
  • азиатские локали;
  • RTL-интерфейсы;
  • редкие языки.

Изолированное хранение данных

Крупные приложения часто:

  • хранят собственный snapshot CLDR;
  • не обновляют данные автоматически;
  • проводят ручную валидацию изменений.

Версии CLDR и производительность

Новые версии CLDR обычно содержат больше данных.

Это влияет на:

  • размер bundle;
  • время загрузки;
  • потребление памяти;
  • скорость инициализации Globalize.

Пример загрузки только необходимых данных:

Globalize.load(
    require("cldr-data/main/en/numbers.json"),
    require("cldr-data/main/en/ca-gregorian.json"),
    require("cldr-data/supplemental/numberingSystems.json")
);

Подход selective loading значительно уменьшает bundle size.


Использование cldr-data-downloader

Для автоматической загрузки конкретных версий CLDR используется пакет:

npm install cldr-data-downloader

Пример:

const downloader =
    require("cldr-data-downloader");

downloader({
    cldrVersion: "43.1.0"
});

Это полезно для:

  • CI/CD;
  • reproducible builds;
  • enterprise deployment.

Миграция между версиями

Пошаговая стратегия

  1. Обновление supplemental data.
  2. Проверка pluralization.
  3. Проверка currencies.
  4. Проверка calendars.
  5. Проверка timezone formatting.
  6. Проверка unit formatting.

Сравнение результатов форматирования

Полезная практика — snapshot testing.

Пример:

const result =
    Globalize("fr").formatNumber(12345.67);

expect(result).toBe("12 345,67");

После обновления CLDR тесты позволяют быстро обнаружить изменения.


Supplemental data и версии

Особую роль играют supplemental datasets:

supplemental/plurals.json
supplemental/timeData.json
supplemental/weekData.json

Именно эти данные чаще всего меняются между версиями CLDR.

Они определяют:

  • правила недель;
  • plural categories;
  • first day of week;
  • preferred hour cycle.

Версионирование locale aliases

Новые версии CLDR активно используют locale aliases.

Например:

zh-CN

может автоматически сопоставляться с:

zh-Hans-CN

Такие изменения способны влиять на:

  • fallback chains;
  • выбор переводов;
  • форматирование дат.

Поддержка новых языков

Каждая новая версия CLDR добавляет:

  • новые локали;
  • дополнительные переводы;
  • региональные варианты языка.

Например:

  • es-419;
  • en-150;
  • sr-Latn;
  • uz-Arab.

Globalize автоматически получает поддержку этих локалей после загрузки соответствующих данных.


Размеры пакетов CLDR

Полный CLDR может занимать десятки мегабайт.

Поэтому в production-приложениях применяются:

  • tree shaking;
  • selective imports;
  • lazy loading;
  • dynamic locale loading.

Пример динамической загрузки:

async function loadLocale(locale) {
    const data =
        await import(
            `cldr-data/main/${locale}/numbers.json`
        );

    Globalize.load(data.default);
}

Различия ICU и CLDR

CLDR часто используется совместно с ICU (International Components for Unicode).

Связь между ними:

  • CLDR предоставляет данные;
  • ICU реализует алгоритмы;
  • Globalize использует CLDR напрямую.

Во многих средах:

  • браузеры используют ICU;
  • Node.js использует ICU;
  • Globalize использует CLDR JSON.

Из-за различий версий результаты форматирования могут отличаться.


Актуальные рекомендации

Для современных проектов рекомендуется:

  • использовать Globalize 1.x;
  • применять свежие версии CLDR;
  • фиксировать версии зависимостей;
  • загружать только нужные locale data;
  • тестировать локализацию после каждого обновления;
  • избегать автоматических major-updates CLDR;
  • хранить snapshots форматирования.

Пример полной конфигурации

const Globalize = require("globalize");

Globalize.load(
    require("cldr-data/supplemental/likelySubtags.json"),
    require("cldr-data/supplemental/numberingSystems.json"),
    require("cldr-data/supplemental/plurals.json"),
    require("cldr-data/main/en/numbers.json"),
    require("cldr-data/main/en/ca-gregorian.json")
);

Globalize.locale("en");

const formatter =
    Globalize.numberFormatter();

console.log(formatter(12345.67));

В этой конфигурации:

  • используются supplemental datasets;
  • подключаются locale-specific данные;
  • Globalize получает доступ к актуальным правилам CLDR;
  • форматирование полностью зависит от версии подключённых данных.