Date comparison in Javascript acts like a string comparison - javascript

I'm using Angular and have the following filter function in my controller:
$scope.filterDocuments = function (row) {
var dateCompare = $filter('date')(row.FilingDate, 'MM/dd/yyyy');
if (dateCompare >= $scope.dateLimit) {
if ($scope.query === '' || $scope.query === undefined) {
return true;
} else if (angular.lowercase(row.Description).indexOf($scope.query) !== -1) {
return true;
} else {
return false;
}
} else {
return false;
}
};
This function is used to filter the data during an ng-repeat. What happens is the date comparision is acting like a string comparision. I have tried changing the code to this:
$scope.filterDocuments = function (row) {
var dateCompare = $filter('date')(row.FilingDate, 'MM/dd/yyyy');
if (dateCompare.getTime() >= $scope.dateLimit.getTime()) {
if ($scope.query === '' || $scope.query === undefined) {
return true;
} else if (angular.lowercase(row.Description).indexOf($scope.query) !== -1) {
return true;
} else {
return false;
}
} else {
return false;
}
};
And that fails worse!
How to fix this so that the date comparision works and I can filter based upon the dates?

I found the answer on another thread (can't find it now). I am using the following function:
function stringToDate(_date, _format, _delimiter) {
var formatLowerCase = _format.toLowerCase();
var formatItems = formatLowerCase.split(_delimiter);
var dateItems = _date.split(_delimiter);
var monthIndex = formatItems.indexOf("mm");
var dayIndex = formatItems.indexOf("dd");
var yearIndex = formatItems.indexOf("yyyy");
var month = parseInt(dateItems[monthIndex]);
month -= 1;
var formatedDate = new Date(dateItems[yearIndex], month, dateItems[dayIndex]);
return formatedDate;
}
This takes a date string and returns a formatted date. I then use that to do the comparision:
if (stringToDate(dateCompare, 'mm/did/yyyy', '/') >= stringToDate($scope.dateLimit, 'mm/did/yyyy', '/')) {
It works like a charm :)

Related

Stop execute ajax in for loop

I'm trying to do the following. Get number of pages from the API. Each page has multiple results. I check all the results with my condition. If the result fits the condition, then I need to finish the check, finish the page search and pass the result to another function. I don't understand how to end ajax (getData() execution in the checkPages() function) and exit the for loop in the same place. The break and return keywords do not help. Please tell me how to do it. Maybe I need to do to refactor my code. I don't really like to "throw" results from a function into a function. I do not use async/await because I need compatibility with old browsers.
getData("url-to-get-data").done(function (result) {
checkPages(result.total_pages);
});
function getData(url) {
return $.get({
url: "url-to-get-data"
})
}
function checkPages(pagesCount) {
for (var i = 2; i <= pagesCount; i++) {
getData("url-to-get-data", i).done(function(result) {
var today = checkToday(result);
if (today != null) {
//someMethod
//how to end the getData function and the for loop
}
});
}
}
function checkToday(response) {
var results = response.results;
var today = new Date();
var day = today.getDate();
var month = today.getMonth();
for (var i = 0; i < results.length; i++) {
var d = new Date(results[i].release_date);
if (d.getDate() === day && d.getMonth() === month) {
return results[i];
}
}
return null;
}
simplest change to your checkPages function
inner function that calls itself as required
function checkPages(pagesCount) {
function checkPage(i) {
if (i <= pagesCount) {
getData("url-to-get-data", i).done(function(result) {
var today = checkToday(result);
if (today == null) { // only get next page if today is null
checkPage(i+1);
}
});
}
}
checkPage(2);
}
If I understand correctly you are trying to do something like this?
UPDATE: implemented que to check if request is finsihed
getData("url-to-get-data").done(function (result) {
checkPages(result.total_pages);
});
function getData(url) {
return $.get({
url: "url-to-get-data"
})
}
function checkPages(pagesCount) {
let doContinue = true;
let loading = false;
let i = 2;
var checker = setTimeout(()=>{
if(i > pagesCount) clearTimeout(checker);
if(!loading){
loading = true;
getData("url-to-get-data", i).done(function(result) {
var today = checkToday(result);
if (today != null) {
clearTimeout(checker);
}
i++;
loading = false;
});
}
},100);
}
function checkToday(response) {
var results = response.results;
var today = new Date();
var day = today.getDate();
var month = today.getMonth();
for (var i = 0; i < results.length; i++) {
var d = new Date(results[i].release_date);
if (d.getDate() === day && d.getMonth() === month) {
return results[i];
}
}
return null;
}
Make your ajax call synchronous or use callback functions to keep getting more data until conditions are met.

value is not added to multidimensional array

The first time the function fires I get this result:
output1:test
The output2 2 alert is not firing. I know something is probably undefined in alert Does anyone know why the value won't be added in the multidimensional array?
I expect this to display after the false1:
output2:test2
Also if you want to fiddle with the code here it is:
https://jsfiddle.net/ndf0sjgf/1/
var carSelectedArray = [
[null]
];
addRow(carSelectedArray);
addRow(carSelectedArray);
function addRow(carSelectedArray) {
var arrayempty = false;
if (carSelectedArray[0][0] == null || carSelectedArray.length == 0) {
arrayempty = true;
} else {
arrayempty = false;
}
if (arrayempty == true) {
carSelectedArray[0][0] = "test";
alert("output1:" + carSelectedArray[0][0]);
} else {
carSelectedArray[1][0] = "test2";
alert("output2:" + carSelectedArray[1][0]);
}
}
Your loop works well, however your didn't define your array well.
there is only 1 dimension here :
var carSelectedArray = [[null]];
So replace with this :
var carSelectedArray = [[],[]];
PS : null is not required
and at the beginning in your function, you define arrayempty to false, so you can remove this :
else {
arrayempty = false;
}
Solution here : https://plnkr.co/edit/Qikalr0jc54R3MRSea4G?p=preview
var carSelectedArray = [[],[]];
addRow(carSelectedArray);
addRow(carSelectedArray);
function addRow(carSelectedArray) {
var arrayempty = false;
if (carSelectedArray[0][0] == null || carSelectedArray.length == 0) {
arrayempty = true;
}
if (arrayempty == true) {
carSelectedArray[0][0] = "test";
alert("output1:" + carSelectedArray[0][0]);
} else {
carSelectedArray[1][0] = "test2";
alert("output2:" + carSelectedArray[1][0]);
}
}

Filter by numerical range, custom filter - AngularJS

I am trying to create a filter for AngularJS data. I have 2 inputs, minAgeInput and maxAgeInput.
I would like to return all products/objects (with ng-repeat), where the product's minAge and maxAge are within the boundaries set by the input values.
My filter function looks like this:
or link to Plunker
$scope.ageRange = function (plane) {
var minAgeProduct = parseFloat(product.minAge);
var maxAgeProduct = parseFloat(product.maxAge);
var minAgeInput = parseFloat($scope.minAge);
var maxAgeInput = parseFloat($scope.maxAge);
if(minAgeInput >= minAgeProduct) {
if(maxAgeInput <= maxAgeProduct) {
return true;
} else {
return false;
}
return true;
} else {
return false;
}
};
Here is the functional solution to the question:
$scope.ageRange = function (plane) {
var minAgeProduct = parseFloat(plane.minAge);
var maxAgeProduct = parseFloat(plane.maxAge);
var minAgeInput = parseFloat($scope.minAge);
var maxAgeInput = parseFloat($scope.maxAge);
if (!isNaN(minAgeInput) && maxAgeProduct < minAgeInput)
return false;
if (!isNaN(maxAgeInput) && minAgeProduct > maxAgeInput)
return false;
return true;
};
A working solution can be found here Plunker

Searching with multiple values in YDN-DB

Is it possible to find multiple value (like sql IN keyword) in YDN-DB?
//simple scenario
"SELECT * FROM categories WHERE code IN ('AB','CD','EF','GH','IJ','KL');"
var code = "'AB','CD','EF','GH','IJ','KL'";
var key_range = ydn.db.KeyRange.only(code);
cacheDb.values('categories','code',key_range).then(function(record){
console.log(record);
},function(e){
console.log(e);
});
You can use multi query approach, as described in recently updated tutorial.
Basically, you will create iterator for each element of IN clause and join (union) the result, as follow:
var keys = [];
var multiQuery = function(sec_keys, pri_keys) {
var advance = [];
var cmp = ydn.db.cmp(pri_keys[0], pri_keys[1]);
if (cmp == 1) { // pri_keys[0] > pri_keys[1]
if (keys[keys.length - 1] != pri_keys[1]) {
keys.push(pri_keys[1]);
}
advance[1] = true; // advance iter_1 on step
} else if (cmp == -1) { // pri_keys[0] < pri_keys[1]
if (keys[keys.length - 1] != pri_keys[0]) {
keys.push(pri_keys[0]);
}
advance[1] = true; // advance iter_1 on step
} else { // pri_keys[0] == pri_keys[1]
if (keys[keys.length - 1] != pri_keys[0]) {
keys.push(pri_keys[0]);
}
advance[0] = true; // advance iter_0 on step
advance[1] = true; // advance iter_1 on step
}
if (keys.length >= 10) {
return [];
} else {
return advance;
}
};
Then use scan method:
db.scan(multiQuery, [iterators...]).done(function() {
db.values('article', keys).done(function(values) {
console.log(keys, values);
})
});

Converting dates in JavaScript

How can I convert one date format to another format in JavaScript?
Example:
the old format is
YYYY/MM/DD
but I want to convert it into
DD-MM-YYYY
I think you can use jQuery UI library's datepicker: use the parseDate method to convert a string to a Date object, and then formatDate to convert the Date object to another string. Check the samples provided on the site; they include format modifiers.
Here -
// Utility function to append a 0 to single-digit numbers
Date.LZ = function(x) {return(x<0||x>9?"":"0")+x};
// Full month names. Change this for local month names
Date.monthNames = new Array('January','February','March','April','May','June','July','August','September','October','November','December');
// Month abbreviations. Change this for local month names
Date.monthAbbreviations = new Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');
// Full day names. Change this for local month names
Date.dayNames = new Array('Sunday','Monday','Tuesday','Wednesday','Thursday','Friday','Saturday');
// Day abbreviations. Change this for local month names
Date.dayAbbreviations = new Array('Sun','Mon','Tue','Wed','Thu','Fri','Sat');
// Used for parsing ambiguous dates like 1/2/2000 - default to preferring 'American' format meaning Jan 2.
// Set to false to prefer 'European' format meaning Feb 1
Date.preferAmericanFormat = true;
// If the getFullYear() method is not defined, create it
if (!Date.prototype.getFullYear) {
Date.prototype.getFullYear = function() { var yy=this.getYear(); return (yy<1900?yy+1900:yy); } ;
}
// Parse a string and convert it to a Date object.
// If no format is passed, try a list of common formats.
// If string cannot be parsed, return null.
// Avoids regular expressions to be more portable.
Date.parseString = function(val, format) {
// If no format is specified, try a few common formats
if (typeof(format)=="undefined" || format==null || format=="") {
var generalFormats=new Array('y-M-d','MMM d, y','MMM d,y','y-MMM-d','d-MMM-y','MMM d','MMM-d','d-MMM');
var monthFirst=new Array('M/d/y','M-d-y','M.d.y','M/d','M-d');
var dateFirst =new Array('d/M/y','d-M-y','d.M.y','d/M','d-M');
var checkList=new Array(generalFormats,Date.preferAmericanFormat?monthFirst:dateFirst,Date.preferAmericanFormat?dateFirst:monthFirst);
for (var i=0; i<checkList.length; i++) {
var l=checkList[i];
for (var j=0; j<l.length; j++) {
var d=Date.parseString(val,l[j]);
if (d!=null) {
return d;
}
}
}
return null;
};
this.isInteger = function(val) {
for (var i=0; i < val.length; i++) {
if ("1234567890".indexOf(val.charAt(i))==-1) {
return false;
}
}
return true;
};
this.getInt = function(str,i,minlength,maxlength) {
for (var x=maxlength; x>=minlength; x--) {
var token=str.substring(i,i+x);
if (token.length < minlength) {
return null;
}
if (this.isInteger(token)) {
return token;
}
}
return null;
};
val=val+"";
format=format+"";
var i_val=0;
var i_format=0;
var c="";
var token="";
var token2="";
var x,y;
var year=new Date().getFullYear();
var month=1;
var date=1;
var hh=0;
var mm=0;
var ss=0;
var ampm="";
while (i_format < format.length) {
// Get next token from format string
c=format.charAt(i_format);
token="";
while ((format.charAt(i_format)==c) && (i_format < format.length)) {
token += format.charAt(i_format++);
}
// Extract contents of value based on format token
if (token=="yyyy" || token=="yy" || token=="y") {
if (token=="yyyy") {
x=4;y=4;
}
if (token=="yy") {
x=2;y=2;
}
if (token=="y") {
x=2;y=4;
}
year=this.getInt(val,i_val,x,y);
if (year==null) {
return null;
}
i_val += year.length;
if (year.length==2) {
if (year > 70) {
year=1900+(year-0);
}
else {
year=2000+(year-0);
}
}
}
else if (token=="MMM" || token=="NNN"){
month=0;
var names = (token=="MMM"?(Date.monthNames.concat(Date.monthAbbreviations)):Date.monthAbbreviations);
for (var i=0; i<names.length; i++) {
var month_name=names[i];
if (val.substring(i_val,i_val+month_name.length).toLowerCase()==month_name.toLowerCase()) {
month=(i%12)+1;
i_val += month_name.length;
break;
}
}
if ((month < 1)||(month>12)){
return null;
}
}
else if (token=="EE"||token=="E"){
var names = (token=="EE"?Date.dayNames:Date.dayAbbreviations);
for (var i=0; i<names.length; i++) {
var day_name=names[i];
if (val.substring(i_val,i_val+day_name.length).toLowerCase()==day_name.toLowerCase()) {
i_val += day_name.length;
break;
}
}
}
else if (token=="MM"||token=="M") {
month=this.getInt(val,i_val,token.length,2);
if(month==null||(month<1)||(month>12)){
return null;
}
i_val+=month.length;
}
else if (token=="dd"||token=="d") {
date=this.getInt(val,i_val,token.length,2);
if(date==null||(date<1)||(date>31)){
return null;
}
i_val+=date.length;
}
else if (token=="hh"||token=="h") {
hh=this.getInt(val,i_val,token.length,2);
if(hh==null||(hh<1)||(hh>12)){
return null;
}
i_val+=hh.length;
}
else if (token=="HH"||token=="H") {
hh=this.getInt(val,i_val,token.length,2);
if(hh==null||(hh<0)||(hh>23)){
return null;
}
i_val+=hh.length;
}
else if (token=="KK"||token=="K") {
hh=this.getInt(val,i_val,token.length,2);
if(hh==null||(hh<0)||(hh>11)){
return null;
}
i_val+=hh.length;
hh++;
}
else if (token=="kk"||token=="k") {
hh=this.getInt(val,i_val,token.length,2);
if(hh==null||(hh<1)||(hh>24)){
return null;
}
i_val+=hh.length;
hh--;
}
else if (token=="mm"||token=="m") {
mm=this.getInt(val,i_val,token.length,2);
if(mm==null||(mm<0)||(mm>59)){
return null;
}
i_val+=mm.length;
}
else if (token=="ss"||token=="s") {
ss=this.getInt(val,i_val,token.length,2);
if(ss==null||(ss<0)||(ss>59)){
return null;
}
i_val+=ss.length;
}
else if (token=="a") {
if (val.substring(i_val,i_val+2).toLowerCase()=="am") {
ampm="AM";
}
else if (val.substring(i_val,i_val+2).toLowerCase()=="pm") {
ampm="PM";
}
else {
return null;
}
i_val+=2;
}
else {
if (val.substring(i_val,i_val+token.length)!=token) {
return null;
}
else {
i_val+=token.length;
}
}
}
// If there are any trailing characters left in the value, it doesn't match
if (i_val != val.length) {
return null;
}
// Is date valid for month?
if (month==2) {
// Check for leap year
if ( ( (year%4==0)&&(year%100 != 0) ) || (year%400==0) ) { // leap year
if (date > 29){
return null;
}
}
else {
if (date > 28) {
return null;
}
}
}
if ((month==4)||(month==6)||(month==9)||(month==11)) {
if (date > 30) {
return null;
}
}
// Correct hours value
if (hh<12 && ampm=="PM") {
hh=hh-0+12;
}
else if (hh>11 && ampm=="AM") {
hh-=12;
}
return new Date(year,month-1,date,hh,mm,ss);
};
// Check if a date string is valid
Date.isValid = function(val,format) {
return (Date.parseString(val,format) != null);
};
// Check if a date object is before another date object
Date.prototype.isBefore = function(date2) {
if (date2==null) {
return false;
}
return (this.getTime()<date2.getTime());
};
// Check if a date object is after another date object
Date.prototype.isAfter = function(date2) {
if (date2==null) {
return false;
}
return (this.getTime()>date2.getTime());
};
// Check if two date objects have equal dates and times
Date.prototype.equals = function(date2) {
if (date2==null) {
return false;
}
return (this.getTime()==date2.getTime());
};
// Check if two date objects have equal dates, disregarding times
Date.prototype.equalsIgnoreTime = function(date2) {
if (date2==null) {
return false;
}
var d1 = new Date(this.getTime()).clearTime();
var d2 = new Date(date2.getTime()).clearTime();
return (d1.getTime()==d2.getTime());
};
// Format a date into a string using a given format string
Date.prototype.format = function(format) {
format=format+"";
var result="";
var i_format=0;
var c="";
var token="";
var y=this.getYear()+"";
var M=this.getMonth()+1;
var d=this.getDate();
var E=this.getDay();
var H=this.getHours();
var m=this.getMinutes();
var s=this.getSeconds();
var yyyy,yy,MMM,MM,dd,hh,h,mm,ss,ampm,HH,H,KK,K,kk,k;
// Convert real date parts into formatted versions
var value=new Object();
if (y.length < 4) {
y=""+(+y+1900);
}
value["y"]=""+y;
value["yyyy"]=y;
value["yy"]=y.substring(2,4);
value["M"]=M;
value["MM"]=Date.LZ(M);
value["MMM"]=Date.monthNames[M-1];
value["NNN"]=Date.monthAbbreviations[M-1];
value["d"]=d;
value["dd"]=Date.LZ(d);
value["E"]=Date.dayAbbreviations[E];
value["EE"]=Date.dayNames[E];
value["H"]=H;
value["HH"]=Date.LZ(H);
if (H==0){
value["h"]=12;
}
else if (H>12){
value["h"]=H-12;
}
else {
value["h"]=H;
}
value["hh"]=Date.LZ(value["h"]);
value["K"]=value["h"]-1;
value["k"]=value["H"]+1;
value["KK"]=Date.LZ(value["K"]);
value["kk"]=Date.LZ(value["k"]);
if (H > 11) {
value["a"]="PM";
}
else {
value["a"]="AM";
}
value["m"]=m;
value["mm"]=Date.LZ(m);
value["s"]=s;
value["ss"]=Date.LZ(s);
while (i_format < format.length) {
c=format.charAt(i_format);
token="";
while ((format.charAt(i_format)==c) && (i_format < format.length)) {
token += format.charAt(i_format++);
}
if (typeof(value[token])!="undefined") {
result=result + value[token];
}
else {
result=result + token;
}
}
return result;
};
// Get the full name of the day for a date
Date.prototype.getDayName = function() {
return Date.dayNames[this.getDay()];
};
// Get the abbreviation of the day for a date
Date.prototype.getDayAbbreviation = function() {
return Date.dayAbbreviations[this.getDay()];
};
// Get the full name of the month for a date
Date.prototype.getMonthName = function() {
return Date.monthNames[this.getMonth()];
};
// Get the abbreviation of the month for a date
Date.prototype.getMonthAbbreviation = function() {
return Date.monthAbbreviations[this.getMonth()];
};
// Clear all time information in a date object
Date.prototype.clearTime = function() {
this.setHours(0);
this.setMinutes(0);
this.setSeconds(0);
this.setMilliseconds(0);
return this;
};
// Add an amount of time to a date. Negative numbers can be passed to subtract time.
Date.prototype.add = function(interval, number) {
if (typeof(interval)=="undefined" || interval==null || typeof(number)=="undefined" || number==null) {
return this;
}
number = +number;
if (interval=='y') { // year
this.setFullYear(this.getFullYear()+number);
}
else if (interval=='M') { // Month
this.setMonth(this.getMonth()+number);
}
else if (interval=='d') { // Day
this.setDate(this.getDate()+number);
}
else if (interval=='w') { // Weekday
var step = (number>0)?1:-1;
while (number!=0) {
this.add('d',step);
while(this.getDay()==0 || this.getDay()==6) {
this.add('d',step);
}
number -= step;
}
}
else if (interval=='h') { // Hour
this.setHours(this.getHours() + number);
}
else if (interval=='m') { // Minute
this.setMinutes(this.getMinutes() + number);
}
else if (interval=='s') { // Second
this.setSeconds(this.getSeconds() + number);
}
return this;
};
Copy this to a .js file, and include it in your page.
Then you can use the format() method on the Date object.
You can also find another library here.
My date extensions will do that well - they also parses data formats and does a lot of date math/compares as well:
DP_DateExtensions Library
Not sure if it'll help, but I've found it invaluable in several projects. The date functions are (mostly) based on CFML (if that matters).
I'm not saying that they're better than the other options given - but I am proud of them and it never (well... almost never) hurts to be spoilt for choice.
If you don't use jQuery (and I can't think why, but just in case), I have created a patch for the Javascript Date object which will allow you to both parse dates from strings in different formats and convert dates to strings in different formats.
You can see more info on Javascript Date Formatter article on my blog.
My answer is very late but I think following solution is simple and effective for this question. This works for me always.
Here you go :
function dateToYMD(date) {
var d = date.getDate();
var m = date.getMonth() + 1;
var y = date.getFullYear();
return ''+ (d <= 9 ? '0' + d : d) + '-' + (m<=9 ? '0' + m : m) + '-' + y ;
}

Categories

Resources