Сравнение двух дат в JavaScript
Проблема с сравнением дат в JavaScript
Здравствуйте!
Я пытаюсь решить задачу по сравнению значений двух дат в JavaScript, которые будут вводиться в текстовые поля. Мне нужно определить, какая из этих дат больше, меньше, а также проверить, не находится ли она в прошлом.
Не могли бы вы подсказать, как правильно реализовать такое сравнение? Какие методы или подходы лучше всего использовать для этой задачи? Заранее спасибо за помощь!
4 ответ(ов)
Самый простой способ сравнения дат в JavaScript - это сначала преобразовать их в объекты Date, а затем сравнить эти объекты.
Ниже представлен объект с тремя функциями:
dates.compare(a, b)
Возвращает число:
- -1, если a < b
- 0, если a = b
- 1, если a > b
- NaN, если a или b является некорректной датой
dates.inRange(d, start, end)
Возвращает булевый тип или NaN:
- true, если d находится между start и end (включительно)
- false, если d раньше start или позже end
- NaN, если одна или несколько дат являются некорректными
dates.convert
Используется другими функциями для преобразования входных данных в объект даты. Входные данные могут быть:
- объектом date: возвращается без изменений
- массивом: интерпретируется как [год, месяц, день]. ПРИМЕЧАНИЕ: месяц - от 0 до 11
- числом: интерпретируется как количество миллисекунд с 1 января 1970 года (метка времени)
- строкой: поддерживаются несколько разных форматов, таких как "YYYY/MM/DD", "MM/DD/YYYY", "Jan 31 2009" и т.д.
- объектом: интерпретируется как объект с атрибутами год, месяц и дата. ПРИМЕЧАНИЕ: месяц - от 0 до 11.
Пример кода:
// Источник: http://stackoverflow.com/questions/497790
var dates = {
convert: function(d) {
// Преобразует дату в d в объект даты. Входные данные могут быть:
// объектом даты: возвращается без модификации
// массивом : интерпретируется как [год, месяц, день]. ПРИМЕЧАНИЕ: месяц от 0 до 11.
// числом : интерпретируется как количество миллисекунд
// с 1 января 1970 года (метка времени)
// строкой : любой формат, поддерживаемый движком JavaScript, например
// "YYYY/MM/DD", "MM/DD/YYYY", "Jan 31 2009" и т.д.
// объектом : интерпретируется как объект с атрибутами год, месяц и дата
// ПРИМЕЧАНИЕ: месяц от 0 до 11.
return (
d.constructor === Date ? d :
d.constructor === Array ? new Date(d[0], d[1], d[2]) :
d.constructor === Number ? new Date(d) :
d.constructor === String ? new Date(d) :
typeof d === "object" ? new Date(d.year, d.month, d.date) :
NaN
);
},
compare: function(a, b) {
// Сравнивает две даты (могут быть любого типа, поддерживаемого функцией convert)
// и возвращает:
// -1 : если a < b
// 0 : если a = b
// 1 : если a > b
// NaN : если a или b является некорректной датой
// ПРИМЕЧАНИЕ: Код внутри isFinite выполняет присваивание (=).
return (
isFinite(a = this.convert(a).valueOf()) &&
isFinite(b = this.convert(b).valueOf()) ?
(a > b) - (a < b) :
NaN
);
},
inRange: function(d, start, end) {
// Проверяет, попадает ли дата в d между датами start и end.
// Возвращает булевый тип или NaN:
// true : если d между start и end (включительно)
// false : если d раньше start или позже end
// NaN : если одна или несколько дат некорректны.
// ПРИМЕЧАНИЕ: Код внутри isFinite выполняет присваивание (=).
return (
isFinite(d = this.convert(d).valueOf()) &&
isFinite(start = this.convert(start).valueOf()) &&
isFinite(end = this.convert(end).valueOf()) ?
start <= d && d <= end :
NaN
);
}
}
Используйте этот код для работы с датами в JavaScript, что упростит ваши задачи по сравнению дат и проверке диапазонов.
Самый простой способ — вычесть одну дату из другой и сравнить результат.
var oDateOne = new Date();
var oDateTwo = new Date();
console.log(oDateOne - oDateTwo === 0); // Проверяет, равны ли даты
console.log(oDateOne - oDateTwo < 0); // Проверяет, является ли oDateOne раньше oDateTwo
console.log(oDateOne - oDateTwo > 0); // Проверяет, является ли oDateOne позже oDateTwo
Таким образом, результат вычитания двух объектов Date
возвращает разницу в миллисекундах, что позволяет легко выполнить нужные сравнения.
Сравнение только даты (игнорируя временную составляющую):
Date.prototype.sameDay = function(d) {
return this.getFullYear() === d.getFullYear()
&& this.getDate() === d.getDate()
&& this.getMonth() === d.getMonth();
}
Использование:
if(date1.sameDay(date2)) {
// выделить день в календаре или что-то еще умное
}
Я больше не рекомендую изменять prototype
встроенных объектов. Вместо этого попробуйте следующее:
function isSameDay(d1, d2) {
return d1.getFullYear() === d2.getFullYear() &&
d1.getDate() === d2.getDate() &&
d1.getMonth() === d2.getMonth();
}
console.log(isSameDay(new Date('Jan 15 2021 02:39:53 GMT-0800'), new Date('Jan 15 2021 23:39:53 GMT-0800')));
console.log(isSameDay(new Date('Jan 15 2021 10:39:53 GMT-0800'), new Date('Jan 16 2021 10:39:53 GMT-0800')));
Обратите внимание, что год/месяц/день будут возвращены для вашего часового пояса; я рекомендую использовать библиотеку, учитывающую часовые пояса, если вы хотите проверить, принадлежат ли две даты одному и тому же дню в другом часовом поясе.
Например:
> (new Date('Jan 15 2021 01:39:53 Z')).getDate() // 15 января по UTC
14 // Возвращает "14", потому что я в GMT-08
Примечание - Сравнение только части даты:
Когда мы сравниваем две даты в JavaScript, учитываются также часы, минуты и секунды. Поэтому, если нам нужно сравнить только даты, мы можем использовать следующий подход:
var date1 = new Date("01/01/2014").setHours(0, 0, 0, 0);
var date2 = new Date("01/01/2014").setHours(0, 0, 0, 0);
Теперь: выражение if (date1.valueOf() > date2.valueOf())
будет работать без проблем.
Где найти документацию по форматированию даты в JavaScript?
Форматирование даты в JavaScript в виде yyyy-mm-dd
Как отсортировать массив объектов по свойству даты?
Как вычесть дни из обычной даты?
Как преобразовать дату в UTC?