check date against an array of dates - javascript

I am trying to write a function that returns a TRUE or FALSE value based on whether the date is present in the array or not. Currently I have this:
function isInArray(value, array) {
var a = array.indexOf(value) > -1;
if (a == false) {
return false; //DATE DOES NOT EXIST
}
else {
return true; //DATE EXISTS IN ARRAY
}
}
Now normally I would use a for loop, however I am generating a list of dates between a start date and end date with this while loop:
while (day > 0) {
var tDate = new Date(sDate.addDays(dayCounter));
datesArray.push(tDate);
day = day - 1; //DEDUCT THE DAYS AS ADDED
var dateExists = isInArray(value, array);
if (dateExists == false) {
}
else {
matchedDays++;
}
daysCounter++;
}
this however is not working and always returns FALSE, what do I need to do to make this work and return the correct value?
sample data: ARRAY[26/12/2016, 27/12/2016, 28/12/2016, 29/12/2016]
value passed in [27/12/2016]
return TRUE if the value exists in the array
return FALSE if the value does not exist in the array
probably a simple mistake above! so thankyou for any help on this. also will a time affect the date when its being checked?

You can try using the find() method (if ecmascript is supported):
Case: array contains strings
var array = ["26/12/2016", "27/12/2016", "28/12/2016", "29/12/2016"];
var value1 = "26/12/2016"; //exists
var value2 = "26/12/2026"; //doesn't exist
function isInArray(array, value) {
return (array.find(item => {return item == value}) || []).length > 0;
}
console.log(isInArray(array, value1));
console.log(isInArray(array, value2));
Case: array contains Date objects
var array = [new Date("December 26, 2016 00:00:00"), new Date("December 27, 2016 00:00:00"), new Date("December 28, 2016 00:00:00"), new Date("December 29, 2016 00:00:00")];
var value1 = new Date("December 26, 2016 00:00:00"); //exists
var value2 = new Date("December 16, 2026 00:00:00"); //doesn't exist
function isInArray(array, value) {
return !!array.find(item => {return item.getTime() == value.getTime()});
}
console.log(isInArray(array, value1));
console.log(isInArray(array, value2));

you can use includes function.
ri = ["26/12/2016", "27/12/2016", "28/12/2016", "29/12/2016"];
ri.includes("20/12/2016"); //False
ri.includes("26/12/2016"); //True
Alternative to IE
indexOf return the position of value.
var pos = ri.indexOf("26/12/2016"); // 0
var pos = ri.indexOf("20/12/2016"); // -1
var pos = ri.indexOf("27/12/2016"); // 1
if(pos > -1){ //is in array }

Something like
function isInArray(value, array) {
for (var i = 0; i < array.length; i++) {
if (value == array[i]) {
return true;
}
}
return false;
}
should work..
You may have to use different comparing operations though.

I solved by getting only the first 15 characters in the dates, this is my snippet:
//get the first 15 characters of each date in my array (hdates)
for (i=0;i<hdates.length;i++){
hdates[i]=hdates[i].toString().substring(0,15); //converts dates to 15 characters long strings
}
function highlight(date) {
if(hdates.indexOf(date.toString().substring(0,15))>-1) { //converts my date element to compare, too
return'ok';
} else {
return 'ko';
}
}
if you don't want to alter your array, I'd suggest you to clone it and then convert the dates in 15 character long strings

Related

Creating Sorted Rows with JavaScript

At my wits end, I think I may be going code blind but can't for the life of me figure out what is causing the issue.
The desired outcome is for there to be only one date per row in the data array and as many flights for each date.
This works for the first item, but not any of the others, ending up with duplicate dates.
Where am I going wrong?
Desired data:
example in coming data 5 objects, only two dates.
["2020-02-20", "LGW"]
["2020-02-20", "LTN"]
["2020-02-20", "LHR"]
["2020-02-26", "LTN"]
["2020-02-26", "LHR"]
an array of two objects (one for each date), with the flights an array by date in the respective date object.
data = [ ["2020-02-20", ["LGW","LTN","LHR"]],
["2020-02-26", ["LTN","LHR"]]
]
Code shown below with comments:
function getRows(alternatives) {
var data = [];
for (var i = 0; alternatives.length > i; i++) {
var tmp = new Date(parseInt(alternatives[i].substring(0, 10)) * 1000);
var month = (tmp.getMonth() + 1);
var date = tmp.getFullYear() + "-" + (month < 10 ? "0" + month : month) + "-" + tmp.getDate();
var airport = alternatives[i].slice(11, 14);
var rowData = {
date: date,
flights: []
};
// if data has objects, check to see if the date is in any of the objects, if it isn't then add rowData to data
if (data.length > 0) {
for (var j = 0; data.length > j; j++) {
if (data[j].date === rowData.date) {
//if there are no flights, add the airport, if there are, is the airport already there, if not, add it
if (data[j].flights.length > 0 || !data[j].flights.includes(airport)) {
data[j].flights.push(airport);
}
}
else {
data.push(rowData);
continue;
}
}
}
else {
rowData.flights.push(airport);
data.push(rowData);
}
}
// not working, dupe dates are appearing in the rows
return data;
}
You can use reduce, create the object which has date as key with value consisting of array with date and array of flights. Check if key already exist, if present then only push in the flights array.
const input = [["2020-02-20", "LGW"],
["2020-02-20", "LTN"],
["2020-02-20", "LHR"],
["2020-02-26", "LTN"],
["2020-02-26", "LHR"]];
const output = Object.values(input.reduce((accu, [date, flight]) => {
if(!accu[date]) {
accu[date] = [date, [flight]];
} else {
accu[date][1].push(flight);
}
return accu;
}, {}));
console.log(output);

Get the minimum and maximum dates from JSON

There JSON:
[{"source":"2016-11-02","sourcecount":38},{"source":"2016-11-01","sourcecount":30},{"source":"2016-11-02","sourcecount":30},{"source":"2016-11-03","sourcecount":30}]
As in JavaScript to get the maximum and minimum date of it?
var array = [{"source":"2016-11-02","sourcecount":38},{"source":"2016-11-01","sourcecount":30},{"source":"2016-11-02","sourcecount":30},{"source":"2016-11-03","sourcecount":30}];
var max = null;
var min = null;
for (var i = 0; i < array.length; i++) {
var current = array[i];
if (max === null || current.source > max.source) {
max = current;
}
if (min === null || current.source < min.source) {
min = current;
}
}
document.getElementById('maxResult').innerHTML = max.source;
document.getElementById('minResult').innerHTML = min.source;
Max: <span id="maxResult"></span><br/ >
Min: <span id="minResult"></span>
You could do something like this, provided your date format is "yyyy-MM-dd".
Convert the date string to dateKey. which always follow the ascending order as the dates proceed. 20160101(Jan 1st) is always less than 20161231(Dec 31st).
Keeping that in mind, just convert the dates to dateKey and map dateKeys to the object and just extract the max and min of the dateKeys and return the actual date.
var datesArray = [{
"source": "2016-11-02",
"sourcecount": 38
}, {
"source": "2016-11-10",
"sourcecount": 30
}, {
"source": "2016-11-31",
"sourcecount": 38
}, {
"source": "2016-01-01",
"sourcecount": 30
}];
var newObject = {};
var dates = datesArray.map(function(obj) {
var regEx = new RegExp(/-/g);
//Convert date to dateKey
var dateKey = parseInt(obj.source.replace(regEx, ""), 10)
newObject[dateKey] = obj;
return dateKey;
});
console.log("Max", newObject[Math.max(...dates)].source);
console.log("Min", newObject[Math.min(...dates)].source);
The good thing is, your date is in ISO 8601 format already. You can just simply do this,
var data = [{"source":"2016-11-02","sourcecount":38},{"source":"2016-11-01","sourcecount":30},{"source":"2016-11-02","sourcecount":30},{"source":"2016-11-03","sourcecount":30}];
var dateArr = data.map(function(v) {
return new Date(v.source);
});
// Sort the date
dateArr.sort(function(a, b) {
return a.getTime() - b.getTime();
// OR `return a - b`
});
// The highest date is in the very last of array
var highestDate = dateArr[dateArr.length - 1];
// The lowest is in the very first..
var lowestDate = dateArr[0];
Or you prefer to have your original object instead, then you can do,
var data = [{"source":"2016-11-02","sourcecount":38},{"source":"2016-11-01","sourcecount":30},{"source":"2016-11-02","sourcecount":30},{"source":"2016-11-03","sourcecount":30}];
data.sort(function(a,b) {
var date1 = (new Date(a.source));
var date2 = (new Date(b.source));
return date1 - date2;
});
// highest date is '2016-11-03'
var highestDate = data[data.length - 1].source
// lowest date is '2016-11-01'
var lowestDate = data[0].source
Try this
var data = [{"source":"2016-11-02","sourcecount":38},{"source":"2016-11-01","sourcecount":30},{"source":"2016-11-02","sourcecount":30},{"source":"2016-11-03","sourcecount":30}]
function compare(a,b) {
if (new Date(a.source) < new Date(b.source))
return -1;
if (new Date(a.source) > new Date(b.source))
return 1;
return 0;
}
data = data.sort(compare);
var minDate = data[0].source;
var maxDate = data[data.length - 1].source;

Check isDate is returning Invalid date

I have date string like this 1 May 2010 To 15 Aug 2016 .I just want to check this as date string on my function and not to proceed on a function.When I'm checking this string with new Date(value) its returning Invalid date.How can I check this as date?
I would use js date library moment js for this.
var checkDate = function (str){
var dates = str.split("To");
var flag = true;
for(var i = 0; i < dates.length; i++) {
if (moment(dates[i]).isValid()) {
flag = false;
}
}
return flag;
}
I have created a fiddle for that
https://jsfiddle.net/Refatrafi/wj5zc75e/
var str = "1 May 2010 To 15 Aug 2016";
//First split string
var array = str.split("To");
//then check if both are dates
for(var i = 0; i < array.length; i++) {
if(isNaN(new Date(array[i]))) { //Checking date
alert(array[i]+ ' is not valid date');
}
}
When parsing strings you should always provide the format of the string to parse. This can be done very simply using the ES5 every method:
var isValid = '1 May 2010 To 15 Aug 2016'.split(' To ').every(function(s) {
return moment(s,'D MMM YYYY').isValid();
});
console.log(isValid);
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.14.1/moment.js"></script>
If arrow functions are OK, then:
var isValid = '1 May 2010 To 15 Aug 2016'.split(' To ').every(s=>moment(s,'D MMM YYYY').isValid());
does the job.
var checkDate = function (str){
var dates = str.split("To");
for(var i = 0; i < dates.length; i++) {
if (moment(dates[i]).isValid()) {
return true;
} else {
return false;
}
}
}
I can use this function in my code anywhere.

How to get specific year from the Date field in jquery

I know its a bit silly question, but I actually wanted to know how can I retrieve the year value for a date that I already have without using the "Split" function. I can achieve it with the help of the "split" function. Below is the code that I used in jquery.
outputJSon = JSON.parse($('#' + Datepicker_id).val());
var currentYear = parseInt(CalculateYearfromString($('#' + currentActivityCalendarId).parents('.service-timeline').find('.membership-year .period').text()));
if (currentYear === undefined && $.trim(currentYear) === "")
currentYear = new Date().getFullYear();
if (parseInt(outputJSon["Date"].split('/')[0]) === currentYear)
outputDate = outputJSon["Date"];
else
outputDate = outputJSon["Date"].replace(outputJSon["Date"].split('/')[0], currentYear)
outputDateType = outputJSon["DateType"];
In the above code, I am retrieving the date value in a JSON format which returns Date eg. 2016/05/26 and DateType eg. Day.
I am fetching the current year that I have selected and then checking if currentYear value is equal to the year that I have in the outputJSon["Date"]. If there is a match, then I am replacing the [0] value of the outputJSon["Date"] with the currentYear, with the help of replace function. This works as expected and no error is encountered.
I just want to be sure that if the date format changes(from 2016/05/26 to 26/05/2016)**then the split function that I have written will retrieve wrong value. How can I avoid this. Shall I remove **split function and think of something else?
Any help is appreciated.
Thanks,
Totally unsexy, but what's wrong with indexOf?
if (outputJSon["Date"].indexOf(currentYear) != -1) {
// currentYear is in the string somewhere
}
Note also that in the original, there is no need for parseInt:
outputJSon["Date"].split('/')[0] == currentYear
is sufficient (and less to type).
Also, parseInt will never return undefined, so:
currentYear === undefined
will always be false and so:
if (currentYear === undefined && $.trim(currentYear) === "")
will never be true and the assignment:
currentYear = new Date().getFullYear();
will never execute.
I would also seriously question the use of:
outputJSon = JSON.parse($('#' + Datepicker_id).val());
The use of JSON.parse seems entirely gratuitous, you already have a string returned by $('#' + Datepicker_id).val().
You can check the length to make sure it is a valid year number.
currentYear2 = outputJSon["Date"].split('/');
currentYear2 = (currentYear2[0].length === 4) ? currentYear2[0] : currentYear2[2];
Is there any issues when you simply do
outputDate = new Date(outputJSon["Date"]).getFullYear();
You can try something like this:
JSFiddle.
Code
function getYear() {
var input = $("#dpDate").val();
var cdate = getDate(input);
console.log(cdate, cdate.getFullYear());
}
function getDate(input) {
var arr = [];
var seperator = ['/', '-'];
var year, month, date;
var yearIndex = 2;
var result = undefined;
seperator.forEach(function(s) {
if (input.indexOf(s) > -1)
arr = input.split(s);
});
if (arr.length > 1) {
// Set year
if (arr[0] > 1000) {
year = arr[0]
yearIndex = 0;
} else if (arr[2] > 1000) {
year = arr[2];
yearIndex = 2;
}
// set month and date
// If string starts with year, assume yyyy/mm/dd
if (yearIndex === 0) {
month = arr[1]
date = arr[2]
} else {
// If value greater than 12, assume it as date and other one as month
if (arr[0] > 12) {
date = arr[0]
month = arr[1]
} else if (arr[1] > 12) {
date = arr[1]
month = arr[0]
}
// If none of the value is ggreater than 12, assume default format of dd/mm/yyyy
else {
date = arr[0]
month = arr[1]
}
}
result = new Date(year, month - 1, date);
}
return result;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<input id="dpDate" type="text" placeholder="dd/mm/yyyy" value="15/2/2016" />
<button onclick="getYear()">Get Year</button>
regex_yearfirst = /\d{4}\W/;
regex_yearlast = /\d{4}\n/;
if (regex_yearfirst.test(outputJSon["Date"])) {
yearIndex=0;
}
else if (regex_yearlast.test(outputJSon["Date"])) {
yearIndex=2;
}
else {
console.log("date format not recognized")
}
if (parseInt(outputJSon["Date"].split('/')[yearIndex]) === currentYear) {
outputDate = outputJSon["Date"];
}
else {
outputDate = outputJSon["Date"].replace(outputJSon["Date"].split('/')[yearIndex], currentYear)
}

How to sort just a single column in 2d array

I have a 2d array called dateTime[]. dateTime[count][0] contains future datetime and dateTime[count][1] contains a 4 digit value like 1234 or something.
I am trying to sort the column 0 that is dateTime[count][0] in ascending order. ( i,e, sorting the colunm 0 of the 2d array according to closest datetime from now)
Suppose my javascript 2d array is like:
dateTime[0][0] = 2/26/2013 11:41AM; dateTime[0][1] = 1234;
dateTime[1][0] = 2/26/2013 10:41PM; dateTime[1][1] = 4567;
dateTime[2][0] = 2/26/2013 8:41AM; dateTime[2][1] = 7891;
dateTime[3][0] = 3/26/2013 8:41AM; dateTime[3][1] = 2345;
I just wrote like this actually this is how I inserted value to dateTime[count][0] ; = new Date(x*1000); where x is unix time()
How I want the array to look after sorting:
dateTime[0][0] = 2/26/2013 8:41AM; dateTime[0][1] = 7891;
dateTime[1][0] = 2/26/2013 11:41AM; dateTime[1][0] = 1234;
dateTime[2][0] = 2/26/2013 10:41PM; dateTime[2][1] = 4567;
dateTime[3][0] = 3/26/2013 8:41AM; dateTime[3][1] = 2345;
please let me know how to solve this with less code.
Thanks. :)
This what I have done till now (I haven't sorted the array, also here dateTime is called timers)
function checkConfirm() {
var temp = timers[0][0];
var timeDiv = timers[0][1];
for (var i=0;i<timers.length;i++) {
if (timers[i][0] <= temp) { temp = timers[i][0]; timeDiv = timers[i][1]; }
}
if (timers.length > 0 ){ candidate(temp,timeDiv); }
}
function candidate(x,y) {
setInterval(function () {
var theDate = new Date(x*1000);
var now = new Date();
if ( (now.getFullYear() === theDate.getFullYear()) && (now.getMonth() === theDate.getMonth()) ) {
if ( (now.getDate() === theDate.getDate()) && (now.getHours() === theDate.getHours()) ) {
if ( now.getMinutes() === theDate.getMinutes() && (now.getSeconds() === theDate.getSeconds()) ) { alert("its time"); }
}
}
}, 10);
}
AT the end, I wanted to alert the user every time when the current time matches the time in the array. This is how I tried to solve the problem but this is completely wrong approach.
Use the .sort() function, and compare the dates.
// dateTime is the array we want to sort
dateTime.sort(function(a,b){
// each value in this array is an array
// the 0th position has what we want to sort on
// Date objects are represented as a timestamp when converted to numbers
return a[0] - b[0];
});
DEMO: http://jsfiddle.net/Ff3pd/

Categories

Resources