В григорианском календаре високосный год вводится для компенсации расхождения между астрономическим и календарным годом. Базовое правило формализуется через делимость:
y = 4k ;; (y 100m ;; y = 400n)
Иными словами, год считается високосным, если он кратен 4, но исключаются годы, кратные 100, за исключением тех, что кратны 400. Это правило является фундаментом работы большинства календарных систем, включая те, которые используются в библиотеке Globalize.
Библиотека Globalize опирается на данные CLDR (Unicode Common Locale Data Repository), где календарные правила уже формализованы и структурированы. Для григорианского календаря, который используется по умолчанию в большинстве локалей, информация о високосных годах не вычисляется вручную в библиотеке, а следует стандарту CLDR.
Это означает:
Globalize использует встроенные механизмы форматирования дат, основанные на ICU/CLDR шаблонах. При работе с датами, содержащими 29 февраля, библиотека не требует дополнительных проверок — корректность определяется самим календарём.
import Globalize from "globalize";
// предположим, что CLDR данные уже загружены
const globalize = new Globalize("ru");
const leapDate = new Date(2024, 1, 29); // 29 февраля 2024
console.log(
globalize.formatDate(leapDate, {
datetime: "medium"
})
);
Поведение при форматировании определяется локалью, но логика високосного года остаётся неизменной для всех языков.
Важно разделять два уровня работы с календарём:
Globalize работает исключительно на уровне представления. Это означает:
При работе с пользовательским вводом возможны ситуации, когда дата 29
февраля вводится для года, не являющегося високосным. В таких случаях
поведение зависит от реализации JavaScript Date, а
Globalize лишь интерпретирует уже нормализованное значение.
Пример обработки:
const date = new Date(2023, 1, 29);
console.log(date.toString());
JavaScript автоматически преобразует такую дату в 1 марта 2023 года, и Globalize будет форматировать уже скорректированное значение.
В CLDR данные о месяцах не зависят от високосности года. Однако разница проявляется в длине февраля:
Globalize не хранит эти значения явно, но получает их через календарную модель CLDR, что гарантирует единообразие между локалями.
При использовании относительного времени важно учитывать корректность базовой даты. Например, вычисление разницы между 28 февраля и 1 марта в високосный год отличается от невисокосного сценария.
import Globalize from "globalize";
const globalize = new Globalize("ru");
const from = new Date(2024, 1, 28);
const to = new Date(2024, 2, 1);
console.log(
globalize.formatRelativeTime(
(to - from) / (1000 * 60 * 60 * 24),
"day"
)
);
Здесь результат зависит от количества фактических дней между датами, а не от логики календарных переходов.
Вся календарная логика, связанная с високосными годами, определяется в CLDR через:
Globalize не реализует алгоритмы определения високосного года самостоятельно, что исключает расхождения между локалями и платформами.
При разборе строковых представлений дат Globalize опирается на формат локали. Например:
const parsed = globalize.parseDate("29.02.2024", {
skeleton: "yMd"
});
console.log(parsed);
Корректный разбор возможен только при наличии согласованного календарного контекста. Если дата некорректна (например, 29.02.2023), результат будет зависеть от внутренней нормализации JavaScript Date.
Високосный год не связан с часовыми поясами напрямую, однако переходы времени могут влиять на отображение даты:
Date, уже
учитывающий временную зону;Особое внимание требуется при операциях инкремента дат:
Date.Globalize не изменяет это поведение, но корректно отображает итоговое значение:
const d = new Date(2024, 1, 28);
d.setDate(d.getDate() + 1);
console.log(globalize.formatDate(d, { datetime: "short" }));
Форматы ICU, используемые Globalize, не содержат отдельной логики для високосных годов. Вместо этого:
Такой подход исключает необходимость ручного контроля високосных правил при локализации дат.