Avatar ·

Как сравнить две даты в JavaScript? Поиск разницы и проверка на равенство

Всем привет! Я новичок в JavaScript и никак не могу разобраться со сравнением дат. У меня есть две даты: одна приходит с сервера в виде строки "2025-03-15T10:30:00Z", а вторую я создаю через new Date() для текущего момента. Мне нужно понять, какая дата раньше, и проверить, равны ли они с точностью до дня (без времени). Пробовал просто писать date1 > date2, но это не работает — получаю странные результаты. Когда я вывожу обе даты в консоль, они выглядят как-то так: "Sat Mar 15 2025 13:30:00 GMT+0300" и "2025-03-15T10:30:00.000Z". Видимо, проблема в формате? Вот мой код, который не работает: ```javascript let dateFromServer = "2025-03-15T10:30:00Z"; let currentDate = new Date(); if (dateFromServer > currentDate) { console.log("Дата с сервера больше"); } else { console.log("Дата с сервера меньше или равна"); } ``` Он всегда выводит "Дата с сервера больше", даже если я ставлю дату из прошлого года. Подскажите, как правильно сравнивать даты? Нужно ли их преобразовывать в один формат? И как сравнить только дату, без учёта времени? Заранее спасибо за помощь! <<>>

Основная проблема: строка vs объект Date

Вы столкнулись с классической ошибкой новичков — сравнением строки и объекта. В вашем коде dateFromServer — это обычная строка, а currentDate — объект Date. JavaScript при сравнении строки и объекта через операторы > или < преобразует оба операнда в числа, но делает это по-разному. Строка преобразуется в число NaN (Not a Number), а объект Date — в свою временную метку (timestamp) в миллисекундах. Любое сравнение с NaN возвращает false, поэтому условие dateFromServer > currentDate всегда ложно, и вы получаете неверный результат.

Правильное решение: преобразование в объект Date

Чтобы сравнивать даты корректно, нужно сначала преобразовать строку в объект Date с помощью конструктора new Date(dateString). После этого оба значения будут объектами Date, и их можно сравнивать через операторы >, <, >=, <=. JavaScript автоматически вызовет метод valueOf() для каждого объекта Date, который возвращает числовую временную метку (количество миллисекунд с 1 января 1970 года).

let dateFromServer = new Date("2025-03-15T10:30:00Z");
let currentDate = new Date();

if (dateFromServer > currentDate) {
    console.log("Дата с сервера позже текущей");
} else if (dateFromServer < currentDate) {
    console.log("Дата с сервера раньше текущей");
} else {
    console.log("Даты равны");
}

Сравнение только дат (без времени)

Если нужно сравнить только дату, игнорируя время, используйте методы setHours() или создайте новые даты с обнулённым временем:

function compareDatesOnly(date1, date2) {
    // Обнуляем время для обеих дат
    let d1 = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate());
    let d2 = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate());
    
    if (d1 > d2) {
        return "Первая дата позже";
    } else if (d1 < d2) {
        return "Первая дата раньше";
    } else {
        return "Даты равны";
    }
}

let serverDate = new Date("2025-03-15T10:30:00Z");
let today = new Date();
console.log(compareDatesOnly(serverDate, today));

Проверка на точное равенство

Для проверки равенства двух объектов Date используйте метод getTime() или оператор == после приведения к числу:

let date1 = new Date("2025-03-15T10:30:00Z");
let date2 = new Date("2025-03-15T10:30:00Z");

// Способ 1: через getTime()
if (date1.getTime() === date2.getTime()) {
    console.log("Даты равны с точностью до миллисекунды");
}

// Способ 2: через оператор +
if (+date1 === +date2) {
    console.log("Даты равны");
}

Дополнительные советы

  • Часовые пояса: Всегда работайте в UTC, если данные приходят с сервера в формате ISO (с буквой Z на конце). Используйте методы getUTCFullYear(), getUTCMonth() и т.д.
  • Библиотеки: Для сложных операций с датами (разница в днях, работа с часовыми поясами) используйте библиотеку date-fns или Moment.js (хотя последняя уже устарела).
  • Форматирование: Для вывода дат в читаемом виде используйте toLocaleDateString() или toISOString().

Теперь ваш код будет работать корректно. Главное правило: всегда преобразуйте строки в объекты Date перед сравнением.

<<>>

Альтернативный подход: использование библиотеки date-fns

Если вы часто работаете с датами и хотите избежать ручного преобразования, рекомендую использовать библиотеку date-fns. Она легковесна, хорошо документирована и предоставляет удобные функции для сравнения дат.

// Установка: npm install date-fns
import { compareAsc, format, isEqual, startOfDay } from 'date-fns';

let serverDate = new Date("2025-03-15T10:30:00Z");
let currentDate = new Date();

// Сравнение с учётом времени
if (compareAsc(serverDate, currentDate) > 0) {
    console.log("Дата с сервера позже");
} else if (compareAsc(serverDate, currentDate) < 0) {
    console.log("Дата с сервера раньше");
} else {
    console.log("Даты равны");
}

// Сравнение только дат (без времени)
let serverDateOnly = startOfDay(serverDate);
let currentDateOnly = startOfDay(currentDate);

if (isEqual(serverDateOnly, currentDateOnly)) {
    console.log("Даты совпадают");
}

Преимущества date-fns:

  • Чистые функции без мутации исходных данных
  • Поддержка Tree Shaking (импортируете только то, что нужно)
  • Работа с часовыми поясами через date-fns-tz
  • Простая проверка на равенство через isEqual()

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