Сравнение даты с датой без сравнения времени в JavaScript

Что не так с кодом ниже?

Возможно, было бы проще просто сравнить дату, а не время. Я также не знаю, как это сделать, и я искал, но я не мог найти свою точную проблему.

Кстати, когда я показываю две даты в предупреждении, они отображаются точно так же.

Мой код:

window.addEvent('domready', function() {
    var now = new Date();
    var input = $('datum').getValue();
    var dateArray = input.split('/');
    var userMonth = parseInt(dateArray[1])-1;
    var userDate = new Date();
    userDate.setFullYear(dateArray[2], userMonth, dateArray[0], now.getHours(), now.getMinutes(), now.getSeconds(), now.getMilliseconds());

    if (userDate > now)
    {
        alert(now + '\n' + userDate);
    }
});

Есть ли более простой способ сравнить даты и не включать время?

Ответ 1

Я все еще изучаю JavaScript, и единственный найденный мной способ сравнить две даты без времени - это использовать метод setHours объекта Date и установить ноль часов, минут, секунд и миллисекунд. Затем сравните две даты.

Например,

date1 = new Date()
date2 = new Date(2011,8,20)

date2 будет установлен с часами, минутами, секундами и миллисекундами на ноль, но для date1 будет установлено время создания даты1. Чтобы избавиться от часов, минут, секунд и миллисекунд на дату1, сделайте следующее:

date1.setHours(0,0,0,0)

Теперь вы можете сравнивать две даты только как ДАТЫ, не беспокоясь об элементах времени.

Ответ 2

ОСТЕРЕГАЙТЕСЬ ВРЕМЕНИ

Использование объекта date для непосредственного представления даты просто поставит вас перед проблемой чрезмерной точности. Вам нужно управлять временем и часовым поясом, чтобы не пускать их, и они могут вернуться обратно на любом этапе. Принятый ответ на этот вопрос попадает в ловушку.

Дата в JavaScript не имеет понятия о часовом поясе. Это момент времени (тики с начала эпохи) с удобными (статическими) функциями для перевода в и из строк, используя по умолчанию "локальный" часовой пояс устройства или, если указан, UTC или другой часовой пояс. Представлять просто дату и торговлю; с объектом даты вы хотите, чтобы ваши даты представляли полночь UTC в начале рассматриваемой даты. Это общее и необходимое соглашение, позволяющее вам работать с датами независимо от сезона или часового пояса их создания., Поэтому вам нужно быть очень бдительными, чтобы управлять понятием часового пояса, как при создании объекта "Дата в формате UTC", так и при его сериализации.

Многие люди смущены поведением консоли по умолчанию. Если вы распылите дату на консоль, вы увидите, что вы увидите ваш часовой пояс. Это просто потому, что консоль вызывает toString() в вашу дату, а toString() дает вам местное представительство. Базовая дата не имеет часового пояса! (Пока время соответствует смещению часового пояса, у вас все еще будет объект даты в формате UTC)

Десериализация (или создание полуночных UTC Date объектов)

В большинстве случаев вы хотите, чтобы ваша дата отражала часовой пояс пользователя. Нажмите, если сегодня ваш день рождения. Пользователи в Новой Зеландии и США нажимают одновременно и получают разные даты. В этом случае сделайте это...

// create a date (utc midnight) reflecting the value of myDate and the environment timezone offset.
new Date(Date.UTC(myDate.getFullYear(),myDate.getMonth(), myDate.getDate()));

Иногда международная сопоставимость превосходит локальную точность. В этом случае сделайте это...

// the date in London of a moment in time. Device timezone is ignored.
new Date(Date.UTC(myDate.getUTCFullYear(), myDate.getUTCMonth(), myDate.getUTCDate()));

десериализация даты

Часто даты на проводе будут в формате ГГГГ-ММ-ДД. Чтобы десериализовать их, сделайте это...

var midnightUTCDate = new Date( dateString + 'T00:00:00Z');

Сериализация

Позаботившись об управлении часовым поясом при создании, теперь вы должны быть уверены, что часовой пояс не будет отображаться при преобразовании обратно в строковое представление. Так что вы можете безопасно использовать...

  • toISOString()
  • getUTCxxx()
  • getTime() //returns a number with no time or timezone.
  • .toLocaleDateString("fr",{timezone:"UTC"}) // whatever locale you want, but ALWAYS UTC.

И полностью избегать всего остального, особенно...

  • getYear(), getMonth(), getDate()

Итак, чтобы ответить на ваш вопрос, на 7 лет поздно...

<input type="date" onchange="isInPast(event)">
<script>
var isInPast = function(event){
  var userEntered = new Date(event.target.valueAsNumber); // valueAsNumber has no time or timezone!
  var now = new Date();
  var today = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate() ));
  if(userEntered.getTime() < today.getTime())
    alert("date is past");
  else if(userEntered.getTime() == today.getTime())
    alert("date is today");
  else
    alert("date is future");

}
</script>

Видишь, это работает...

Ответ 3

Как насчет этого?

Date.prototype.withoutTime = function () {
    var d = new Date(this);
    d.setHours(0, 0, 0, 0);
    return d;
}

Это позволяет сравнить дату даты такой, как это, не влияя на значение вашей переменной:

var date1 = new Date(2014,1,1);
new Date().withoutTime() > date1.withoutTime(); // true

Ответ 4

Использование Moment.js

Если у вас есть возможность включить стороннюю библиотеку, определенно стоит взглянуть на Moment.js. Это делает работу с Date и DateTime намного, намного проще.

Например, видя, что одна Дата идет после другой, но исключая их время, вы должны сделать что-то вроде этого:

var date1 = new Date(2016,9,20,12,0,0); // October 20, 2016 12:00:00
var date2 = new Date(2016,9,20,12,1,0); // October 20, 2016 12:01:00

// Comparison including time.
moment(date2).isAfter(date1); // => true

// Comparison excluding time.
moment(date2).isAfter(date1, 'day'); // => false

Второй параметр, который вы передаете в isAfter - это точность выполнения сравнения, которая может быть любым из year, month, week, day, hour, minute или second.

Ответ 5

Просто сравните с помощью .toDateString, как показано ниже:

new Date().toDateString();

Это вернет вам только дату, а не время или часовой пояс, например:

"Пт Фев 03 2017"

Следовательно, обе даты могут сравниваться в этом формате также без временной части.

Ответ 6

Это может быть немного более чистая версия, также обратите внимание, что вы всегда должны использовать radix при использовании parseInt.

window.addEvent('domready', function() {
    // Create a Date object set to midnight on today date
    var today = new Date((new Date()).setHours(0, 0, 0, 0)),
    input = $('datum').getValue(),
    dateArray = input.split('/'),
    // Always specify a radix with parseInt(), setting the radix to 10 ensures that
    // the number is interpreted as a decimal.  It is particularly important with
    // dates, if the user had entered '09' for the month and you don't use a
    // radix '09' is interpreted as an octal number and parseInt would return 0, not 9!
    userMonth = parseInt(dateArray[1], 10) - 1,
    // Create a Date object set to midnight on the day the user specified
    userDate = new Date(dateArray[2], userMonth, dateArray[0], 0, 0, 0, 0);

    // Convert date objects to milliseconds and compare
    if(userDate.getTime() > today.getTime())
    {
            alert(today+'\n'+userDate);
    }
});

За дополнительной информацией о радиксе обратитесь к странице MDC parseInt.

JSLint - отличный инструмент для поиска вещей, таких как отсутствующий радикс и многие другие вещи, которые могут вызвать неясность и сложность отладки ошибок, Это заставляет вас использовать лучшие стандарты кодирования, чтобы избежать будущих головных болей. Я использую его для каждого проекта JavaScript, который я кодирую.

Ответ 7

Библиотека date.js удобна для этих целей. Это делает все сценарии, связанные с датой JS, намного проще.

Ответ 8

Так я это делаю:

var myDate  = new Date($('input[name=frequency_start]').val()).setHours(0,0,0,0);
var today   = new Date().setHours(0,0,0,0);
if(today>myDate){
    jAlert('Please Enter a date in the future','Date Start Error', function(){
        $('input[name=frequency_start]').focus().select();
    });
}

Ответ 9

Как я не вижу здесь подобного подхода, и мне не нравится устанавливать h/m/s/ms на 0, так как это может вызвать проблемы с точным переходом в локальный часовой пояс с измененным объектом date (I предположим так), позвольте мне представить здесь это, написанное несколько мгновений назад, lil function:

+: Простая в использовании, делает основные операции сравнения (сравнение дня, месяца и года без времени).
-: Кажется, что это полная противоположность мышлению "из коробки".

function datecompare(date1, sign, date2) {
    var day1 = date1.getDate();
    var mon1 = date1.getMonth();
    var year1 = date1.getFullYear();
    var day2 = date2.getDate();
    var mon2 = date2.getMonth();
    var year2 = date2.getFullYear();
    if (sign === '===') {
        if (day1 === day2 && mon1 === mon2 && year1 === year2) return true;
        else return false;
    }
    else if (sign === '>') {
        if (year1 > year2) return true;
        else if (year1 === year2 && mon1 > mon2) return true;
        else if (year1 === year2 && mon1 === mon2 && day1 > day2) return true;
        else return false;
    }    
}

Использование:

datecompare(date1, '===', date2) для проверки равенства,
datecompare(date1, '>', date2) для большей проверки,
!datecompare(date1, '>', date2) для менее или равной проверки

Кроме того, вы можете переключать date1 и date2 в местах, чтобы достичь любого другого простого сравнения.

Ответ 10

После прочтения этого вопроса в то же время после его публикации я решил опубликовать другое решение, так как не нашел его вполне удовлетворительным, по крайней мере, для моих нужд:

Я использовал что-то вроде этого:

var currentDate= new Date().setHours(0,0,0,0);

var startDay = new Date(currentDate - 86400000 * 2);
var finalDay = new Date(currentDate + 86400000 * 2);

Таким образом, я мог бы использовать даты в формате, который я хотел бы обработать впоследствии. Но это было только для моей потребности, но я решил опубликовать его в любом случае, возможно, это поможет кому-то

Ответ 11

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

Math.floor(date1.getTime() / 86400000) > Math.floor(date2.getTime() / 86400000);

Он игнорирует временную часть, он работает для разных часовых поясов, и вы также можете сравнить на равенство ==. 86400000 - это количество миллисекунд в дне (= 24*60*60*1000).

Помните, что оператор сравнения == никогда не должен использоваться для сравнения объектов Date, потому что он не работает, когда вы ожидаете, что тест на равенство сработает, потому что он сравнивает два объекта Date (и не сравнивает эти две даты), например:

> date1;
outputs: Thu Mar 08 2018 00:00:00 GMT+1300

> date2;
outputs: Thu Mar 08 2018 00:00:00 GMT+1300

> date1 == date2;
outputs: false

> Math.floor(date1.getTime() / 86400000) == Math.floor(date2.getTime() / 86400000);
outputs: true

Примечания: Если вы сравниваете объекты Date, для которых часть времени установлена в ноль, вы можете использовать date1.getTime() == date2.getTime() но вряд ли стоит оптимизировать. Вы можете использовать <, >, <= или >= при непосредственном сравнении объектов Date, поскольку эти операторы сначала преобразуют объект Date, вызывая .valueOf() прежде чем оператор .valueOf() сравнение.

Ответ 12

Если вы действительно сравниваете дату только с отсутствующим временным компонентом, другое решение, которое может показаться неправильным, но работает и избегает всех проблем с временем и часовым поясом Date() состоит в том, чтобы сравнивать строковую дату ISO напрямую, используя сравнение строк:

> "2019-04-22" <= "2019-04-23"
true
> "2019-04-22" <= "2019-04-22"
true
> "2019-04-22" <= "2019-04-21"
false
> "2019-04-22" === "2019-04-22"
true

Вы можете получить текущую дату (дату UTC, необязательно локальную дату пользователя), используя:

> new Date().toISOString().split("T")[0]
"2019-04-22"

Мой аргумент в пользу этого - простота программиста - вы гораздо меньше рискуете испортить это, чем пытаться правильно обрабатывать время и смещение, вероятно, за счет скорости (я не сравнивал производительность)

Ответ 13

Убедитесь, что вы построили userDate с 4-значным годом как setFullYear(10, ...) !== setFullYear(2010, ...).

Ответ 14

Вы можете использовать некоторую арифметику с общим количеством ms.

var date = new Date(date1);
date.setHours(0, 0, 0, 0);

var diff = date2.getTime() - date.getTime();
return diff >= 0 && diff < 86400000;

Мне это нравится, потому что обновление исходных дат не выполняется и выполняется быстрее, чем разделение строк и сравнение.

Надеюсь на эту помощь!

Ответ 15

Я знаю, что на этот вопрос уже был дан ответ, и это, возможно, не лучший способ, но в моем сценарии он работает отлично, поэтому я подумал, что он может помочь кому-то, как я.

если у вас есть date string как

String dateString="2018-01-01T18:19:12.543";

и вы просто хотите сравнить часть даты с другим объектом Date в JS,

var anotherDate=new Date(); //some date

затем необходимо convert string в объект Date с помощью new Date("2018-01-01T18:19:12.543");

и вот фокус:

var valueDate =new Date(new Date(dateString).toDateString());

            return valueDate.valueOf() == anotherDate.valueOf(); //here is the final result

Я использовал toDateString() Date object JS, который возвращает только строку Date.

Примечание. Не забудьте использовать .valueOf() при сравнении дат.

больше информации о .valeOf() здесь ссылка

Удачной кодировки.

Ответ 16

Это поможет. Мне удалось получить это так.

var currentDate = new Date(new Date().getFullYear(), new Date().getMonth() , new Date().getDate())

Ответ 17

Сравнение с setHours() будет решением. Образец:

var d1 = new Date();
var d2 = new Date("2019-2-23");
if(d1.setHours(0,0,0,0) == d2.setHours(0,0,0,0)){
    console.log(true)
}else{
    console.log(false)
}

Ответ 18

var fromdate = new Date(MM/DD/YYYY);
var todate = new Date(MM/DD/YYYY);
if (fromdate > todate){
    console.log('False');
}else{
    console.log('True');
}

если ваш формат даты отличается, используйте библиотеку moment.js для преобразования формата даты, а затем используйте приведенный выше код для сравнения двух дат

Пример:

Если ваша дата указана в формате "ДД/ММ/ГГГГ" и требуется преобразовать ее в "ММ/ДД/ГГГГ", см. Приведенный ниже пример кода

var newfromdate = new Date(moment(fromdate, "DD/MM/YYYY").format("MM/DD/YYYY"));
console.log(newfromdate);
var newtodate = new Date(moment(todate, "DD/MM/YYYY").format("MM/DD/YYYY"));
console.log(newtodate);

Ответ 19

Этот JS будет изменять содержание после установленной даты здесь то же самое, но в w3schools

date1 = new Date()
date2 = new Date(2019,5,2) //the date you are comparing

date1.setHours(0,0,0,0)

var stockcnt = document.getElementById('demo').innerHTML;
if (date1 > date2){
document.getElementById('demo').innerHTML="yes"; //change if date is > set date (date2)
}else{
document.getElementById('demo').innerHTML="hello"; //change if date is < set date (date2)
}
<p id="demo">hello</p> <!--What will be changed-->
<!--if you check back in tomorrow, it will say yes instead of hello... or you could change the date... or change > to <-->

Ответ 20

Просто используйте toDateString() для обеих дат. toDateString не включает время, поэтому для 2 раз в одну и ту же дату значения будут одинаковыми, как показано ниже.

var d1 = new Date(2019,01,01,1,20)
var d2 = new Date(2019,01,01,2,20)
console.log(d1==d2) // false
console.log(d1.toDateString() == d2.toDateString()) // true

Очевидно, что некоторые проблемы с часовыми поясами, высказанные в других местах по этому вопросу, являются действительными, но во многих случаях они не актуальны.

Ответ 21

Вы можете использовать fp_incr (0). Который устанавливает часть часового пояса в полночь и возвращает объект даты.