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

Логирование временных значений в приложениях на основе Day.js строится вокруг идеи неизменяемости объектов и предсказуемого форматирования. Каждый вызов метода возвращает новый экземпляр даты, что упрощает трассировку состояния в логах и исключает скрытые мутации.

Ключевой подход:

  • фиксировать «сырой» входной формат
  • фиксировать результат парсинга
  • фиксировать формат вывода
  • фиксировать метаданные (UTC, локаль, таймзона)

Пример базового логирования:

import dayjs from 'dayjs';

const input = '2026-05-23T10:15:00';

const parsed = dayjs(input);

console.log('INPUT:', input);
console.log('PARSED:', parsed.format());
console.log('ISO:', parsed.toISOString());

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


Проверка валидности дат при отладке

Одной из частых проблем является некорректный парсинг входных значений. В Day.js нет исключений при ошибке — вместо этого возвращается невалидный объект.

Для диагностики используется метод:

dayjs(input).isValid()

Типичный паттерн логирования

const d = dayjs(userInput);

if (!d.isValid()) {
  console.error('INVALID DATE:', userInput);
} else {
  console.log('VALID DATE:', d.format());
}

Расширенное логирование состояния

function logDate(label, value) {
  const d = dayjs(value);

  console.log(`[${label}]`);
  console.log('raw:', value);
  console.log('valid:', d.isValid());
  console.log('formatted:', d.isValid() ? d.format() : 'INVALID');
}

Логирование форматированных значений

Форматирование — основной инструмент наблюдения за состоянием даты. В зависимости от задачи используются разные представления:

  • ISO 8601
  • пользовательский формат
  • UNIX timestamp
const d = dayjs();

console.log('ISO:', d.toISOString());
console.log('Custom:', d.format('DD.MM.YYYY HH:mm'));
console.log('Timestamp:', d.valueOf());

Диагностика расхождений формата

Если отображаемое время отличается от ожидаемого:

console.log('LOCAL:', d.format());
console.log('UTC:', d.utc().format());

Отладка парсинга входных данных

Day.js поддерживает несколько стратегий парсинга: строки ISO, timestamps и пользовательские форматы через плагины. Ошибки часто возникают из-за неявного формата.

Пример проблемного входа

const input = '23/05/2026'; // неоднозначный формат

const d = dayjs(input);
console.log(d.isValid()); // может быть false или неожиданное значение

Решение через строгий парсинг (customParseFormat)

import customParseFormat from 'dayjs/plugin/customParseFormat';
dayjs.extend(customParseFormat);

const d = dayjs('23/05/2026', 'DD/MM/YYYY', true);

console.log('STRICT VALID:', d.isValid());

Логирование при отладке форматов

function debugParse(value, format) {
  const d = dayjs(value, format, true);

  console.log({
    value,
    format,
    valid: d.isValid(),
    parsed: d.isValid() ? d.format() : null
  });
}

Сравнение дат и логирование различий

При отладке бизнес-логики часто требуется понять расхождение между датами.

Методы сравнения

  • isSame
  • isBefore
  • isAfter
  • diff
const a = dayjs('2026-05-01');
const b = dayjs('2026-05-23');

console.log('isBefore:', a.isBefore(b));
console.log('diff days:', b.diff(a, 'day'));

Расширенное логирование разницы

function logDiff(a, b, unit = 'day') {
  const da = dayjs(a);
  const db = dayjs(b);

  console.log('A:', da.format());
  console.log('B:', db.format());
  console.log('DIFF:', db.diff(da, unit), unit);
}

Логирование временных интервалов и duration

Для работы с интервалами используется плагин duration.

import duration from 'dayjs/plugin/duration';
dayjs.extend(duration);

Базовое логирование интервала

const start = dayjs('2026-05-23 10:00');
const end = dayjs('2026-05-23 12:30');

const diff = dayjs.duration(end.diff(start));

console.log('hours:', diff.hours());
console.log('minutes:', diff.minutes());

Форматированное представление

function logDuration(start, end) {
  const d = dayjs.duration(dayjs(end).diff(dayjs(start)));

  console.log(`${d.hours()}h ${d.minutes()}m`);
}

Работа с UTC и влияние на логи

При отладке распределённых систем важно учитывать временные зоны. Day.js использует плагины UTC и timezone.

import utc from 'dayjs/plugin/utc';
dayjs.extend(utc);

Сравнение локального и UTC времени

const d = dayjs();

console.log('LOCAL:', d.format());
console.log('UTC:', d.utc().format());

Логирование ошибок смещения времени

function logUtcMismatch(value) {
  const local = dayjs(value);
  const utc = dayjs.utc(value);

  console.log('local:', local.format());
  console.log('utc:', utc.format());
  console.log('diff minutes:', local.diff(utc, 'minute'));
}

Локализация и влияние на отладочные логи

Локаль влияет на вывод месяцев, дней недели и относительных форматов.

import 'dayjs/locale/ru';

dayjs.locale('ru');

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

const d = dayjs();

console.log(d.format('dddd, D MMMM YYYY'));

Диагностика ошибок локали

function logLocale(value) {
  const d = dayjs(value);

  console.log('locale:', dayjs.locale());
  console.log('formatted:', d.format('LL'));
}

Создание утилиты централизованного логирования

В реальных проектах используется единый слой логирования дат.

function createDateLogger(namespace) {
  return function log(value, label = '') {
    const d = dayjs(value);

    console.log(`[${namespace}] ${label}`);
    console.log('raw:', value);
    console.log('valid:', d.isValid());
    console.log('iso:', d.toISOString());
    console.log('format:', d.format());
  };
}

const logDate = createDateLogger('AUTH');

logDate('2026-05-23T10:00:00', 'token expiry');

Перехват и стандартизация логов

Для крупных приложений важно унифицировать формат логов временных значений.

Единый формат записи

function normalizeDate(value) {
  const d = dayjs(value);

  return {
    raw: value,
    valid: d.isValid(),
    iso: d.isValid() ? d.toISOString() : null,
    timestamp: d.isValid() ? d.valueOf() : null
  };
}

Использование в лог-системах

console.log('EVENT_TIME', normalizeDate(event.createdAt));

Типичные ошибки при отладке дат

1. Неявный парсинг строк

dayjs('05-06-2026'); // неоднозначно: месяц/день

Диагностика:

console.log(dayjs('05-06-2026').format());

2. Потеря UTC контекста

dayjs(value).format(); // локальное время

Решение:

dayjs.utc(value).format();

3. Сравнение невалидных дат

const a = dayjs('invalid');
const b = dayjs('2026-01-01');

console.log(a.diff(b)); // NaN

4. Неправильная локаль

dayjs.locale('en');
console.log(dayjs().format('LL'));

Инструменты разработки и расширенная диагностика

При сложной отладке временных вычислений используются дополнительные приёмы:

Логирование цепочек преобразований

function trace(value) {
  let d = dayjs(value);

  console.log('step 1:', d.format());

  d = d.add(1, 'day');
  console.log('step 2:', d.format());

  d = d.subtract(2, 'hour');
  console.log('step 3:', d.format());
}

Контроль «скрытых» преобразований

function safeFormat(value) {
  const d = dayjs(value);

  return d.isValid()
    ? d.format('YYYY-MM-DD HH:mm:ss')
    : '[INVALID DATE]';
}

Структурированное логирование в JSON

Для систем мониторинга важно сохранять даты в структурированном виде:

function logEventTime(value) {
  const d = dayjs(value);

  console.log(JSON.stringify({
    input: value,
    valid: d.isValid(),
    iso: d.toISOString(),
    unix: d.valueOf()
  }));
}

Отладка сложных цепочек с плагинами

При использовании нескольких плагинов (UTC, timezone, duration, customParseFormat) важно фиксировать состояние после каждого шага:

function debugChain(value) {
  const base = dayjs(value);
  console.log('base:', base.format());

  const utc = base.utc();
  console.log('utc:', utc.format());

  const shifted = utc.add(3, 'hour');
  console.log('shifted:', shifted.format());
}

Контроль воспроизводимости ошибок

Для диагностики нестабильных багов фиксируется полный контекст:

function fullDebug(value) {
  const d = dayjs(value);

  return {
    input: value,
    valid: d.isValid(),
    iso: d.toISOString(),
    format: d.format(),
    timestamp: d.valueOf(),
    locale: dayjs.locale()
  };
}

Поведение невалидных объектов в логах

Невалидные даты не выбрасывают исключений, что требует явной обработки:

const d = dayjs('broken');

console.log(d.format());   // "Invalid Date"
console.log(d.valueOf());  // NaN

Стандартный паттерн:

if (!d.isValid()) {
  console.warn('Date parse error', d);
}