1

I have the following code where I have an arrival date and departure date and edit their format, as well as a disabled date:

var aankomstDatum = "19-05-2018";
var parts = aankomstDatum.split('-');
aankomstDatumDate = new Date(parts[2],parts[1]-1,parts[0]);

vertrekDatum = "02-06-2018";
var parts2 = vertrekDatum.split('-');
vertrekDatumDate = new Date(parts2[2],parts2[1]-1,parts2[0]);

var aankomstDatumDateCheck = (aankomstDatumDate.getMonth() + 1) + '/' + aankomstDatumDate.getDate() + '/' +  aankomstDatumDate.getFullYear();
//alert(aankomstDatumDateCheck);

var vertrekDatumDateCheck = (vertrekDatumDate.getMonth() + 1) + '/' + vertrekDatumDate.getDate() + '/' +  vertrekDatumDate.getFullYear();
//alert(vertrekDatumDateCheck);

var disabledDates = "26-05-2018";
var partsdisabled = disabledDates.split('-');
var disableddatesDatumDate = new Date(partsdisabled[2], partsdisabled[1]-1, partsdisabled[0]); //alert(disableddatesDatumDate);

var disableddatesDatumDateCheck = (disableddatesDatumDate.getMonth() + 1) + '/' + disableddatesDatumDate.getDate() + '/' +  disableddatesDatumDate.getFullYear();
//alert(disableddatesDatumDateCheck);

if(dateCheck(aankomstDatumDateCheck,vertrekDatumDateCheck,disableddatesDatumDateCheck)) {
    console.log("Not available");
} else {
    console.log("Available");
}

function dateCheck() {
    return true;
}

Basically, if the disabled date is between the arrival date and departure date, the if-else fires, and in the other case the else.

This code works (hooray!), but I'm not there yet. Because I planned to have multiple dates as var disabledDates and that's where I'm stuck. So, how can edit the code that multiple disabled dates are checked?

halfer
  • 19,824
  • 17
  • 99
  • 186
Kevin Verhoeven
  • 179
  • 3
  • 18
  • Can you provide a working example? e.g. Declare aankomstDatumDate and give it a date. If you insert a code sample and paste your code into the JavaScript box (bottom-left), you'll get a Run script button which runs your code. I also think your code could be simplified a lot, which I'd be happy to do when you have a working example. – DJDaveMark Jan 23 '18 at 15:57
  • OK I removed the errors from the code you posted. Is the arrival date supposed to be before the departure date, i.e. You don't want people to have a holiday/work trip where the period contains a disabled date? Are these dates a good test case: `{ arrival: 25-05-2018, disabled: 26-05-2018, departure: 27-05-2018 }`? – DJDaveMark Jan 23 '18 at 16:12
  • Hi, I have made a working example here: https://jsfiddle.net/x3gys7wa/ The disabled date should best be between the arrival date and the departure date for this test e.g. that would mean someone else has already reserved during that period. If you need any more info, i'll do my best to help! – Kevin Verhoeven Jan 23 '18 at 16:17
  • Also edited the question with your edits + how I get the arrival and departure dates in my current code. – Kevin Verhoeven Jan 23 '18 at 16:21

2 Answers2

3

Here's a simplified version of your code, which works as you ask. I think it's better to construct Date objects using ISO8601 formatted text while testing i.e. "2018-05-19" (which creates dates in UTC). Also see tips at the end of the answer.

Click the Run code snippet button below the code to see the console output (much better than using alert):

var start = new Date("2018-05-19");
var end = new Date("2018-06-02");

var bookings = [
    new Date("2018-05-26"),
    new Date("2018-05-28")
];

if (validPeriod(start, end, bookings)) {
    console.log("no bookings found");
} else {
    console.log("found at least one booking");
}

function validPeriod(start, end, bookings) {
    var valid = true;

    for (var i = 0; i < bookings.length; i++) {
        var date = bookings[i];
        if (start <= date && date <= end) {
            valid = false;
            break;
        }
    }

    return valid;
}

Tips

I strongly recommend you use Moment.js to work with dates. It'll save you headaches in the future.

If you don't opt for Moment.js, just remember that depending on how you create the date will depend on which timezone is used, and depending on the timezone of your computer which date will display, One easy way is to use the new Date(year, month, day, hours, minutes, seconds) constructor:

// for a browser/computer in timezone GMT+0200 (Paris)

// create a local date
new Date(2018, 5-1, 18).toString() // "Fri May 18 2018 00:00:00 GMT+0200 (CEST)"
new Date(2018, 5-1, 18).toISOString() // "2018-05-17T22:00:00.000Z"

// create a UTC date
new Date(Date.UTC(2018, 5-1, 18)).toString() // "Fri May 18 2018 02:00:00 GMT+0200 (CEST)"
new Date(Date.UTC(2018, 5-1, 18)).toISOString() // "2018-05-18T00:00:00.000Z"

// for a browser/computer in timezone GMT-0400 (New York)

// create a local date
new Date(2018, 5-1, 18).toString() // "Fri May 18 2018 00:00:00 GMT-0400 (EDT)"
new Date(2018, 5-1, 18).toISOString() // "2018-05-18T04:00:00.000Z"

// create a UTC date
new Date(Date.UTC(2018, 5-1, 18)).toString() // "Thu May 17 2018 20:00:00 GMT-0400 (EDT)"
new Date(Date.UTC(2018, 5-1, 18)).toISOString() // "2018-05-18T00:00:00.000Z"

But watch out if you use a string for the Date constructor because it uses Date.parse(dateString) internally and sometimes it's interpreted as a local date, and sometimes UTC:

// for a browser/computer in timezone GMT-0400 (New York)
new Date("08-19-2018"); // Sun Aug 19 2018 00:00:00 GMT-0400 (EDT) <-- local
new Date("08/19/2018"); // Sun Aug 19 2018 00:00:00 GMT-0400 (EDT) <-- local
new Date("2018-05-19"); // Fri May 18 2018 20:00:00 GMT-0400 (EDT) <-- UTC
new Date("2018/05/19"); // Sat May 19 2018 00:00:00 GMT-0400 (EDT) <-- local
DJDaveMark
  • 2,669
  • 23
  • 35
  • Thanks a lot! For this project I am not able to use JS libraries (clients eh?), so that's why this one was so difficult. You helped me a lot! – Kevin Verhoeven Jan 23 '18 at 16:46
  • @KevinVerhoeven Accept my answer and I'll be even happier to have helped ;o) – DJDaveMark Jan 23 '18 at 16:49
  • "*It's better to construct Date object using ISO8601 formatted text while testing*"— not necessarily. The built-in parser will parse "2018-05-19" as UTC, whereas user may expect it to be parsed as local (i.e. per ISO 8601). – RobG Jan 23 '18 at 20:37
  • @RobG That's why I sent a link to MDN on Date constructor params with ISO8601 & why I mentioned Moment.js Date's in JavaScript can be a problem if not used correctly. – DJDaveMark Jan 24 '18 at 08:51
  • @RobG I'll add an extra mention for the fact that his example used local timezone, and my answer uses UTC. – DJDaveMark Jan 24 '18 at 09:11
1

Adding to the @djdavemark's answer,

You can also use JavaScript's in build some function to check if any date is falling in the given range.

As @RobG mentioned that for some browsers these date strings might give wrong results, therefore just to be safe you can explicitly format in the way Date constructor accepts.

From @CMS's answer Question: Why does Date.parse give incorrect results?

function parseDate(input) {
  var parts = input.split('-');
  // new Date(year, month [, day [, hours[, minutes[, seconds[, ms]]]]])
  return new Date(parts[2], parts[1]-1, parts[0]); // Note: months are 0-based
}  

var startData = parseDate("19-05-2018")
var endDate = parseDate("25-05-2018")

var dateSet = [
"20-05-2018",
"21-05-2018",
"22-05-2018"
];

var dateSet2 = [
"26-05-2018",
];

function inBetween(element, index, array) {
  return parseDate(element) >= startData && parseDate(element) <= endDate;
}

console.log(dateSet.some(inBetween))

console.log(dateSet2.some(inBetween))

This looks more elegant.

For more information on array's some method MDN Docs

Vignesh Raja
  • 7,927
  • 1
  • 33
  • 42
warl0ck
  • 3,356
  • 4
  • 27
  • 57
  • MDN is not the "official docs", it's a public wiki hosted by Mozilla that anyone can contribute to. The only "official" documentation is the language standard, [*ECMA-262*](http://www.ecma-international.org/ecma-262/8.0/index.html). It is also not recommended to use the built-in parser, in many browsers (e.g. Chrome) new Date("19-05-2018") will return an invalid Date. See [*Why does Date.parse give incorrect results?*](https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results) – RobG Jan 23 '18 at 23:01
  • Thanks for the feedback @RobG, I have updated the answer accordingly. – warl0ck Jan 24 '18 at 04:06
  • 1
    You should post your code as a runnable snippet, which would reveal that it doesn't work correctly. You're passing values from the array as strings, then comparing to Date objects. Both will be coerced to type Number, and "20-05-2018" evaluates to NaN. NaN is never <= to anything, including NaN, so returns *false* (see [*Abstract Relational Comparison algorithm*](http://www.ecma-international.org/ecma-262/8.0/index.html#sec-abstract-relational-comparison)). – RobG Jan 24 '18 at 04:33
  • Thanks for adding this insight too! – Kevin Verhoeven Jan 24 '18 at 08:39