Get the minimum and maximum dates from JSON - javascript

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;

Related

Find the closest hour [javascript]

I have a list of these items:
hours = ['19:30', '20:10', '20:30', '21:00', '22:00']
Assuming that now it's 20:18, how can I get the '20:10' item from the list? I want to use this to find the currently running show in a TV Guide.
First we should parse it to datetime in some way:
function parseTime(str) {
var values = str.split(':');
var hour = parseInt(values[0]);
var minutes = parseInt(values[1]);
var d = new Date();
d.setHours(hour);
d.setMinutes(minutes);
return d;
}
var now = new Date();
var bestMatch = undefined;
var bestMatchDiff = undefined;
And finally:
for(var i=0; i<hours.length; i++) {
var parsedTime = parseTime(hours[i]);
var diff = Math.abs(now - parsedTime);
if (!bestMatchDiff || bestMatchDiff>diff) {
bestMatch = parsedTime;
bestMatchDiff = diff;
}
}
bestMatch would be the closest time. This is not the currently running show now. For that, you need to ignore times that are yet to come:
for(var i=0; i<hours.length; i++) {
var parsedTime = parseTime(hours[i]);
var diff = Math.abs(now - parsedTime);
if (now<parsedTime) {
continue;
}
if (!bestMatchDiff || bestMatchDiff>diff) {
bestMatch = parsedTime;
bestMatchDiff = diff;
}
}
But keep in mind this might return undefined even if your list is not empty.
var hours = ['19:30', '20:10', '20:30', '21:00', '22:00']
var diffrenceTime
var selectedShow
var d1 = new Date()
var currentHH = 20
var currentMM = 18
d1.setHours(currentHH, currentMM, 0)
hours.forEach(v => {
var d2 = new Date()
var hh = v.split(':')[0]
var mm = v.split(':')[1]
d2.setHours(hh, mm, 0)
if (diffrenceTime == undefined) {
diffrenceTime = d2 - d1
selectedShow = v
}
if (d2 - d1 < 0 && d2 - d1 >= diffrenceTime) {
diffrenceTime = d2 - d1
selectedShow = v
}
})
console.log(selectedShow)
To find the currently running show (of course more validations need to be added):
const currentShow = hours[
hours.findIndex(
(c) => new Date(`01/01/2000 ${c}`) - new Date(`01/01/2000 20:31`) >= 0
) - 1
];
To find the next show:
const nextShow = hours.find(
(c) => new Date(`01/01/2000 ${c}`) - new Date(`01/01/2000 20:31`) >= 0
);
Well, you could do something like this
var originalArray = ['19:30', '20:10', '20:30', '21:00', '22:00'];
var newArray = originalArray.map(i=>{
return i.split(":")
})
newArray.forEach((k, idx)=>{newArray[idx] = parseInt(k[0]) + parseInt(k[1])/60})
console.log(newArray);
var time = "20:18".split(':');
var t = parseInt(time[0])+ parseInt(time[1])/60;
console.log(t);
var closestTimeIndex = 0, closestDistance = Math.abs(t-newArray[closestTimeIndex]);
for(var m=1; m<newArray.length;m++){
if(Math.abs(newArray[m]-t) < closestDistance){
closestDistance = Math.abs(newArray[m]-t);
closestTimeIndex = m;
}
}
console.log("colsest time is: " + originalArray[closestTimeIndex]);

Meteor + MongoDB : Check if date is in range

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".

Sort a string date array

I want to sort an array in ascending order. The dates are in string format
["09/06/2015", "25/06/2015", "22/06/2015", "25/07/2015", "18/05/2015"]
Even need a function to check whether these dates are in continuous form:
eg - Valid - ["09/06/2015", "10/06/2015", "11/06/2015"]
Invalid - ["09/06/2015", "25/06/2015", "22/06/2015", "25/07/2015"]
Example code:
function sequentialDates(dates){
var temp_date_array = [];
$.each(dates, function( index, date ) {
//var date_flag = Date.parse(date);
temp_date_array.push(date);
});
console.log(temp_date_array);
var last;
for (var i = 0, l = temp_date_array.length; i < l; i++) {
var cur = new Date();
cur.setTime(temp_date_array[i]);
last = last || cur;
//console.log(last+' '+cur);
if (isNewSequence(cur, last)) {
console.log("Not Sequence");
}
}
//return dates;
}
function isNewSequence(a, b) {
if (a - b > (24 * 60 * 60 * 1000))
return true;
return false;
}
The Simple Solution
There is no need to convert Strings to Dates or use RegExp.
The simple solution is to use the Array.sort() method. The sort function sets the date format to YYYYMMDD and then compares the string value. Assumes date input is in format DD/MM/YYYY.
data.sort(function(a,b) {
a = a.split('/').reverse().join('');
b = b.split('/').reverse().join('');
return a > b ? 1 : a < b ? -1 : 0;
// return a.localeCompare(b); // <-- alternative
});
Update:
A helpful comment suggested using localeCompare() to simplify the sort function. This alternative is shown in the above code snippet.
Run Snippet to Test
<!doctype html>
<html>
<body style="font-family: monospace">
<ol id="stdout"></ol>
<script>
var data = ["09/06/2015", "25/06/2015", "22/06/2015", "25/07/2015", "18/05/2015"];
data.sort(function(a,b) {
a = a.split('/').reverse().join('');
b = b.split('/').reverse().join('');
return a > b ? 1 : a < b ? -1 : 0;
// return a.localeCompare(b); // <-- alternative
});
for(var i=0; i<data.length; i++)
stdout.innerHTML += '<li>' + data[i];
</script>
</body>
</html>
You will need to convert your strings to dates, and compare those dates, if you want to sort them. You can make use of the parameter that the sort method accepts, in order to achieve this:
var dateStrings = ["09/06/2015", "25/06/2015", "22/06/2015", "25/07/2015", "18/05/2015"];
var sortedStrings = dateStrings.sort(function(a,b) {
var aComps = a.split("/");
var bComps = b.split("/");
var aDate = new Date(aComps[2], aComps[1], aComps[0]);
var bDate = new Date(bComps[2], bComps[1], bComps[0]);
return aDate.getTime() - bDate.getTime();
});
In order to reduce code redundancy, and to handle different date formats, you can add an additional function that will create the comparator needed by the sort method:
function createSorter(dateParser) {
return function(a, b) {
var aDate = dateParser(a);
var bDate = dateParser(b);
return aDate.getTime() - bDate.getTime();
};
}
dateStrings.sort(createSorter(function(dateString) {
var comps = dateString.split("/");
return new Date(comps[2], comps[1], comps[0]);
}));
You can then use different date formatters by passing different functions to the createSorter call.
As for your second question, you can create an (sorted) array of dates from your strings, and perform your logic on that array:
function myDateParser(dateString) {
var comps = dateString.split("/");
return new Date(comps[2], comps[1], comps[0]);
}
var sortedDates = dateStrings.map(myDateParser).sort();
You can walk through the sortedDates array and if you find two non-consecutive dates, then you have dates with gaps between them.
var dateRE = /^(\d{2})[\/\- ](\d{2})[\/\- ](\d{4})/;
function dmyOrdA(a, b){
a = a.replace(dateRE,"$3$2$1");
b = b.replace(dateRE,"$3$2$1");
if (a>b) return 1;
if (a <b) return -1;
return 0; }
function dmyOrdD(a, b){
a = a.replace(dateRE,"$3$2$1");
b = b.replace(dateRE,"$3$2$1");
if (a>b) return -1;
if (a <b) return 1;
return 0; }
function mdyOrdA(a, b){
a = a.replace(dateRE,"$3$1$2");
b = b.replace(dateRE,"$3$1$2");
if (a>b) return 1;
if (a <b) return -1;
return 0; }
function mdyOrdD(a, b){
a = a.replace(dateRE,"$3$1$2");
b = b.replace(dateRE,"$3$1$2");
if (a>b) return -1;
if (a <b) return 1;
return 0; }
dateArray = new Array("09/06/2015", "25/06/2015", "22/06/2015", "25/07/2015", "18/05/2015");
var c = dateArray.sort( dmyOrdA );
console.log(c);
To sort your date string ascendingly without alteration to its value, try this:
var T = ["09/06/2015", "25/06/2015", "22/06/2015", "25/07/2015", "18/05/2015"];
var sortedT = T.sort(s1,s2){
var sdate1 = s1.split('/');
var sdate2 = s2.split('/');
var date1 = s1[1]+'/'+s1[0]+'/'+s1[2];
var date2 = s2[1]+'/'+s2[0]+'/'+s2[2];
if (Date.parse(date1) > Date.parse(date2)) return 1;
else if (Date.parse(date1) < Date.parse(date2) return -1;
else return 0;
}
The resultant array sortedT should be a sorted array of date string.
NOTE:
Your date format is stored in dd/mm/yyyy but the standard date format of JavaScript is mm/dd/yyyy. Thus, in order to parse this string to Date without using external date format library, the date string is therefore needed to be converted for compatibility during sort.

how to calculate values of an (javascript) object with date keys

I have the following simplified (javascript) object, of which properties are dates (in string fomat):
Given a random startdate and enddate within the range of dates in the object, how to code (efficiently) the calculation - say accumulate- of the values within this range? As an example, for the following code the calculation result should be 12 (3+4+5) for the given startdate and enddate.
var startdate = '2014-01-03';
var enddate = '2014-01-05'
var obj = {};
obj['2014-01-02'] = '2';
obj['2014-01-03'] = '3';
obj['2014-01-04'] = '4';
obj['2014-01-05'] = '5';
obj['2014-01-06'] = '6';
You can just loop through the properties of the object, doing a comparison, and adding.
var startdate = '2014-01-04';
var enddate = '2014-01-05';
var arr = {};
arr['2014-01-02'] = '2';
arr['2014-01-03'] = '3';
arr['2014-01-04'] = '4';
arr['2014-01-05'] = '5';
arr['2014-01-06'] = '6';
var total = 0;
for(var p in arr) {
if(arr.hasOwnProperty(p)) {
if(new Date(p) >= new Date(startdate) && new Date(p) <= new Date(enddate)) {
total += parseInt(arr[p], 10);
}
}
}
console.log(total);
Sample http://jsbin.com/imUdewaJ/1/edit
I'm sure there is a better way to do this, but I don't know how due to having to parse the date object out for comparison.
--Edit added in the hasOwnProperty check from comments below
When doing stuff with dates, you might want to use thirdparty tools to handle browser compatibility. Momentjs is a good one for dates.
solution with momentjs:
var startdate = moment('2014-01-03');
var enddate = moment('2014-01-05');
var obj = {};
obj['2014-01-02'] = '2';
obj['2014-01-03'] = '3';
obj['2014-01-04'] = '4';
obj['2014-01-05'] = '5';
obj['2014-01-06'] = '6';
var strDate;
var total = 0;
for (strDate in obj) {
if (obj.hasOwnProperty(strDate)) {
var date = moment(strDate)
if (date.diff(startdate, 'days')>=0 && date.diff(enddate, 'days')<=0) {
total += parseInt(obj[strDate], 10);
}
}
}
console.log(total);
It's possible that some browsers won't support date1 > date2, so it might be better to also use getTime().
function getDate(date) {
return new Date(date).getTime();
}
function getTotal(start, end) {
var total = 0;
for (var k in obj) {
var current = getDate(k);
if (current >= start && current <= end) {
total += parseInt(obj[k], 10);
}
}
return total;
}
var start = getDate(startdate);
var end = getDate(enddate);
console.log(getTotal(start, end)); // 12

How to compare two different dates in dd/mm/yyyy format

Can anyone help me in finding the solution
i just want to compare two dates in dd/mm/yyyy format.
function compareDate(dt1 , dt2 , formatString){var returnVal = 2;
var dt1Parts;
var dt2Parts;
var dt1dd;
var dt1mm;
var dt1yyyy;
var dt2dd;
var dt2mm;
var dt2yyyy;
if(formatString == 'dd/mm/yyyy'){
dt1Parts = dt1.split('/');
dt2Parts = dt2.split('/');
dt1dd = parseInt(dt1Parts[0]);
dt1mm = parseInt(dt1Parts[1]);
dt1yyyy = parseInt(dt1Parts[2]);
dt2dd = parseInt(dt2Parts[0]);
dt2mm = parseInt(dt2Parts[1]);
dt2yyyy = parseInt(dt2Parts[2]);
}
else if(formatString == 'dd-mm-yyyy'){
dt1Parts = dt1.split('-');
dt2Parts = dt2.split('-');
dt1dd = parseInt(dt1Parts[0]);
dt1mm = parseInt(dt1Parts[1]);
dt1yyyy = parseInt(dt1Parts[2]);
dt2dd = parseInt(dt2Parts[0]);
dt2mm = parseInt(dt2Parts[1]);
dt2yyyy = parseInt(dt2Parts[2]);
}else{
alert(formatString+' format is not supported.');
}
if(dt1yyyy == dt2yyyy && dt1mm == dt2mm && dt1dd == dt2dd){
returnVal = 0;
}
else if(dt1yyyy > dt2yyyy){
returnVal = 1 ;
}else if(dt1yyyy == dt2yyyy ){
if(dt1mm > dt2mm){
returnVal = 1;
}else if(dt1mm == dt2mm){
if(dt1dd > dt2dd){
returnVal = 1;
}else{
returnVal = -1;
}
}else{
returnVal = -1;
}
}else{
returnVal = -1;
}
return returnVal;
}
Thanks in advance,
Shilpa
Invert the strings to yyyy/mm/dd, or convert them to a number or Date object.
The simplest way just for comparison would be ASCII order. Invert using something like this:
function invert(date) {
return date.split(/[/-]/).reverse().join("")
}
function compareDates(date1, date2) {
return invert(date1).localeCompare(invert(date2));
}
Here's how you convert that string format to a date:
var myString = "17/07/1979",
correctFormat = myString.replace(/(\d+)\/(\d+)\/(\d+)/, "$3/$2/$1"),
myDate = new Date(correctFormat);
Without knowing what language or class libs you're working with:
Method 1: Resort your strings to be yyyymmdd and the do string compare.
Method 2: Stuff yyyy mm and dd into the high, middle, and low bits of an integer and compare.
The easiest way is probably to create 2 javascript Date objects from your input string. You could achieve that by chopping your input into day, month and year. You can use the 'substring' function for that.
Then you can do:
var firstDate = new Date(year1, month1, day1);
var secondDate = new Date(year2, month2, day2);
Once you have 2 date objects, you can use the normal compare operators:
if (firstDate > secondDate)
// do something
else
...
Try this
var date1=new Date('your date1 string');
var date2=new Date('your date2 string');
var difference=new Date(date1.getTime()-date2.getTime());
if ($.datepicker.parseDate('dd/mm/yy', fDate) > $.datepicker.parseDate('dd/mm/yy', tDate)) {
//do something
}
You can compare two dates.Here I compare from date greater than to date
try this

Categories

Resources