Meteor + MongoDB : Check if date is in range - javascript

I'm having a difficulty showing my records from MongoDB. Basically I have some fields 'leaves_start' and 'leaves_end' in my MongoDB. This fields has the date range of the user's leave. See example below.
user_name : junel
leaves_start: 10/05/2015
leaves_end: 10/10/2015
I want to get all the records in my MongoDB if the current date (e.g 10/07/2015) is within the range of the record's leaves_start and leaves_end.
I already tried $gte and $lte but I'm a little bit confused on how to implement it on my current state.
Here's my sample method:
getTowerLeaveData_LV: function(dateToday,tower) {
var arr = LeavesCollection.find($or: [
{ leaves_start: { $lte: dateToday } },
{ leaves_end: { $gte: dateToday } } ],
leaves_approval_status: {$ne: 'Rejected'}}).fetch();
return arr
},
Here's my sample Mongodb Record
_____________________________________
name | leaves_start | leaves_end
_____________________________________
Junel | 10/01/2015 | 10/03/2015
_____________________________________
Jaycee | 10/03/2015 | 10/03/2015
_____________________________________
Tori | 10/05/2015 | 10/10/2015
_____________________________________
Ryan | 10/02/2015 | 10/05/2015
If the value of dateToday is 10/03/2015, then method should return the records of Junel, Jaycee and Ryan.
I hope that this makes sense. Thanks guys!

startDate = ;// get Start Date from UI Convert it to date format using new Date();
endDate = ;// get End Date from UI Convert it to date format using new Date();
MyCollection.find({
leaves_start: { $lte: endDate}, // start Less and endDate
leaves_end: { $gte: startDate } // end greater than StartDate
});
if the startDate and endDate is same you get all the records for that date , else it will be date Range.

You'd do it like this
MyCollection.find({
leaves_start: { $lte: new Date },
leaves_end: { $gte: new Date }
});

I'm not sure if this will be helpful, but here's the code that I came up with:
THE RECORDS
METHOD:
//monthyear = "10-2015"
//numOfDays = 31
getTowerLeaveData_LV: function(monthyear, numOfDays,tower, userid, username) {
var selectedMonthYear = monthyear.split("-");
var tempArr = new Array();
var reArr = new Array()
tempArr.push(username)
reArr.push(username);
LeavesCollection.find({associate_tower: {$in: tower}, leaves_approval_status: {$ne: 'Rejected'}, user_id: userid},{sort:{leaves_timestamp :-1}},{fields: {_id:1,user_id:1,associate_id:1, associate_fullname:1,leaves_type:1,leaves_start:1,leaves_end:1, leaves_days:1}}).forEach(
function(leaver) {
for(var a=1; a!=numOfDays+1; a++) {
var dateActive = selectedMonthYear[0] + "/" + a.toString() + "/" + selectedMonthYear[1];
var res = dateCheck(leaver.leaves_start, leaver.leaves_end,dateActive);
if(res == true) {
tempArr.splice(a, 0,[leaver.leaves_approval_status,leaver.leaves_type,leaver._id,leaver.associate_fullname,a]);
}
}
});
for(var a=1; a!=numOfDays+1; a++) {
var temp = findKey(tempArr,a);
if(temp != false) {
reArr.push(tempArr[temp]);
} else {
reArr.push('null')
}
}
return reArr;
},
MISC JS FUNCTIONS:
function dateCheck(from,to,check) {
var fDate,lDate,cDate;
fDate = Date.parse(from);
lDate = Date.parse(to);
cDate = Date.parse(check);
if((cDate <= lDate && cDate >= fDate)) {
return true;
}
return false;
}
function findKey(array, search) {
var theIndex = false;
for (var i = 0; i < array.length; i++) {
if (array[i].indexOf(search) > -1) {
theIndex = i;
break;
}
}
return(theIndex);
}
OUTPUT IN ARRAY:
EXPLANATION OF OUTPUT:
The items after the Name in the array is equal to the value of numOfDays(which is dates). If the program find a match date to the range between "leaves_start" and "leaves_end", it will return the array data from mongodb, if not, it will return "null".

Related

Dynamic disable of day Date Picker JavaScript

I want to disable days dynamically by using array,
replacing the code :
var monday = 1;
var tuesday = 2;
with a dynamic value from a database
var disabledDay = ["1","2","3"];
Any help will really be appreciated Thanks
old code
jsFiddle: http://jsfiddle.net/314wd8t7/
$("#picker").datepicker(
{ beforeShowDay: function(day) {
var string = jQuery.datepicker.formatDate('yy-mm-dd', day);
var day = day.getDay();
var monday = 1;
var tuesday = 2;
if (day != monday && day != tuesday){
return [ true ]
} else {
return [ false ]
}
}
});
$('#picker').datepicker();
<div id="picker"></div>
I think you want something like this.
http://jsfiddle.net/dgo48jry/
const disabledDays = ["1", "2", "3"]
.map((n) => parseInt(n))
.filter((n) => !isNaN(n));
$("#picker").datepicker({
beforeShowDay: function(day) {
return [!disabledDays.includes(day.getDay())];
}
});
$('#picker').datepicker();
This assumes that your server is returning the values as strings. If you dont need string, you can simply remove the map filter lines.

Google Script does not trigger as expected given row conditions

I have the 2 columns in my table schema:
Column D= Date, i.e. 20180611 [yyymmdd]
Column F= Continuous Value, i.e. 0.1, 0.6, -0.3 etc.
This is what I want to happen:
Check in column D for yesterday's date. Then, take in the corresponding row, and check if column F is greater than 0.5 (for yesterday's date). If TRUE, then send an email alert.
This is the script I have but it does not trigger for some reason. What is wrong with it?
function readCell() {
var sheet = SpreadsheetApp.getActive().getSheetByName('test');
var dates = sheet.getRange('D1:D').getValues();
var date = null;
var dateRow = 0;
var dateCount = dates.length;
var yesterday = new Date();
yesterday.setDate(yesterday.getDate() - 1);
var yesterdayString = yesterday.toDateString();
for (dateRow; dateRow < dateCount; ++dateCount) {
try {
date = dates[dateRow].toDateString();
if (date === yesterdayString) {
++dateRow;
// To account for zero-based array
break;
}
} catch (error) {
Logger.log(error);
}
}
var value = sheet.getRange('F' + dateRow).getValue();
if (value >= 0.5) {
var result = ('Alert found on: ' + date);
MailApp.sendEmail('blabla#gmail.com', 'Alert', result);
}
};
Here is the data
The problem could be due to the use of an open reference D2:D to get values and then use dates.length to set the number of iterations on the for loop because it could be a number too large.
One "quick and dirty" way that could solve the above issue is to replace
var dateCount = dates.length;
by
var dateCount = sheet.getDataRange().getValues().length;

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;

Sort date string in an array

I wanted to sort an array of objects using js. Here is what I have implemented.
var employees = []
employees[0] = {
retiredate: "01/12/2014"
}
employees[1] = {
retiredate: "29/01/2015"
}
employees[2] = {
retiredate: "05/12/2014"
}
employees[3] = {
retiredate: "08/12/2014"
}
employees[4] = {
retiredate: "11/12/2014"
}
employees[5] = {
retiredate: "14/01/2015"
}
employees[6] = {
retiredate: "03/12/2014"
}
employees[7] = {
retiredate: "16/01/2015"
}
employees[8] = {
retiredate: "19/01/2015"
}
employees[9] = {
retiredate: "22/01/2015"
}
employees[10] = {
retiredate: "28/01/2015"
}
employees[11] = {
retiredate: "23/01/2015"
}
employees[12] = {
retiredate: "15/01/2015"
}
//console.log(periodesSorted);
console.log("START ... ")
employees.sort(function(a, b) {
var dateA = new Date(a.retiredate),
dateB = new Date(b.retiredate)
return dateA - dateB //sort by date ascending
})
for (ind2 = 0; ind2 < employees.length; ind2++) {
console.log(employees[ind2].retiredate)
}
console.log("End ... ")
In firefox the array of retiredate is well sorted.
In chrome, I have the following results
01/12/2014
15/01/2015
05/12/2014
08/12/2014
11/12/2014
14/01/2015
29/01/2015
16/01/2015
19/01/2015
22/01/2015
28/01/2015
23/01/2015
03/12/2014
The results are not sorted. Where did I go wrong in the codes?
Can anyone suggest a fix for this ?
Regards
You can use
employees.sort(function (d1, d2) {
function parseDate(str) {
var parts = str.match(/(\d+)/g);
// assumes M/D/Y date format
return new Date(parts[2], parts[0]-1, parts[1]); // months are 0-based
}
return parseDate(d1.retiredate) - parseDate(d2.retiredate);
});
Here Is example Link
Instead of this:
new Date(a.retiredate)
Make it like this to convert dd/mm/yyyy to yyyy-mm-dd before creating the date:
new Date(a.retiredate.replace( /(\d{2})\/(\d{2})\/(\d{4})/, "$3-$2-$1") );
Working JSFiddle:
http://jsfiddle.net/inanda/csz56b0q/1/
In our case you need convert date to format mm/dd/yyyy, you can do it like this
employees.sort(function(a, b) {
var toDate = function (date) {
var res = date.split('/');
return new Date(res[2], res[1], res[0]).getTime();
// getTime returns the number of milliseconds
// or you can use + before new Date..
};
return toDate(a.retiredate) - toDate(b.retiredate);
})
Example
Personally I would avoid all the re-parsing & date construction (84 times in your sample);
// prepare the data by appending a date from a reformatted string
for (var i = 0; i < employees.length; i++) {
var dateString = employees[i].retiredate;
employees[i]._date = new Date(dateString.substr(6, 4) + "-" + dateString.substr(3, 2) + "-" + dateString.substr(0, 2));
}
// sort without conversion
employees.sort(function(a, b) {
return a._date - b._date;
})

Loop from startdate to enddate from inputs with javascript

I've got a startdate and enddate from inputs. And I need to put all the dates from the startdate until the enddate into the database. Therefore I need to make a loop like this:
FOR i = startdate; i <= enddate; i + 1 day
{
here i use the date
}
How do I make such a loop with dates from input boxes?
I get 'invalid date' if I try to do this:
var endDate = new Date($("#enddate").val());
And I can't use the endDate.getTime() like I need as you said in the answer, if I do it like this.
var endDate = $("#enddate").val());
var endDateTime = endDate.getTime();
So basically: How can I convert the input to a date? The input of enddate is like this: dd/mm/yyyy.
No it's not an SQL question, I need to do this is javascript because I need to check the dates first.
Thank you for helping me out ;)
Would a loop like this work?:
var current_date = new Date("01/13/2013");
var end_date = new Date("01/20/2013");
var end_date_time = end_date.getTime();
while (current_date.getTime() < end_date_time) {
console.log(current_date);
current_date.setDate(current_date.getDate()+1);
}
http://jsfiddle.net/Sn6Ws/
Depending on the format of your textboxes' values, you can set it up like this:
$(document).ready(function () {
$("#btn").on("click", function () {
dateLooper(function (cur, end) {
console.log("Current date: " + cur.toString() + ", End Date: " + end.toString());
});
});
});
function dateLooper(callback) {
var start_date_text = document.getElementById("start_date").value;
var end_date_text = document.getElementById("end_date").value;
var current_date = new Date(start_date_text);
var end_date = new Date(end_date_text);
var end_date_time = end_date.getTime();
while (current_date.getTime() < end_date_time) {
//console.log(current_date);
callback.call(this, current_date, end_date);
current_date.setDate(current_date.getDate()+1);
}
}
http://jsfiddle.net/Sn6Ws/1/
Per your comments that explain the date are in the format "dd/mm/yyyy", you could use something like this:
var start_date_text = document.getElementById("start_date").value;
var start_split = start_date_text.split("/");
if (start_split.length != 3) {
return false;
}
start_date_text = start_split[1] + "/" + start_split[0] + "/" + start_split[2];
var end_date_text = document.getElementById("end_date").value;
var end_split = end_date_text.split("/");
if (end_split.length != 3) {
return false;
}
end_date_text = end_split[1] + "/" + end_split[0] + "/" + end_split[2];
to get the dates in the right format before passing them to new Date. Here's an updated jsFiddle that demonstrates it:
http://jsfiddle.net/Sn6Ws/4/
Of course, be careful that if the dates don't come in with the specified format (in case users can type this in or something), the code will most likely throw an error. You can obviously put more checks in to make sure certain things set before proceeding with certain operations (like making sure each item is a number/integer, making sure the days are in the range 1 to 31, etc.). So for that reason, you may want to go the route of regular expressions. At least with regular expressions, you can specify a specific pattern and know whether it matches perfectly or not, and immediately get the values you need to build a date.
Using regular expressions, here's an example that isn't complete but should hopefully help:
function dateLooper(callback) {
var re = /^(\d{1,2})\/(\d{1,2})\/(\d{4})$/;
var start_date_text = document.getElementById("start_date").value;
var start_match = re.exec(start_date_text);
if (start_match) {
var valid = true;
// Set `valid` variable based on the following
// Validate start_match[1] is valid day
// Validate start_match[2] is valid month
// Validate start_match[3] is valid year
if (valid) {
start_date_text = combineDate(start_match);
} else {
return false;
}
} else {
return false;
}
var end_date_text = document.getElementById("end_date").value;
var end_match = re.exec(end_date_text);
if (end_match) {
var valid = true;
// Set `valid` variable based on the following
// Validate end_match[1] is valid day
// Validate end_match[2] is valid month
// Validate end_match[3] is valid year
if (valid) {
end_date_text = combineDate(end_match);
} else {
return false;
}
} else {
return false;
}
var current_date = new Date(start_date_text);
var end_date = new Date(end_date_text);
var end_date_time = end_date.getTime();
var days_spent = 0;
while (current_date.getTime() < end_date_time) {
days_spent++;
callback.call(this, current_date, end_date, days_spent);
current_date.setDate(current_date.getDate()+1);
}
return days_spent;
}
function combineDate(re_match) {
return re_match[2] + "/" + re_match[1] + "/" + re_match[3];
}
http://jsfiddle.net/Sn6Ws/6/

Categories

Resources