Code review checklist

Проверка корректности начинается с анализа того, как используются функции библиотеки и соответствуют ли они ожидаемой семантике работы с датами в JavaScript. Библиотека Date-fns предоставляет чистые функции без мутаций, и любое отклонение от этого принципа в коде требует отдельного внимания.

Ключевые аспекты:

  • отсутствие мутаций исходных объектов Date
  • правильный выбор функции под конкретную задачу (например, различие между addDays, addMonths, addYears)
  • корректная работа с возвращаемыми значениями (всегда новый объект Date)

Пример корректного подхода:

import { addDays } from 'date-fns';

const baseDate = new Date(2026, 0, 1);
const result = addDays(baseDate, 10);

// baseDate остаётся неизменной

Любые попытки модифицировать дату через побочные эффекты должны рассматриваться как ошибка архитектуры.


Иммутабельность и защита от побочных эффектов

Date-fns построена вокруг иммутабельного подхода, но нарушение этого принципа часто возникает на уровне приложения.

Контрольные точки:

  • отсутствие прямого изменения объекта Date
  • отсутствие повторного использования изменённых ссылок
  • отсутствие скрытых мутаций через внешние утилиты

Типичный проблемный сценарий:

const date = new Date(2026, 0, 1);
const updated = date.setDate(date.getDate() + 5);

Здесь нарушается иммутабельность, поскольку setDate изменяет исходный объект и возвращает timestamp, а не новый Date.

Корректный вариант:

import { addDays } from 'date-fns';

const date = new Date(2026, 0, 1);
const updated = addDays(date, 5);

Работа с форматированием дат

Форматирование через date-fns/format требует строгого контроля строк формата и соответствия бизнес-логике.

Проверяемые моменты:

  • отсутствие «магических» строк без констант
  • единый стандарт форматов в проекте
  • корректная локализация
import { format } from 'date-fns';

const date = new Date(2026, 0, 1);

const formatted = format(date, 'yyyy-MM-dd');

Частая ошибка — несогласованность форматов в разных частях системы, например смешивание dd.MM.yyyy и yyyy-MM-dd, что приводит к ошибкам в интеграциях.


Парсинг дат и неоднозначность входных данных

Парсинг является одной из наиболее уязвимых зон при работе с датами.

Контроль включает:

  • отказ от небезопасного парсинга строк через new Date(string)
  • использование parse, parseISO
  • явное указание формата входных данных
import { parse } from 'date-fns';

const date = parse('2026-01-01', 'yyyy-MM-dd', new Date());

Особое внимание уделяется:

  • локальным форматам (DD/MM/YYYY vs MM/DD/YYYY)
  • некорректным входным данным
  • отсутствию таймзоны в строках ISO

Таймзоны и работа с UTC

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

Проверка включает:

  • явное понимание локального времени vs UTC
  • использование date-fns-tz при необходимости
  • отсутствие неявных преобразований времени

Пример работы с UTC:

import { format } from 'date-fns';
import { utcToZonedTime } from 'date-fns-tz';

const date = new Date('2026-01-01T12:00:00Z');
const zoned = utcToZonedTime(date, 'Europe/Berlin');

const formatted = format(zoned, 'yyyy-MM-dd HH:mm:ss');

Проверка граничных значений

Работа с датами требует обязательного тестирования крайних случаев.

Сценарии проверки:

  • переходы через месяцы с разным количеством дней
  • високосные годы
  • переходы через DST (летнее/зимнее время)
  • начало и конец года
import { addMonths } from 'date-fns';

const date = new Date(2026, 0, 31);
const result = addMonths(date, 1); // потенциальный сдвиг на февраль

Непредсказуемые сдвиги дат при добавлении месяцев требуют отдельного внимания в бизнес-логике.


Производительность и избыточные операции

Date-fns оптимизирована как набор небольших функций, но неправильное использование приводит к избыточным вычислениям.

Проверяется:

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

Антипаттерн:

format(addDays(addMonths(addYears(date, 1), 2), 3), 'yyyy-MM-dd');

Корректнее:

const step1 = addYears(date, 1);
const step2 = addMonths(step1, 2);
const step3 = addDays(step2, 3);

Tree-shaking и контроль импорта

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

Проверяемые моменты:

  • отсутствие импорта из корня пакета
  • использование точечных импортов

Неправильно:

import { format } from 'date-fns';

В современных сборках предпочтительнее:

import format from 'date-fns/format';

Это снижает вероятность попадания лишнего кода в финальный бандл.


Локализация и работа с языками

Date-fns поддерживает локали через отдельные модули.

Контроль включает:

  • единый источник локали
  • отсутствие смешивания локалей в одном формате вывода
  • корректное подключение языковых пакетов
import { format } from 'date-fns';
import { ru } from 'date-fns/locale';

const date = new Date(2026, 0, 1);

const result = format(date, 'PPPP', { locale: ru });

Ошибки часто возникают при частичном применении локалей, когда часть интерфейса использует одну локаль, а часть — другую.


Тестирование логики дат

Код, использующий Date-fns, требует детерминированных тестов.

Проверяется:

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

Пример тестового подхода:

import { addDays } from 'date-fns';

test('adds days correctly', () => {
  const base = new Date(2026, 0, 1);
  const result = addDays(base, 10);

  expect(result).toEqual(new Date(2026, 0, 11));
});

Согласованность API и доменной логики

Date-fns часто используется в слоях бизнес-логики, где требуется строгая согласованность терминов.

Проверяется:

  • единообразие терминов «дата», «время», «период»
  • отсутствие смешивания бизнес-единиц (например, минуты и дни без явного преобразования)
  • явное именование функций-обёрток

Пример проблемной абстракции:

const expire = addDays(createdAt, config.timeout);

Если timeout хранится в минутах, такая конструкция становится источником скрытых ошибок.


Обработка null, undefined и некорректных дат

Date-fns не скрывает ошибки входных данных, поэтому требуется явная защита.

Контроль:

  • проверка через isValid
  • отсутствие передачи undefined в функции
  • обработка некорректных значений на входе
import { isValid } from 'date-fns';

const date = new Date(input);

if (!isValid(date)) {
  // обработка ошибки
}

Единообразие использования в кодовой базе

В крупных проектах критично поддерживать единый стиль использования Date-fns.

Анализируется:

  • единый набор импортируемых функций
  • отсутствие дублирующих утилит поверх Date-fns
  • централизованные хелперы для частых операций

Пример допустимой абстракции:

import { format, addDays } from 'date-fns';

export const formatDate = (date) => format(date, 'yyyy-MM-dd');
export const shiftDate = (date, days) => addDays(date, days);

Избыточные обёртки без добавленной ценности ухудшают читаемость и усложняют поддержку.