Библиотека Globalize строит всю систему форматирования и парсинга данных вокруг понятия текущей локали. Локаль определяет правила отображения чисел, дат, валют, сообщений и единиц измерения. В отличие от простых утилит форматирования, здесь локаль — это управляемое состояние, влияющее на все операции экземпляра или глобального контекста.
В основе работы лежит связка:
en, ru,
fr)CLDR предоставляет структурированные правила локализации, а Globalize выступает как слой доступа к этим правилам.
В Globalize существует два основных способа работы с локалью:
Глобальная локаль задаётся через статический контекст и влияет на все операции, выполняемые без явного указания локали.
Globalize.locale("ru");
Globalize.formatDate(new Date(), { datetime: "medium" });
Globalize.formatNumber(1234567.89);
После установки "ru" все форматирования начинают
использовать русские правила: разделители, порядок дат, названия месяцев
и т.д.
Ключевая особенность: глобальная локаль изменяет поведение всей библиотеки в текущем контексте выполнения.
Альтернативный подход — создание экземпляра Globalize с фиксированной локалью:
const gRu = new Globalize("ru");
const gEn = new Globalize("en");
gRu.formatNumber(12345.67);
gEn.formatNumber(12345.67);
Такой подход устраняет зависимость от глобального состояния и позволяет изолировать форматирование.
Смена локали — это операция, влияющая на все последующие вызовы форматирования.
Globalize.locale("en");
Globalize.formatNumber(1000); // 1,000
Globalize.locale("de");
Globalize.formatNumber(1000); // 1.000
Изменение происходит мгновенно, так как библиотека не хранит “снимки” состояния форматирования — только ссылку на текущую локаль.
Важная особенность: уже созданные экземпляры
new Globalize(locale) не изменяются при смене глобальной
локали.
Внутренний механизм выбора локали подчиняется приоритетам:
Globalize.locale())Пример:
Globalize.locale("ru");
const g = new Globalize("en");
g.formatNumber(1000); // английская локаль (экземпляр)
g.formatNumber(1000, "fr"); // французская локаль (явная)
Явная локаль всегда перекрывает любые другие уровни.
Globalize не содержит локализованных данных по умолчанию. Локаль становится активной только после загрузки соответствующих CLDR-фрагментов.
import likelySubtags from "cldr-data/supplemental/likelySubtags.json";
import numbers from "cldr-data/main/ru/numbers.json";
import timeZoneNames from "cldr-data/main/ru/timeZoneNames.json";
Globalize.load(likelySubtags);
Globalize.load(numbers);
Globalize.load(timeZoneNames);
Globalize.locale("ru");
Если локаль установлена без загрузки данных, форматирование может привести к ошибкам или fallback-поведению.
Globalize поддерживает цепочку fallback-локалей. Например:
pt-BRptenЕсли данных для конкретной локали недостаточно, система автоматически поднимается по цепочке.
Globalize.locale("pt-BR");
При отсутствии части CLDR-данных будут использованы базовые правила
pt.
Важный аспект архитектуры — отсутствие скрытого глобального состояния внутри экземпляров.
const g = new Globalize("ru");
Globalize.locale("en");
g.formatNumber(1000);
Результат остаётся русским, так как экземпляр хранит локаль отдельно.
Это делает возможными сценарии:
При построении интерфейсов локаль часто изменяется во время работы приложения.
Типичный поток:
function setLanguage(lang) {
Globalize.locale(lang);
renderUI();
}
После смены локали требуется повторное форматирование всех отображаемых значений, так как уже отрендеренные строки не пересчитываются автоматически.
Globalize использует локаль не только для чисел и дат, но и для сообщений.
Globalize.loadMessages({
ru: {
greeting: "Привет, {name}!"
},
en: {
greeting: "Hello, {name}!"
}
});
Globalize.locale("ru");
Globalize.messageFormatter("greeting")({ name: "Иван" });
Смена локали автоматически переключает набор сообщений.
Одна и та же локаль влияет на несколько подсистем:
formatNumber)formatDate)formatCurrency)messageFormatter)parseNumber, parseDate)Globalize.locale("de");
Globalize.formatNumber(1234.56);
Globalize.formatDate(new Date());
Globalize.formatCurrency(99.99, "EUR");
Единая локаль гарантирует согласованное поведение всех форматтеров.
Использование глобальной локали может приводить к побочным эффектам:
Пример проблемного сценария:
Globalize.locale("ru");
setTimeout(() => {
Globalize.locale("en");
}, 0);
Globalize.formatNumber(1000);
Результат зависит от тайминга выполнения.
Более стабильная модель — использование экземпляров:
function formatPrice(value, locale) {
const g = new Globalize(locale);
return g.formatCurrency(value, "USD");
}
Каждый вызов получает собственный контекст, исключая влияние внешнего состояния.
Локаль в Globalize не является просто строкой идентификатора. Она активирует набор загруженных данных:
numbers)ca-gregorian)timeZoneNames)currencies)dateFields)Если локаль переключается, но соответствующие данные не загружены, поведение остаётся ограниченным.
Globalize использует кэширование форматтеров внутри локали. Это означает:
Globalize.locale("en");
Globalize.formatNumber(1000);
Globalize.locale("ru");
Globalize.formatNumber(1000);
Каждая локаль имеет собственный набор кэшированных функций.
JavaScript выполняется в однопоточном контексте, однако асинхронность создаёт иллюзию параллельных состояний.
Globalize не защищает глобальную локаль от конкурентного изменения, поэтому архитектурно важно:
Полное устранение зависимости от состояния достигается передачей локали в методы:
Globalize.formatNumber(1000, { locale: "fr" });
или через экземпляр:
new Globalize("fr").formatNumber(1000);
Этот подход делает поведение функций детерминированным и независимым от внешнего контекста.