Високосные годы: isLeapYear

Функция isLeapYear в date-fns предназначена для определения високосного года на основе календарной логики Григорианского календаря. Проверка выполняется строго по математическому правилу делимости года и не зависит от локали, временной зоны или настроек окружения, так как анализируется только числовое значение года.

Високосный год определяется по следующему набору правил:

  • год делится на 4 без остатка;
  • если год делится на 100 без остатка, он не является високосным;
  • если год делится на 400 без остатка, он снова считается високосным.

Эта логика формирует детерминированный алгоритм, который одинаково применяется во всех календарных системах, использующих Григорианский стандарт.

Сигнатура функции isLeapYear

В библиотеке date-fns функция имеет следующий формат:

isLeapYear(date: Date | number): boolean

Аргументом может выступать:

  • объект Date
  • числовое представление времени (timestamp в миллисекундах)

Возвращаемое значение — булево:

  • true — год является високосным
  • false — год не является високосным

Принцип работы

Функция извлекает год из переданного значения даты и применяет последовательную проверку делимости:

  1. Определяется год через getFullYear().
  2. Проверяется кратность 4.
  3. Исключаются годы, кратные 100, но не кратные 400.

Логика может быть выражена эквивалентным псевдокодом:

function isLeapYear(date) {
  const year = getYear(date)

  if (year % 400 === 0) return true
  if (year % 100 === 0) return false
  if (year % 4 === 0) return true
  return false
}

Поведение с объектом Date

При передаче экземпляра Date используется локальное календарное представление года. Это означает, что:

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

Пример:

import { isLeapYear } from "date-fns"

isLeapYear(new Date(2020, 0, 1)) // true
isLeapYear(new Date(2021, 6, 15)) // false

Поведение с timestamp

При передаче числа функция интерпретирует его как миллисекунды с Unix-эпохи:

isLeapYear(1609459200000) // 2021-01-01 → false

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

Граничные случаи календаря

Годы, кратные 100

Годы вроде 1900 или 2100 не являются високосными, несмотря на делимость на 4:

isLeapYear(new Date(1900, 0, 1)) // false

Это связано с корректировкой календарного дрейфа.

Годы, кратные 400

Годы 1600, 2000, 2400 считаются високосными:

isLeapYear(new Date(2000, 0, 1)) // true

Это компенсация накопленной ошибки календаря.

Внутренние особенности реализации

В date-fns функция реализована как чистая функция без побочных эффектов. Она:

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

Это делает её предсказуемой в любых условиях выполнения, включая серверные среды и браузеры.

Работа с некорректными значениями

При передаче некорректных данных поведение зависит от возможности преобразования в дату:

  • Invalid Date приводит к некорректному результату (обычно false);
  • строковые значения не поддерживаются напрямую;
  • предпочтение отдаётся явной типизации через Date или number.

Пример:

isLeapYear(new Date("invalid")) // false

Использование в валидации календарных данных

Определение високосного года применяется для:

  • проверки корректности дат 29 февраля;
  • построения календарных интерфейсов;
  • расчёта количества дней в феврале;
  • валидации пользовательского ввода дат.

Пример логики проверки февраля:

function getDaysInFebruary(date) {
  return isLeapYear(date) ? 29 : 28
}

Связь с другими функциями библиотеки

В экосистеме date-fns isLeapYear часто используется совместно с:

  • getDaysInMonth — определение количества дней в месяце;
  • setYear — изменение года у даты;
  • addYears — арифметика годов;
  • startOfYear — нормализация даты к началу года.

Комбинация этих функций позволяет строить календарные вычисления без ручной работы с объектом Date API.

Особенности при работе с историческими датами

Алгоритм ориентирован на Григорианский календарь и применяется ретроспективно. Это означает:

  • функция корректно вычисляет високосные годы для дат до введения календаря;
  • историческая точность зависит от модели календаря, а не реального исторического контекста.

Производительность

Функция имеет постоянную сложность O(1), так как:

  • выполняется фиксированное число арифметических операций;
  • отсутствуют циклы и рекурсия;
  • нет обращений к внешним ресурсам.

Это делает её подходящей для массовых вычислений, например при генерации календарей или обработке больших массивов дат.

Типичные ошибки использования

Часто встречаются следующие ошибки:

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

Корректная логика всегда сводится к анализу года, а не конкретного календарного дня.