Одной из наиболее распространённых проблем при работе с датами
становится создание объекта из некорректного значения. Day.js
предоставляет метод isValid(), позволяющий определить,
удалось ли корректно распарсить дату.
const date = dayjs('2025-02-31');
console.log(date.isValid()); // true
Особенность Day.js заключается в том, что библиотека использует
механизм Date из Javascript, который автоматически
нормализует значения. В результате 2025-02-31 превращается
в 2025-03-03.
Для строгой проверки необходимо использовать плагин
customParseFormat.
const customParseFormat = require('dayjs/plugin/customParseFormat');
dayjs.extend(customParseFormat);
const date = dayjs('2025-02-31', 'YYYY-MM-DD', true);
console.log(date.isValid()); // false
Третий аргумент true включает строгий режим
проверки.
При работе с формами важно валидировать строки перед сохранением или отправкой на сервер.
function validateDate(value) {
const date = dayjs(value, 'DD.MM.YYYY', true);
return date.isValid();
}
console.log(validateDate('29.02.2024')); // true
console.log(validateDate('29.02.2025')); // false
Високосные годы регулярно становятся причиной ошибок в вычислениях.
Для корректной работы существует плагин isLeapYear.
const isLeapYear = require('dayjs/plugin/isLeapYear');
dayjs.extend(isLeapYear);
console.log(dayjs('2024-01-01').isLeapYear()); // true
console.log(dayjs('2025-01-01').isLeapYear()); // false
const date = dayjs('2024-02-29');
console.log(date.isValid()); // true
const invalidDate = dayjs('2025-02-29', 'YYYY-MM-DD', true);
console.log(invalidDate.isValid()); // false
Особое внимание требуется при добавлении лет к високосной дате.
const date = dayjs('2024-02-29');
const result = date.add(1, 'year');
console.log(result.format('YYYY-MM-DD'));
Результат:
2025-02-28
Day.js автоматически приводит дату к последнему корректному дню месяца.
Разные месяцы содержат разное количество дней, поэтому операции добавления месяцев могут вести себя неочевидно.
const date = dayjs('2025-01-31');
const result = date.add(1, 'month');
console.log(result.format('YYYY-MM-DD'));
Результат:
2025-02-28
const date = dayjs('2025-01-31');
console.log(date.add(1, 'month').format('YYYY-MM-DD'));
console.log(date.add(2, 'month').format('YYYY-MM-DD'));
Результат:
2025-02-28
2025-03-31
Day.js старается сохранить исходный день месяца, если это возможно.
Часто требуется вычислять последний день месяца независимо от количества дней.
const lastDay = dayjs().endOf('month');
console.log(lastDay.format('YYYY-MM-DD'));
function isLastDayOfMonth(date) {
return date.date() === date.daysInMonth();
}
const date = dayjs('2025-02-28');
console.log(isLastDayOfMonth(date)); // true
При добавлении часов дата может перейти на следующий день.
const date = dayjs('2025-05-10 23:30');
const result = date.add(2, 'hour');
console.log(result.format('YYYY-MM-DD HH:mm'));
Результат:
2025-05-11 01:30
const date = dayjs('2025-05-10 00:15');
const result = date.subtract(30, 'minute');
console.log(result.format('YYYY-MM-DD HH:mm'));
Результат:
2025-05-09 23:45
Часовые пояса — одна из самых сложных тем при работе со временем. Для
поддержки таймзон используются плагины utc и
timezone.
const utc = require('dayjs/plugin/utc');
const timezone = require('dayjs/plugin/timezone');
dayjs.extend(utc);
dayjs.extend(timezone);
const local = dayjs();
const utcDate = dayjs.utc();
console.log(local.format());
console.log(utcDate.format());
const date = dayjs.tz('2025-05-10 12:00', 'Europe/Moscow');
console.log(date.tz('Asia/Tokyo').format());
Нежелательно хранить даты без указания временной зоны.
Проблемный пример:
const date = '2025-05-10T12:00:00';
Без таймзоны сервер и клиент могут интерпретировать время по-разному.
Безопасный вариант:
const date = '2025-05-10T12:00:00Z';
Или:
const date = dayjs().utc().toISOString();
DST (Daylight Saving Time) создаёт множество граничных случаев.
В некоторых странах часы переводятся вперёд, и часть времени исчезает.
const date = dayjs.tz(
'2025-03-30 02:30',
'Europe/Berlin'
);
console.log(date.format());
Такое время может быть автоматически скорректировано библиотекой.
При переводе часов назад одно и то же локальное время возникает дважды.
const date = dayjs.tz(
'2025-10-26 02:30',
'Europe/Berlin'
);
console.log(date.format());
В подобных ситуациях рекомендуется хранить даты в UTC и конвертировать только при отображении.
Ошибки часто возникают из-за сравнения объектов вместо временных меток.
Неправильно:
const a = dayjs();
const b = dayjs();
console.log(a === b); // false
Правильно:
console.log(a.isSame(b));
const a = dayjs('2025-05-10 10:00');
const b = dayjs('2025-05-10 22:00');
console.log(a.isSame(b, 'day')); // true
Для этого используется плагин isBetween.
const isBetween = require('dayjs/plugin/isBetween');
dayjs.extend(isBetween);
const date = dayjs('2025-05-15');
console.log(
date.isBetween(
'2025-05-01',
'2025-05-31'
)
);
В отличие от Date, объекты Day.js являются
неизменяемыми.
const date = dayjs();
const updated = date.add(1, 'day');
console.log(date.format());
console.log(updated.format());
Исходный объект не изменяется.
let date = dayjs();
date.add(1, 'day');
console.log(date.format());
Результат останется прежним, потому что необходимо сохранить новое значение.
Правильный вариант:
date = date.add(1, 'day');
Одна из самых частых ошибок — путаница между секундами и миллисекундами.
Unix Timestamp в Javascript использует миллисекунды:
console.log(Date.now());
Многие API возвращают секунды:
const timestamp = 1746870000;
Для корректного преобразования:
const date = dayjs.unix(timestamp);
console.log(date.format());
const timestamp = 1746870000;
console.log(dayjs(timestamp).format());
Результат окажется неверным, потому что Day.js воспримет число как миллисекунды.
null и
undefinedconsole.log(dayjs(null).format());
console.log(dayjs(undefined).format());
undefined создаёт текущую дату, а null —
невалидную.
function parseDate(value) {
if (!value) {
return null;
}
const date = dayjs(value);
return date.isValid() ? date : null;
}
Строки вида:
01/02/2025
могут означать:
const date = dayjs(
'01/02/2025',
'DD/MM/YYYY',
true
);
console.log(date.format('YYYY-MM-DD'));
const date = dayjs('9999-12-31');
console.log(
date.add(1, 'day').format()
);
При работе с экстремально большими значениями следует проверять валидность результата.
const result = date.add(1, 'day');
console.log(result.isValid());
const start1 = dayjs('2025-05-01');
const end1 = dayjs('2025-05-10');
const start2 = dayjs('2025-05-05');
const end2 = dayjs('2025-05-15');
const hasIntersection =
start1.isBefore(end2) &&
end1.isAfter(start2);
console.log(hasIntersection);
startOf() и ручным обнулениемНеправильно:
const date = dayjs()
.hour(0)
.minute(0)
.second(0);
Правильно:
const date = dayjs().startOf('day');
startOf() учитывает все единицы времени, включая
миллисекунды.
const date = dayjs('2025-05-10T12:00:00.123');
console.log(date.millisecond());
const a = dayjs('2025-05-10T12:00:00.123');
const b = dayjs('2025-05-10T12:00:00.124');
console.log(a.isSame(b));
Результат:
false
console.log(a.isSame(b, 'second'));
Результат:
true
const date = dayjs();
console.log(JSON.stringify({ date }));
Day.js автоматически сериализует объект в ISO-формат.
Наиболее безопасный вариант:
const payload = {
createdAt: dayjs().toISOString()
};
const start = dayjs('2025-05-10');
const end = dayjs('2025-05-01');
console.log(end.diff(start, 'day'));
Результат:
-9
const diff = Math.abs(
end.diff(start, 'day')
);
console.log(diff);
diff()const start = dayjs('2025-01-31');
const end = dayjs('2025-02-28');
console.log(end.diff(start, 'month'));
Результат:
1
Однако:
console.log(end.diff(start, 'day'));
Результат:
28
Разные единицы измерения используют разные алгоритмы вычисления.
При взаимодействии клиента и сервера рекомендуется соблюдать единый подход:
Пример безопасной схемы:
const createdAt = dayjs.utc().toISOString();
Отображение:
const localDate = dayjs.utc(createdAt).local();