Сравнение только части даты без сравнения времени в 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);
    }
});

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

15 ответов


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

например,

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

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

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

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


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

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

ОСТЕРЕГАЙТЕСЬ ЧАСОВОГО ПОЯСА

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

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

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

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

// create a date (utc midnight) reflecting the value of myDate and the environment's 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){
  debugger;
  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>

смотрите, как он работает...


используя момент.js

если у вас есть возможность включить стороннюю библиотеку, определенно стоит взглянуть на момент.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.


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

window.addEvent('domready', function() {
    // Create a Date object set to midnight on today's 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 является отличным инструментом для ловли таких вещей, как отсутствующий radix и многие другие вещи, которые могут вызвать неясные и трудно отлаживать ошибки. Это заставляет вас использовать лучшие стандарты кодирования, чтобы избежать будущих головных болей. Я использую его на каждом Код на JavaScript я.


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

new Date().toDateString();

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

"Пт Фев 03 2017"

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


на дата.js библиотека удобна для таких вещей. Он делает все даты, связанные с JS scriping намного проще.


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

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();
    });
}

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

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

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 в местах для достижения любого другого простого сравнения.


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


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

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

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

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

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


вы можете использовать арифметику с МС.

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

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

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

надеюсь, что это поможет!


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

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

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

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

> 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

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


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

если у вас date string as

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

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

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

тогда тебе надо convert на string to


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

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