JS Check if multiple dates are within range - javascript

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?

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

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

Related

JS Date incrementation

Doing this without libraries.
dates.forEach((date) => {
if(date.getDay() == 6) {
console.log('sat', date)
var t = new Date()
console.log('sat new', new Date(t.setDate(date.getDate() + 1)))
} else ...
}
Gives this output
sat
Date Sat Jan 01 2022 00:00:00 GMT+0200 (Eastern European Standard Time)
sat new
Date Sat Apr 02 2022 19:10:27 GMT+0300 (Eastern European Summer Time)
The point of this code is to see if a date is a saturday. If so, increment it towards becoming a work day (i know it says +1 but its a wip)
The result is that the day gets incremented. However for some reason it moves the date towards being in march. I have looked around and apparently this is how you're supposed to do it, but its not doing it.
When I try console.log('sat new', t.setDate(date.getDate() + 1)) (without new Date()) I get a timestamp of 1646236273249. Which this site converts to the 16th of March. Don't know how useful this is.
I hope I gave all the important information here.
In order to increment a day to a given date:
date = new Date(date)
date.setDate(date.getDate() + 1)
console.log(date)
var t = new Date() - not passing anything to the Date constructor will make it "right now".
I think you need to pass the iterated date to the Date constructor:
dates.forEach((date) => {
if(date.getDay() == 6) {
console.log('sat', date)
var t = new Date(date) // this line
console.log('sat new', new Date(t.setDate(date.getDate() + 1)))
}
}

How to set server time in Node.js

I would like to set (mock) my custom time to the Node.js server for testing purposes. Something like this:
console.log(new Date());
// Sat Jun 30 2018 20:00:00 GMT+0100
// ^^
someFunctionToSetTime('Sat Jun 30 2018 12:00:00 GMT+0100')
// ^^
console.log(new Date());
// Sat Jun 30 2018 12:00:00 GMT+0100
// ^^
How do I do this?
P.S. I don't really want to fake the Date class.
Just monkey patch the Date constructor:
let now = 'Sat Jun 30 2018 12:00:00 GMT+0100';
{
const oldDate = Date;
Date = function(...args) {
if(args.length) {
return new oldDate(...args);
} else {
return new oldDate(now);
}
};
Date.parse = oldDate.parse;
Date.UTC = oldDate.UTC;
Date.now = () => +(new Date());
}
First option : Without external modules you can use this to get timezone Date and time in node.js
var myDate = new Date().toLocaleString('en-US', {
timeZone: 'Europe/Paris'
});
Second option : Use momentjs timezone witch allows you to set your location and more... just check the documentation.

Comparing two dates in different timezones

I'm comparing two dates; one returned as a UTC String (as part of an Ajax response) and the second in local browser time:
Basically, I want to see if the date returned (endTime) happened before right now. My code is below and I thought I had it right but it's not working.
var isActive = true;
var buffer = 30000; // 30 seconds
var endTime = new Date(Date.parse(response.endTime)); // Fri Oct 23 2015 12:01:14 GMT-0400 (EDT)
var now = new Date(); // Thu Oct 22 2015 20:01:31 GMT-0400 (EDT)
var nowUtc = new Date(now).toUTCString(); // "Fri, 23 Oct 2015 00:01:31 GMT"
var nowTimeMs = new Date(nowUtc).getTime(); // 1445558491000
var endTimeMs = endTime.getTime() + buffer; // 1445616104000
if( nowTimeMs > endTimeMs ){
isActive = false;
}
isActive should remain as true but instead it's false. I feel like I've been looking at this too long and am missing something very simple. Am I?
Thanks for any helpful tips.
Update:
Based on the responses I thought I'd update my question. What is the best way to compare two dates where one is this:
new Date(); // Thu Oct 22 2015 21:51:53 GMT-0400 (EDT)
...and the other is a String representation of date:
"2015-10-23 01:49:27"
I figure the best way to create a valid Date object out of the String is using this code.
isThisActive:function(p){
var isActive = true;
var buffer = 30000;
var pEndTime = myObj.parseStringAsDate(p.callEndTime);
var now = new Date();
var offset = now.getTimezoneOffset() * 60000;
now.setTime( now.getTime() + offset );
var nowTimeMs = now.getTime();
var endTimeMs = pEndTime.getTime() + buffer;
if( nowTimeMs > endTimeMs ){
isActive = false;
}
return isActive;
},
parseStringAsDate:function(str){
var dateTimeStr = str.split(" ");
var dateStr = dateTimeStr[0].split("-");
var year = dateStr[0];
var month = dateStr[1];
var day = dateStr[2];
var timeStr = dateTimeStr[1].split(":");
var hours = timeStr[0];
var minutes = timeStr[1];
var seconds = timeStr[2];
return new Date( year,month,day,hours,minutes,seconds);
}
Because "pEndTime" is in UTC I applied the offset to the "now" Date object but even this is not working. Where's the problem here? I thought this would solve it.
SOLVED:
The latest code I posted did work. I was just getting incorrect values for the response.endTime (It wasn't converted to correct military time). Thank you everyone for your input. I've tried to upgrade as many helpful responses as I could.
You should not use the Date constructor or Date.parse (which do the same thing) to parse date strings. Either write your own parse function (below) or use a well maintained library.
To parse the format in the OP, you can use:
// Parse Thu Oct 22 2015 20:01:31 GMT-0400 (EDT)
function parseMMMDY(s) {
var b = s.split(/\W/);
var months = {jan:0,feb:1,mar:2,apr:3,may:4,jun:5,jul:6,aug:7,sep:8,oct:9,nov:10,dec:11};
var sign = /GMT-\d{4}/i.test(s)? 1 : -1;
var min = +b[5] + (sign * b[8].slice(0,2) * 60 ) + (sign * b[8].slice(-2));
return new Date(Date.UTC(b[3], months[b[1].toLowerCase().slice(0,3)], b[2], b[4], min, b[6]));
}
document.write(parseMMMDY('Thu Oct 22 2015 20:01:31 GMT-0400 (EDT)'));
I think the problem is here:
var endTime = new Date(Date.parse(response.endTime));
respnonse.endTime is UTC, right? But when you parse it to Date value, Date.parse assumes it is in local timezone (GMT-0400 as in your example code). It means that the endDate gets the wrong value
I usually use moment.js in my projects which related to formatting date time, especially in the reports (I'm working in the field of finance). You must have one more library in your project but it provides many other functionalities
Sorry, this is for your new update. I haven't got enough 'population' to leave a comment :P
var endTime = new Date(Date.parse(response.endTime)); // Fri Oct 23 2015 12:01:14 GMT-0400 (EDT)
var now = new Date(); // Thu Oct 22 2015 20:01:31 GMT-0400 (EDT)
Your endTime doesn't seem to return a UTC date as you mentioned. It looks to be using (EDT) so maybe you didn't have to convert it to UTC.

converting date into timestamp

I have date like this 25. 02. 2014 18:48:21 and I'm trying to convert it into timestamp
var someDate = '25. 02. 2014 18:48:21';
var timestamp = new Date(someDate).getTime();
but it's returning NaN since I moved files to a new domain, what can be a problem?
'25. 02. 2014 18:48:21' is not a valid date format. You'll have to convert it with regex first, like that:
var someDate = '25. 02. 2014 18:48:21';
var converted = someDate.replace(/^(\d{2}\. )(\d{2}\. )(\d{4})/, '$3. $2$1');
// converted is in format: YYYY. MM. DD.
var timestamp = new Date(converted).getTime();
Running this within the console, creating a new date with that variable gives me Invalid Date. Trying switching around the 25. and 02. like so:
var someDate = '02. 25. 2014 18:48:21';
var timestamp = new Date(someDate).getTime(); // 1393372101000
The format should be "Month, Day, Year, Time".
Switching month and day will work. I also removed the dots.
var date = "25. 02. 2014 18:48:21";
new Date(date.replace(/(\d{2})\. (\d{2})\./, '$2 $1'))
// Tue Feb 25 2014 18:48:21 GMT+0100 (W. Europe Standard Time)
you can try something like below (if your string has always same format)
var someDate = '25. 02. 2014 18:48:21';
var arr = someDate.split(' ');
var time = arr[3].split(':');
var timeStamp = new Date(arr[2],arr[1].split('.')[0],arr[0].split('.')[0],time [0],time[1],time[2]).getTime();
It uses javascript date object constructor
var d = new Date(year, month, day, hour, minute, seconds);
which works across all browsers
function convertSomeDate(str){
var d= str.match(/\d+/g),
dA= [d[2], '-', d[1], '-', d[0], 'T', d[3], ':', d[4], ':', d[5], 'Z'].join('');
return +new Date(dA)
}
var someDate= '25. 02. 2014 18:48:21';
convertSomeDate(someDate)
/* returned value: (Number)
1393354101000
*/

Convert date to end of day

I get time in milliseconds from the server. I convert it to Date and get -
Mon Jul 22 2013 11:16:01 GMT+0200 (W. Europe Daylight Time) as the date in the record.
I want to separate out data of Monday, Tuesday etc into arrays. I am thinking of converting this date to Mon Jul 22 2013 23:59:59 GMT+0200 (W. Europe Daylight Time) and then filter out the records.
How can i change the date to the required end of the day time? or is there an easier way to do this ?
You could always construct a new DateTime object just using the year, month and day properties from the existing date, like so:
var actualDate = new Date(); // 2013-07-30 17:11:00
var endOfDayDate = new Date(actualDate.getFullYear()
,actualDate.getMonth()
,actualDate.getDate()
,23,59,59); // 2013-07-30 23:59:59
For future visitors, just use
var start = new Date();
var end = new Date();
start.setHours(0,0,0,0);
end.setHours(23,59,59,999);
Using http://momentjs.com:
var now = new Date().getTime();
var endOfDay = moment(now).endOf("day").toDate(); // Wed Jan 20 2016 23:59:59 GMT-0800 (PST)
var actualDate = new Date()
var eodDate = new Date(Math.floor(actualDate.getTime()/86400000+1)*86400000 + actualDate .getTimezoneOffset()*60000 - 1000)
where 86400000 are total milliseconds in a day
If two Date Objects are on the same day then they have the same Date String:
new Date('1374488161000').toDateString()
=> "Tue Jul 30 2013"
new Date('13744917610403').toDateString()
=> "Tue Jul 30 2013"
Although a rather naive method of comparing days, it's probably the simplest comparison.

Categories