Comparing date part only without comparing time in

2019-01-01 05:21发布

问题:

What is wrong with the code below?

Maybe it would be simpler to just compare date and not time. I am not sure how to do this either, and I searched, but I couldn\'t find my exact problem.

BTW, when I display the two dates in an alert, they show as exactly the same.

My code:

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

Is there a simpler way to compare dates and not including the time?

回答1:

I\'m still learning JavaScript, and the only way that I\'ve found which works for me to compare two dates without the time is to use the setHours method of the Date object and set the hours, minutes, seconds and milliseconds to zero. Then compare the two dates.

For example,

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

date2 will be set with hours, minutes, seconds and milliseconds to zero, but date1 will have them set to the time that date1 was created. To get rid of the hours, minutes, seconds and milliseconds on date1 do the following:

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

Now you can compare the two dates as DATES only without worrying about time elements.



回答2:

How about this?

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

It allows you to compare the date part of the date like this without affecting the value of your variable:

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


回答3:

BEWARE THE TIMEZONE

Using the date object to represent just-a-date straight away gets you into a huge excess precision problem. You need to manage time and timezone to keep them out, and they can sneak back in at any step. The accepted answer to this question falls into the trap.

A javascript date has no notion of timezone. It\'s a moment in time (ticks since the epoch) with handy (static) functions for translating to and from strings, using either the \"local\" timezone of the device, or, if specified, UTC. To represent a date with a date object, you want your dates to represent UTC midnight at the start of the date in question. This is a common and necessary convention that lets you work with dates regardless of the season or timezone of their creation. So you need to be very vigilant to manage the notion of timezone, both when you create your midnight UTC Date object, and when you serialize it.

Deserializing (or creating midnight UTC Date objects)

Most of the time, you will want your date to reflect the timezone of the user. Click if today is your birthday. Users in NZ and US click at the same time and get different dates. In that case, do this...

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

Sometimes, international comparability trumps local accuracy. In that case, do this...

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

Deserialize a date

Often dates on the wire will be in the format YYYY-MM-DD. To deserialize them, do this...

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

Serializing

Having taken care to manage timezone when you create, you now need to be sure to keep timezone out when you convert back to a string representation. So you can safely use...

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

And totally avoid everything else, especially...

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

So to answer your question, 7 years too late...

<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>

See it running...



回答4:

Using Moment.js

If you have the option of including a third-party library, it\'s definitely worth taking a look at Moment.js. It makes working with Date and DateTime much, much easier.

For example, seeing if one Date comes after another Date but excluding their times, you would do something like this:

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

The second parameter you pass into isAfter is the precision to do the comparison and can be any of year, month, week, day, hour, minute or second.



回答5:

Simply compare using .toDateString like below:

new Date().toDateString();

This will return you date part only and not time or timezone, like this:

\"Fri Feb 03 2017\"

Hence both date can be compared in this format likewise without time part of it.



回答6:

This might be a little cleaner version, also note that you should always use a radix when using 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);
    }
});

Checkout the MDC parseInt page for more information about the radix.

JSLint is a great tool for catching things like a missing radix and many other things that can cause obscure and hard to debug errors. It forces you to use better coding standards so you avoid future headaches. I use it on every JavaScript project I code.



回答7:

The date.js library is handy for these things. It makes all JS date-related scriping a lot easier.



回答8:

This is the way I do it:

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:

As I don\'t see here similar approach, and I\'m not enjoying setting h/m/s/ms to 0, as it can cause problems with accurate transition to local time zone with changed date object (I presume so), let me introduce here this, written few moments ago, lil function:

+: Easy to use, makes a basic comparison operations done (comparing day, month and year without time.)
-: It seems that this is a complete opposite of \"out of the box\" thinking.

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

Usage:

datecompare(date1, \'===\', date2) for equality check,
datecompare(date1, \'>\', date2) for greater check,
!datecompare(date1, \'>\', date2) for less or equal check

Also, obviously, you can switch date1 and date2 in places to achieve any other simple comparison.



回答10:

Make sure you construct userDate with a 4 digit year as setFullYear(10, ...) !== setFullYear(2010, ...).



回答11:

After reading this question quite same time after it is posted I have decided to post another solution, as I didn\'t find it that quite satisfactory, at least to my needs:

I have used something like this:

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

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

In that way I could have used the dates in the format I wanted for processing afterwards. But this was only for my need, but I have decided to post it anyway, maybe it will help someone



回答12:

You can use some arithmetic with the total of ms.

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

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

I like this because no updates to the original dates are made and perfom faster than string split and compare.

Hope this help!



回答13:

An efficient and correct way to compare dates is:

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

It ignores the time part, it works for different timezones, and you can compare for equality == too. 86400000 is the number of milliseconds in a day (= 24*60*60*1000).

Beware that the equality operator == should never be used for comparing Date objects because it fails when you would expect an equality test to work because it is comparing two Date objects (and does not compare the two dates) e.g.:

> 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

Notes: If you are comparing Date objects that have the time part set to zero, then you could use date1.getTime() == date2.getTime() but it is hardly worth the optimisation. You can use <, >, <=, or >= when comparing Date objects directly because these operators first convert the Date object by calling .valueOf() before the operator does the comparison.



回答14:

I know this question have been already answered and this may not be the best way, but in my scenario its working perfectly, so I thought it may help someone like me.

if you have date string as

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

and you just want to compare the date part with another Date object in JS,

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

then you have to convert the string to Date object by using new Date(\"2018-01-01T18:19:12.543\");

and here is the trick :-

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

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

I have used toDateString() of Date object of JS, which returns the Date string only.

Note: Don\'t forget to use the .valueOf() function while comparing the dates.

more info about .valeOf() is here reference

Happy codding.



回答15:

This will help. I managed to get it like this.

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