Библиотека Globalize построена поверх набора данных CLDR (Common Locale Data Repository). Именно CLDR предоставляет информацию о локалях, форматах дат, чисел, валют, единиц измерения, правилах множественного числа, календарях и системах письма. Без этих данных Globalize не способен корректно выполнять интернационализацию.
CLDR поддерживается организацией Unicode Consortium и считается стандартным источником локализованных данных для множества платформ и библиотек.
Globalize использует CLDR через библиотеку cldrjs,
которая обеспечивает доступ к данным и их навигацию.
Базовая схема взаимодействия выглядит следующим образом:
const Globalize = require("globalize");
Globalize.load(
require("cldr-data/main/en/numbers"),
require("cldr-data/supplemental/likelySubtags")
);
const globalize = new Globalize("en");
console.log(globalize.formatNumber(12345.67));
В данном примере:
cldr-data содержит JSON-структуры CLDR;Globalize.load() загружает данные;Globalize использует эти структуры для
форматирования.Структура CLDR разделена на два крупных раздела:
mainsupplementalКаждый из них решает собственную задачу.
mainСодержит данные конкретных локалей:
main/
en/
fr/
de/
ru/
Внутри каждой локали находятся файлы:
numbers.json
ca-gregorian.json
currencies.json
timeZoneNames.json
Эти файлы описывают локализованные значения.
Пример:
{
"main": {
"en": {
"numbers": {
"symbols-numberSystem-latn": {
"decimal": ".",
"group": ","
}
}
}
}
}
Здесь определены:
supplementalСодержит общие правила, применяемые ко всем локалям.
Пример структуры:
supplemental/
likelySubtags.json
numberingSystems.json
plurals.json
currencyData.json
Эти данные отвечают за:
mainКаждая локаль хранится в отдельной директории:
main/en/
main/ru/
main/ja/
Типичное содержимое:
main/en/
numbers.json
currencies.json
ca-gregorian.json
units.json
dateFields.json
Каждый файл отвечает за отдельную область интернационализации.
numbers.jsonОдин из важнейших компонентов CLDR.
Содержит:
Пример структуры:
{
"main": {
"en": {
"numbers": {
"defaultNumberingSystem": "latn",
"symbols-numberSystem-latn": {
"decimal": ".",
"group": ","
},
"decimalFormats-numberSystem-latn": {
"standard": "#,##0.###"
}
}
}
}
}
numbers.jsondefaultNumberingSystemОпределяет используемую систему цифр:
"defaultNumberingSystem": "latn"
Возможные значения:
| Значение | Описание |
|---|---|
latn |
латинские цифры |
arab |
арабские цифры |
thai |
тайские цифры |
symbols-numberSystem-latnСодержит символы форматирования.
Пример:
{
"decimal": ".",
"group": ",",
"percentSign": "%",
"plusSign": "+",
"minusSign": "-"
}
Globalize использует эти значения при выводе чисел.
decimalFormats-numberSystem-latnОписывает шаблоны чисел.
Пример:
{
"standard": "#,##0.###"
}
Шаблон интерпретируется следующим образом:
| Символ | Назначение |
|---|---|
# |
необязательная цифра |
0 |
обязательная цифра |
, |
разделитель групп |
. |
десятичный разделитель |
currencies.jsonСодержит локализованные названия валют.
Пример:
{
"main": {
"en": {
"numbers": {
"currencies": {
"USD": {
"displayName": "US Dollar",
"symbol": "$"
}
}
}
}
}
}
Globalize использует:
ca-gregorian.jsonСодержит данные григорианского календаря.
Пример структуры:
{
"main": {
"en": {
"dates": {
"calendars": {
"gregorian": {
}
}
}
}
}
}
Внутри располагаются:
Пример:
{
"months": {
"format": {
"wide": {
"1": "January",
"2": "February"
}
}
}
}
Типы представления:
| Тип | Назначение |
|---|---|
wide |
полное название |
abbreviated |
сокращение |
narrow |
минимальная форма |
Пример:
{
"dateFormats": {
"short": "M/d/yy",
"medium": "MMM d, y",
"long": "MMMM d, y",
"full": "EEEE, MMMM d, y"
}
}
Globalize выбирает формат в зависимости от используемого API.
units.jsonСодержит единицы измерения.
Пример:
{
"main": {
"en": {
"units": {
"long": {
"length-meter": {
"displayName": "meters"
}
}
}
}
}
}
Используется для:
dateFields.jsonСодержит локализованные временные интервалы.
Пример:
{
"day": {
"displayName": "day"
}
}
Применяется при работе с относительным временем:
globalize.formatRelativeTime(-1, "day");
Результат:
yesterday
supplementalФайлы из supplemental содержат общие правила и
алгоритмические данные.
Globalize требует эти данные для:
likelySubtags.jsonОдин из наиболее важных supplemental-файлов.
Позволяет расширять сокращённые локали.
Пример:
{
"supplemental": {
"likelySubtags": {
"en": "en-Latn-US",
"ru": "ru-Cyrl-RU"
}
}
}
Если указано:
new Globalize("en");
CLDR автоматически определяет:
en-Latn-US
Это позволяет корректно определить:
numberingSystems.jsonСодержит описание систем цифр.
Пример:
{
"supplemental": {
"numberingSystems": {
"latn": {
"digits": "0123456789"
}
}
}
}
Globalize использует эти данные при локализации чисел.
plurals.jsonСодержит правила множественного числа.
Пример:
{
"supplemental": {
"plurals-type-cardinal": {
"ru": {
"pluralRule-count-one":
"v = 0 and i % 10 = 1 and i % 100 != 11"
}
}
}
}
Для русского языка CLDR хранит сложные правила склонения.
Globalize использует их в сообщениях:
globalize.plural(5);
Результат:
many
CLDR использует стандартные категории:
| Категория | Назначение |
|---|---|
zero |
ноль |
one |
один |
two |
два |
few |
несколько |
many |
много |
other |
остальные |
Не каждая локаль использует все категории.
currencyData.jsonСодержит сведения о валютах.
Пример:
{
"supplemental": {
"currencyData": {
}
}
}
Внутри располагаются:
weekData.jsonОпределяет региональные правила недели.
Пример:
{
"supplemental": {
"weekData": {
"firstDay": {
"US": "sun",
"RU": "mon"
}
}
}
}
Эти данные используются календарями и форматированием дат.
CLDR использует глубоко вложенные JSON-структуры.
Типичный путь:
main.en.numbers.symbols-numberSystem-latn.decimal
Получение значения через cldrjs:
const Cldr = require("cldrjs");
const cldr = new Cldr("en");
const decimal = cldr.main(
"numbers/symbols-numberSystem-latn/decimal"
);
console.log(decimal);
mainВсе локализованные данные располагаются внутри:
{
"main": {
}
}
Следующий уровень — код локали:
{
"main": {
"en": {
}
}
}
supplementalОбщие данные располагаются отдельно:
{
"supplemental": {
}
}
Это позволяет избегать дублирования между локалями.
CLDR поддерживает каскадное наследование.
Пример:
en-GB
может наследовать данные от:
en
Если значение отсутствует в en-GB, используется значение
из базовой локали.
en{
"currency": "USD"
}
en-CA{
}
При отсутствии значения будет использовано:
USD
Globalize и cldrjs выполняют поиск данных по
цепочке:
en-CA
↓
en
↓
root
rootroot — базовая локаль CLDR.
Она содержит:
Структура:
main/root/
Если значение отсутствует:
ru-KZ
↓
ru
↓
root
Globalize получает данные из root.
cldrjs применяет строковые пути:
cldr.main(
"dates/calendars/gregorian/dateFormats/full"
);
Это эквивалентно глубокому доступу к JSON.
cldr.main("numbers/defaultNumberingSystem");
Одинаковый доступ ко всем разделам.
Пути можно формировать программно.
Globalize.loadГлавный механизм регистрации CLDR-данных.
Пример:
Globalize.load(
require("cldr-data/main/en/numbers"),
require("cldr-data/main/en/ca-gregorian"),
require("cldr-data/supplemental/likelySubtags")
);
Globalize:
cldrjs;CLDR допускает загрузку только нужных компонентов.
Пример:
Globalize.load(
require("cldr-data/main/en/numbers")
);
Однако многие API потребуют дополнительные supplemental-файлы.
Минимальный набор:
Globalize.load(
require("cldr-data/main/en/numbers"),
require("cldr-data/supplemental/numberingSystems"),
require("cldr-data/supplemental/likelySubtags")
);
Дополнительно необходимы:
require("cldr-data/main/en/ca-gregorian")
require("cldr-data/supplemental/timeData")
require("cldr-data/supplemental/weekData")
Необходимы:
require("cldr-data/supplemental/plurals")
После установки:
npm install cldr-data
структура выглядит так:
node_modules/
cldr-data/
main/
supplemental/
require("cldr-data/main/ru/numbers");
Полный набор CLDR очень велик.
Он содержит:
Обычно загружаются только нужные локали.
Пример:
Globalize.load(
require("cldr-data/main/en/numbers"),
require("cldr-data/main/ru/numbers")
);
При использовании Webpack или Vite часто создаются отдельные бандлы локалей.
Например:
locales/en.js
locales/ru.js
locales/de.js
Это уменьшает размер основного приложения.
CLDR тесно интегрирован с Unicode.
Используются:
zh-Hant-TW
Расшифровка:
| Часть | Значение |
|---|---|
zh |
китайский язык |
Hant |
традиционная письменность |
TW |
Тайвань |
CLDR умеет интерпретировать такие идентификаторы автоматически.
После загрузки Globalize нормализует структуры CLDR.
Например:
new Globalize("en-US");
может быть преобразовано во внутренний формат:
language: en
script: Latn
territory: US
Globalize активно кэширует:
Это снижает стоимость повторных операций.
Globalize использует cldrjs, но к данным можно
обращаться напрямую.
Пример:
const Cldr = require("cldrjs");
const cldr = new Cldr("ru");
console.log(
cldr.main(
"dates/calendars/gregorian/months/format/wide/1"
)
);
Результат:
январь
main()Используется для доступа к локализованным данным:
cldr.main(path);
supplemental()Используется для общих правил:
cldr.supplemental(path);
Пример:
cldr.supplemental("plurals-type-cardinal");
Некоторые данные дублируются между разделами.
Это сделано для:
CLDR использует очень детализированную иерархию.
Причины:
Каждый аспект локализации вынесен отдельно:
| Файл | Назначение |
|---|---|
numbers.json |
числа |
currencies.json |
валюты |
ca-gregorian.json |
календарь |
units.json |
единицы |
timeZoneNames.json |
временные зоны |
Такой подход позволяет загружать только необходимые части данных.