-1

I'm trying to check dates in Javascript for a calendar (fullcalendar), essentially I just want it to not be able to choose past dates:

        dateClick: function(info) {
            var today = Date.now();
            var check = new Date(info.dateStr)

            if(check < today)
            {
                alert('You cannot request dates in the past');
                return;
            }
            else
            {
                alert('this is the future');
            }
        },

I'm getting some odd results in that, it seems to calculate the past fine, but also calculates the current day as the past AS well as tomorrow. The day after tomorrow it calculates as the future. No sure what's going on.

info.dateStr gives the format YYYY-mm-dd.

AlphaOmega
  • 117
  • 10

2 Answers2

1

You should coerce to number using +Date or use .getTime() to make sure you are comparing the numeric timestamp values. You're probably fine since you're using Date.now(), which returns a timestamp.

Parsing using the string parsing for Date is strongly discouraged, due to issues like the one in OP:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/Date

Use Date(yyyy, mm, dd, ...) constructor (which uses local time zone) by parsing string manually instead of built-in Date string parsing (which uses UTC if timezone isn't provided).
Using end of the day by adding 24*60*60*1000 to the getTime() value, as that's most likely what you're expecting (same date as today being past is not what most people usually want).
eg: with date to check 05-29-2020, you actually want anything before 05-29-2020 23:59:999

ie: check=05-29-2020 23:59:999 < today=05-29-2020 22:00:000 === false (not past)
or to put it another way the actual intention when:
05-29-2020 => anything from 05-29-2020 00:00 to 05-29-2020 23:59 => actually same as checking 05-30-2020 00:00 - 1 millisecond

dateClick = function(info) {

        var today = Date.now()
        var check = (([y,m,d])=>new Date(+y,+m-1,+d))(info.dateStr.split(/\D/)).getTime()
           + 24*60*60*1000-1  // add full day so same date as today is not past
        console.log(today,check)
        

        if(check < today)
        {
            alert('You cannot request dates in the past');
            return;
        }
        else
        {
            alert('this is the future');
        }
    }
    dateClick({dateStr:'2020-05-28'})
    dateClick({dateStr:'2020-05-29'})
    dateClick({dateStr:'2020-05-30'})
    dateClick({dateStr:'2020-05-31'})
user120242
  • 14,918
  • 3
  • 38
  • 52
  • is there any reason you wouldn't want to replace all of that code with: `if(check.getTime() < today.getTime())` ? – Rick May 30 '20 at 03:32
  • 2 issues: UTC problems, and expectation of any time during the day matching. So for example, if my local time offset Date is on a different Date than UTC time, the date used will be one day earlier, or one day later, if I'm near the beginning or end of the day. The other issue is the one I mentioned at the end. When people say 05-29-2020, they usually mean that if today is 05-29-2020 08:00, anything from 05-29-2020 00:00 to 05-29-2020 23:59 should also pass – user120242 May 30 '20 at 03:35
  • So the actual intention wanted (as mentioned by OP and is generally what most people mean) is that given 05-29-2020 => should allow anything from 05-29-2020 00:00 to 05-29-2020 23:59 => actually the same as saying check 05-29-2020 23:59:59 or 05-30-2020 00:00:00 – user120242 May 30 '20 at 03:45
  • Also today.getTime() would fail. Date.now() is a number timestamp. I put that fix in too at the start, but that's not the problem he was having. – user120242 May 30 '20 at 03:51
0

you want to compare dates like this: date1.getTime() - date2.getTime()

also, keep in mind, if your goal is to make sure a user is inputing a date that is not in the past, you can use html5 date input with a min set:

<input type="date" min="2020-05-29">
Rick
  • 1,710
  • 8
  • 17