Работа с датами в JavaScript сопровождается множеством скрытых
проблем: некорректный ввод, неоднозначные форматы, влияние часовых
поясов, особенности объекта Date, который может содержать
значение Invalid Date, оставаясь при этом экземпляром
Date. В библиотеке Date-fns задача валидации даты решается
через набор функций, центральной из которых является
isValid.
Объект Date в JavaScript не всегда гарантирует
корректность содержимого. Даже при создании экземпляра через
new Date() результат может оказаться невалидным:
const d = new Date('invalid-date');
console.log(d); // Invalid Date
При этом:
typeof d; // "object"
d instanceof Date; // true
Таким образом, проверка через instanceof Date не
является достаточной. Объект существует, но содержит недопустимое
значение времени (NaN внутри временной шкалы).
Проблема усугубляется тем, что многие операции с датой не выбрасывают исключений, а продолжают вычисления с некорректным значением:
const d = new Date('invalid-date');
console.log(d.getTime()); // NaN
В Date-fns используется функция isValid, предназначенная
для строгой проверки корректности даты.
import { isValid } from 'date-fns';
isValid(new Date(2024, 0, 1)); // true
isValid(new Date('invalid')); // false
Функция проверяет не только тип объекта, но и внутреннее значение времени.
Проверка внутри isValid основана на двух ключевых
шагах:
DategetTime() возвращает не
NaNУпрощённая логика:
function isValid(date) {
return date instanceof Date && !isNaN(date.getTime());
}
new Date('2024-13-40'); // Invalid Date
Даже если строка похожа на дату, выход за пределы календаря делает результат недопустимым.
new Date(undefined); // текущая дата, но это частный случай
new Date(null); // 1970-01-01T00:00:00.000Z
new Date(''); // Invalid Date
Особенно опасна пустая строка, которая приводит к невалидной дате.
При работе с API часто приходят строки неизвестного формата:
const apiDate = "2024/99/99";
const date = new Date(apiDate);
isValid(date); // false
Date-fns предоставляет parseISO, которая используется
для строгого разбора ISO-строк:
import { parseISO, isValid } from 'date-fns';
const date = parseISO('2024-05-20T10:30:00Z');
isValid(date); // true
Если строка не соответствует ISO-формату:
const date = parseISO('not-a-date');
isValid(date); // false
Функция isDate определяет только тип значения:
import { isDate } from 'date-fns';
isDate(new Date()); // true
isDate('2024-01-01'); // false
Однако она не проверяет корректность содержимого:
const d = new Date('invalid-date');
isDate(d); // true
isValid(d); // false
Таким образом:
isDate — проверка типаisValid — проверка корректности значенияВ Date-fns многие функции принимают либо Date, либо
timestamp, либо строку. Однако для валидации важно привести значение к
объекту Date.
import { toDate, isValid } from 'date-fns';
const value = '2024-05-01';
const date = toDate(value);
isValid(date); // true
Функция toDate преобразует входное значение в
Date, но не гарантирует корректность исходных данных.
Timestamp также может быть некорректным:
const date = new Date(NaN);
isValid(date); // false
Корректный timestamp:
const date = new Date(1716163200000);
isValid(date); // true
В реальных приложениях проверка даты часто включается в цепочку обработки данных:
import { parseISO, isValid, format } from 'date-fns';
function safeFormat(dateString) {
const date = parseISO(dateString);
if (!isValid(date)) {
return null;
}
return format(date, 'yyyy-MM-dd');
}
Без проверки isValid форматирование может привести к
некорректным результатам или распространению
Invalid Date.
Invalid Date ведёт себя неожиданно в операциях
сравнения:
const d = new Date('invalid');
d > new Date(); // false
d < new Date(); // false
Любая арифметика с таким значением приводит к NaN:
d.getTime() + 1000; // NaN
Поэтому использование isValid — единственный надёжный
способ отсечь такие значения до вычислений.
При обработке списков дат важно фильтровать невалидные элементы:
import { isValid } from 'date-fns';
const dates = [
new Date('2024-01-01'),
new Date('invalid'),
new Date('2024-05-01')
];
const validDates = dates.filter(isValid);
Результат содержит только корректные даты.
Пользовательские данные почти всегда требуют строгой проверки:
import { parse, isValid } from 'date-fns';
function validateInput(input) {
const date = parse(input, 'dd.MM.yyyy', new Date());
return isValid(date);
}
Здесь parse интерпретирует строку по заданному шаблону,
а isValid гарантирует, что результат действительно
представляет календарную дату.
Отсутствие валидации приводит к каскадным ошибкам:
Пример некорректной сортировки:
dates.sort((a, b) => a - b);
Если один из элементов — Invalid Date, результат
становится непредсказуемым.
Практическая стратегия часто включает несколько шагов:
import { parseISO, isValid } from 'date-fns';
function normalizeDate(value) {
const date = typeof value === 'string'
? parseISO(value)
: new Date(value);
if (!isValid(date)) {
return null;
}
return date;
}
Такой подход позволяет централизовать обработку всех типов входных данных.
Иногда используется проверка:
isNaN(date.getTime())
Однако Date-fns делает это более безопасно и инкапсулированно. Прямое
использование isValid снижает риск ошибок и делает код
предсказуемым при работе с различными типами входных значений.
Проверка корректности даты в Date-fns является фундаментальным этапом
обработки временных данных. Она отделяет формально существующий объект
Date от действительно допустимого календарного значения,
предотвращая распространение ошибок на уровне вычислений, форматирования
и бизнес-логики.