How do I compare a JSON date string to javascript string? - javascript

I'm trying to compare two time values, I am creating a new date variable in jS and then passing this down to Memberstack in JSON (this works). I am then calling the data when the page reloads and pulling the value back from Memberstack to compare the dates between the first load and second load.
Here is my code:
// Run timer. //
function runTimer() {
MemberStack.onReady.then(async function(member) {
var metadata = await member.getMetaData() // <------ call the initial date value from Memberstack
if (metadata.startDate != null) {
var initiatedDate = metadata["startDate"]; // <------ the initial date value
var referenceDate = currentDate; // <------ the second date value to compare to
var calcDifference = referenceDate.getTime() - initiatedDate.getTime(); // <------ errors here
var calcDifferenceD = calcDifference / (1000 * 3600 * 24);
alert(calcDifference);
}
})
}
// End run timer. //
When I try to debug this in console I see the following:
When I run initiatedDate.getTime(); on line 83, I'm getting this error:
Uncaught (in promise) TypeError: initiatedDate.getTime is not a function
I need to make lines 81 and 82 match so that I can compare them, can anyone help me compare these two dates?

Right here is the answer to your question.
Your initiatedDate is not an object, but a string, hence .getTime does not exist. So you should convert your string to a Date object.
This is how you can do it:
var initiatedDate = new Date(metadata['startDate'])
And then your initiatedDate will have the .getTime method and there's not going to be an error.

Related

.diff is not a function in Moment.js

I'm trying to get the difference between two dates, but I'm getting the response: Uncaught TypeError: x.diff is not a function
On other topics I've seen I have to create a moment object, but for as far as I know, I'm doing that.
Code:
function datecheck(){
var y = moment($("#input_pickup_date").val(),"L").format("L");
var x = moment().format("L");
console.log(x.diff(y, 'days'));
}
Via the docs, moment().format() returns a String, so your x and y variables are both Strings. If you need to both do calculations on and display the values, separate them out into different variables:
function datecheck() {
var dateSubmitted = moment($("#input_pickup_date").val(), "L"), //your old x variable
now = moment(), //your old y variable
dateSubmittedDisplay = dateSubmitted.format("L"), //a string representing the submitted date in the format you wanted.
nowDisplay = now.format("L"); //a string representing now in the format you wanted.
console.log(x.diff(y, 'days'));
}

Datetime array to array with dates, get corresponding time afterwards

Specific situation.. I'm having an array filled with datetimes I pull in via an api.
Users should be able to select a date from a datepicker (only showing dates available in the array) and afterwards see the corresponding time.
So what I've done..
The original array is obtained via php, so before starting to populate the datepicker with possible dates I create an extra array with dates only.
Since I maintain the key's it's possible to put these 2 arrays next to eachother.
Array looks as following:
["8-8-2017,07:00", "26-8-2017,07:00"];
So far so good...
After a user picks a date I trigger this to be able to start digging for the time corresponding that date.
Now it's getting messy...
$('#datepick').datepicker().on("input change", function(e) {
$("#uur").text('');
var selecteddate = e.target.value;
var searchArr = datesArray;
var ind = searchArr.indexOf(selecteddate.toString());
var result = datesArray.filter(function(item) {
return typeof item == 'string' && item.indexOf(selecteddate.toString()) > -1;
});
var afterComma = result.toString().substr(result.toString().indexOf(",") + 1);
var final = afterComma.replace(":", "u");
$("#uur").text("De warming up party gaat van start rond " + final);
});
The result is that this only works on the last element of the array.
Because I'm splitting based on the comma's. Now I know the easiest way to work arround this would be to change the , that's seperating date and time in another symbol but still I'm wondering why this couldn't be easier.
You convert whole array to string every time. You should change following code:
var afterComma = result.toString().substr(result.toString().indexOf(",") + 1);
To this;
var afterComma = item.toString().substr(item.toString().indexOf(",") + 1);
Edit:
I also missed the loop above
//for every item in result, afterComma will refer to related minute string
for (var item in result) {
var afterComma = item.toString().substr(item.toString().indexOf(",") + 1);
// Do rest here
}

Why is my custom validation in Angular2 not working

Here are two angular2 custom validations that I wrote, the first one validateAge works, but the second one validateDob does not ... the difference is the validateAge uses the component that I am on and is a text based field, the second one needs to use a Date Entry field and find the difference between today's date and the birthdate to find the actual age and then measure it against the age field. but something is not right ... any ideas
function validateAge(control: FormControl): { [s: string]: boolean } {
if (parseInt(control.value) <= 0) {
return {invalidAge: true};
}
}
function validateDob(control: FormControl): {[s:string]: boolean}{
var today = new Date();
var calcAge = today - control.value;
if (calcAge != parseInt([{age}]) ){
return {invalidDate: true}
}
}
The issue you have here is that your control.value is not a Date object, but rather the string representation.
var today = new Date();
Difference in milliseconds between the current timestamp and the entered value
var diff = today - new Date(control.value);
divide by ms per year and take the floor
var calcAge = Math.floor(diff/ (1000*60*60*24*365)));
Now do whatever comparison you need against the appropriate value. You didn't show us what your age object is so I don't actually know what comparison you're looking for.
if (calcAge < someAgeThreshold) ){
return {invalidDate: true}
} else {
return null;
}
Also note that with custom validation the validator returns no error when you return null and anything with a value is considered to have an error.

Trying to add to dateTime in sheets

function getFirstEmptyRow() {
var spr = SpreadsheetApp.getActiveSpreadsheet();
var column = spr.getRange('A:A');
var values = column.getValues(); // get all data in one call
var ct = 0;
while ( values[ct][0] != "" ) {
ct++;
}
return (ct);
}
function getLatestTime() {
return SpreadsheetApp.getActiveSpreadsheet().getSheets()[0].getRange(getFirstEmptyRow(),1).getValue();
}
function getLatestPoints() {
return SpreadsheetApp.getActiveSpreadsheet().getSheets()[0].getRange(getFirstEmptyRow(),2).getValue();
}
function getLatestAverage() {
return SpreadsheetApp.getActiveSpreadsheet().getSheets()[0].getRange(getFirstEmptyRow(),3).getValue();
}
function daysLeft(){
var pointsLeft = 24250 - getLatestPoints();
return (pointsLeft / getLatestAverage()) / 24;
}
function nextRedeem() { //Problem is with this function:
var redeemTime = getLatestTime() + daysLeft() + (2/24);
return redeemTime;
}
In my sheet I have a list of rows with 1)a date/time 2)a point value and 3)A running average of points per hour. I am trying to write a function that figures out how much time is left before the points reach a certain number and add it to the latest time to figure out at what time I expect to have that number of points.
I have little experience with java script and weak typing. My problem is that when I try to add a number to my returned date value I either get a string or just NaN. My other problem is that sheets seems to interpret dates into a number differently than Number() does.
If my nextRedeem() function simply returns getLatestTime(), I can get sheets to show it either as a date or the number of days since 1/1/1900 or whatever it is. At that point, in a cell I can add to it. I can add getLatestTime() and daysLeft() in a cell and it works fine. I can also add the timezone offset and it works, in a cell. But when I do it in this function nothing seems to work. I have tried adding .value to the function calls and using parseFloat() but that gives me NaN.
How do I do arithmetic with these function returns?
The issue is that isn't how Dates are handled in javascript.
var redeemTime = getLatestTime().setDate( getLatestTime().getDate() + daysLeft() + 12 );
This will set the Day of the Month of your DateTime object to whatever the original date was + daysLeft(). I'm not sure what you're referring to with 2/24 (as that's always 12) but I included it in case you have some other context. If you add days over the number of days in the month, it will go into the next month, and similarly if you add negative days below 0, it will go into the previous month.
For more information on handling dates with JavaScript, see this link at W3Schools.
So Date.parse gets me half way there, but it give me milliseconds since 1/1/1970, where google is days since 12/30/1899. So I just had to use some math which I left uncomputed for clarity.
function dateToNum(date) {
return (Date.parse(date)/1000/60/60/24 + 25569)
}
Now I can use dateToNum(getLatestTime()) and do whatever math I want to it. When this number is put into a cell that is formatted to datetime it will display correctly.

How do I loop through objects and categorize by timestamps in Javascript?

I have an array of objects that have a keys called timestamp and motion. motion contains a value and timestamp contains a unix timestamp. I want to iterate over a number of the objects and find what "time of day" period they correspond to, I then want to total up the motion values for that given time of day and save the entire thing in an array of arrays. I want the duration to be changeable.
Let's say these are my objects;
{
timestamp: 1397160634,
motion: 2,
id: '534771d8c311731e21c75c9f'
},
{
timestamp: 1397160634,
motion: 3,
id: '534771d8c311731e21c75c9f'
}
Now I create my results array
var sampleDuration = 60; // Min
var minutesInDay = 1440;
var samplesPerDay = minutesInDay/sampleDuration;
var finalResultItem = []
for (var i = 0; i < samplesPerDay; i++) {
var IndividualresultArray = []
IndividualresultArray.push(60*i);
IndividualresultArray.push(0);
finalResultItem.push(IndividualresultArray);
}
I now have an array of arrays with each subarray's first item being a number (corresponding to a minute stamp) and the second value being zero.
I would now like to loop through all my objects and increment the second value (motion) based on the time of day range that is in the timestamp
_forEach(objects, function (object) {
{
// grab the timestamp
// figure out which minute range it coresponds to
// increment the array value that corresponds to the minute stamp
// rinse and repeat
}
this is where I go blank, I need the end result to look something like this
[[30, 5],[60, 20],[90, 5],[120, 0] .........]
or it could even look like this
[[000002400, 5],[000003000, 20],[000003600, 5],[000004200, 0] .........]
where the first value is a timestamp that ignores the year, month, and day, and only considers the time of day.
I have considered using moment.js in some capacity but I'm not sure how. Any help with this problem would be great.
I created a jsFiddle for you. The motion increment logic should look like (I'm using jQuery here but you get the point)
// Loop through and increment motion
$.each(objs, function (idx, obj) {
var date = new Date(obj.timestamp * 1000); // Convert to milliseconds
var minutesInDay = date.getUTCHours() * 60 + date.getUTCMinutes(); // Remove UTC for local time!
var minuteRange = Math.floor(minutesInDay / sampleDuration);
finalResultItem[minuteRange][1] += obj.motion;
});
EDIT: Removed some discussion after your edit. I also used more generic logic based on sampleDuration.
This should do it:
_forEach(objects, function (object) {
var date = new Date(objec.timestamp*1000);
var minuteOfDay = date.getUTCHours()*60+date.getUTCMinutes();
finalResultItem[minuteOfDay][1] += object.motion;
})
For a variable sample rate, employ a secondOfDay and divide that by your sampleDuration, then floor it to get your array index.

Categories