Select specific object from a JSON array - javascript

I'm working with a windows 8 app using Java Script
I'm get some rss and convert it to JSON format objects using Google API. So Then I got some sort of object array of JSON for that rss feed. I need to do is I want to select few objects among all objects of the array according to the published day. That means I want to get all objects from the array which published before 6 hours(In between current date and before 6 hours except other objects).. Can anyone help me for do that..?
I use this code for get all objects.
function loadNews() {
var allEntries = [];
var pendingRequestCount = listOfFeed.length;
var onRequestFinished = function () {
pendingRequestCount--;
if (pendingRequestCount === 0) {
processItems(allEntries);
}
};
for (var x = 0; x < listOfFeed.length; x++) {
feedburnerUrl = listOfFeed[x].url,
feedUrl = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&output=json&num=999&q=" + encodeURIComponent(feedburnerUrl);
WinJS.xhr({
url: feedUrl,
responseType: "rss/json"
}).done(function complete(result) {
var jsonData = JSON.parse(result.response);
var entries = jsonData.responseData.feed.entries;
allEntries = allEntries.concat(entries);
allEntries.sort(function (entry1, entry2) {// Compare the entries by publish date
return Date.parse(entry2.publishedDate) - Date.parse(entry1.publishedDate); // return get milisecond
});
onRequestFinished();
});
} //loop x finish}
}
According to the above cord, allEntries provide JSON object array
Very thankful for the your answers

You're going to have to loop through every entry and compare the dates. For each date that passes your test, add it to another array. E.g.
var newEntries = JSON.parse(result.response),
filteredEntries = [],
i,
testDate = new Date();
testDate = testDate.setHours(testDate.getHours() - 6);
for(i = 0; i < newEntries.length; i++) {
if(newEntries[i].publishedDate > testDate) {
filteredEntries.push(newEntries[i]);
}
}
new Date() always returns the current date
Date.getHours() returns the hour component of the date
Date.setHours(hour) sets the hour component of the date
If hour is a negative value, the date will go to the previous day. For instance if your date was 2013-5-3 04:33 setting the hour component to -2 will change the date to 2013-5-2 22:33
In the example above, if the time was 2:45 a.m., it will set the time component to -4, which would cause it to test against 8:45 p.m. the previous day.

Related

Convert UTC ISO value to `String` (Text)

Objective: I need to convert a UTC value (col A) to a String before passing it to a function for local time zone conversion.
Errors: no errors, script runs successfully
Issue: Time is not converted to specified time zone
Further info:
If I use the following in my LOCALTIME function, the date is converted correctly.
var originalDate = new Date("2020-05-12T23:22:46.120Z");
Function to get the time in UTC (col A):
function getAllEmailAndDiningPreferences(changeType){
var orders = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Orders');
var ordersData = orders.getDataRange().getValues();
var lr = getLastRow(orders, "A1:E");
for (var i=0; i<lr; i++){
if(ordersData[i][1].length == 0){
var orderId = ordersData[i][0]; //note: need to convert 'orderId' to a String
var email = getEmailFromOrderedId(orderId.toString()); //toString() doesn't convert it to a expected String
convertOrderDateToLocalTimeZone(i+1, orderId);
i+1;
}
}
}
Function to convert to locatime zone:
function LOCALTIME(datetimeString) {
if (datetimeString.map) {
return datetimeString.map(LOCALTIME);
} else {
var originalDate = new Date(datetimeString);
return Utilities.formatDate(originalDate, "Australia/Adelaide", "yyyy-MM-dd'T'HH:mm:ss'Z'")
}
}
Answer:
Due to Sheet locale, you need to get the display value of the cell before making a date object so that the Script project reads it correctly as UTC.
More Information:
getDisplayValues() will literally get the values of the cells as you see them in the UI. As a result, as the strings are inputted in UTC, you can bypass the conversion to your local time zone by calling for the displayed datetime rather than the stored one:
Code Example:
function dateConvert() {
var d = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet().getRange("A2").getDisplayValue();
var dateObj = new Date(d);
var newDate = Utilities.formatDate(dateObj, "Australia/Adelaide", "yyyy-MM-dd'T'HH:mm:ss'Z'")
Logger.log(newDate);
}
In this case, newDate will be converted to the Australia/Adelaide timezone.
There is also the .getDisplayValues() method, which works in the same way only over a range of values rather than just a single cell.
References:
Class Range - getDisplayValue() | Apps Script | Google Developers

why are the dates not being generated properly?

I am using a function in Angular JS to generate the dates for the past one week starting from today's date. I am storing these dates in an array and then using that array to flood a dropdown.
The following is the code that is being used by me.
generate() {
this.date_new = [];
var date = new Date();
var date1 = new Date();
for (var i = 0; i < 7; i++) {
date.setDate(date1.getDate() - i);
var a = date.toString();
var str = this.convert(a);
this.date_new.push(str);
}
}
Here convert is a function which is being used to convert the dates to the required format. A screenshot of generated dates is attached below.
As evident from the screenshot, the last two dates are incorrect. Can somebody explain to me, what the problem is?
The setDate() method sets the day of the Date object relative to the
beginning of the currently set month.
The above is from MDN.
Your code works for the first 5 dates, but once you are modifying your February date with -1, it sets the day relative to the current month e.g. February. So this will turn into January (as you are setting the day to -1), same happens in the next iteration and you get December.
For an easy fix you can just set the date variable to new Date() in the first line of your for loop.
The issue here is using the same date variable in the loop. You need to re-initialize it.
As can be seen in Parameters Value section in the link here. Zero and negative values in setDate() sets the date from previous month.
Hence at setDate(0), date value is set to last day of Feb. Now since you are using the same variable, setDate(-1) takes the previous month from Feb hence you get Jan.
You need to change the code to something like this:
generate() {
this.date_new = [];
var date1 = new Date();
for (var i = 0; i < 7; i++) {
// re-initialize date
var date = new Date();
date.setDate(date1.getDate() - i);
var a = date.toString();
var str = this.convert(a);
this.date_new.push(str);
}
}
Hope this helps :)
The issue here is that negative numbers inside the setDate method don't work quite well.
Please update the code to something like below:
this.date_new = [];
var date = new Date();
var date1 = new Date();
for (var i = 0; i < 7; i++) {
date= new Date(date1.getFullYear(), date1.getMonth(),date1.getDate()-i);
var a = date.toString();
var str = this.convert(a);
this.date_new.push(str);
}
Hope this will solve your problem.

I can't seem to compare two date objects. One from mongo, one generated

edit, I've been able to work around this problem by comparing the values of the dates rather than the dates themselves:
$scope.entries[0].formattedDate === $scope.days[0]
$scope.entries[i].formattedDate.valueOf() === $scope.days[0].valueOf() //true
The goal of this angularjs program is to:
Generate the days in the current week (as an array of Javascript Date Objects)
Obtain a bunch of JSON objects from mongodb. (These objects have a property called "date." This "date" property is in the following format: ISODate("2016-05-18T04:44:42.067Z")
Compare each of the mongo items to a generated day, tell the user if any match (only the day! disregard time)
This is my code to generate the days of the week, and it works well:
$scope.getWeek = function (num) {
var curr = new Date;
curr.setDate(curr.getDate() - (num * 7));
var days = [];
for (var i = 0; i < 7; i++) {
days.push(new Date(curr.setDate(curr.getDate() - curr.getDay() + i)));
days[i].setHours(0, 0, 0, 0);
}
$scope.days = days;
};
I only want to know if the day matches, and not the time. I am using this function to strip the time from every item retrieved from Mongodb:
var removeHours = function (date) {
date.setHours(0, 0, 0, 0);
return date;
};
When it comes to comparing the dates, I'm absolutely stuck! It seems like I've tried everything. When I console.log the two dates, they are identical. I'm probably not aware of something about JS objects and I'm hoping somebody can provide a simple, easy solution.
$scope.entries[i].formattedDate == $scope.days[0] // false

How do I store and retrieve javascript variables that I have made?

I'm working on a followup question to one I posted here, which was resolved.
In my application, I am getting an array of values that are taken from a dynamic field on an input form (Gravity Forms List Field). A testing array that has the same structure can be created this way:
var entries = new Array();
entries[0] = new Array( 1, 1, 2016, "9:00", "am", "5:00", "pm");
entries[1] = new Array( 1, 2, 2016, "9:10", "am", "5:10", "pm");
From left to right, those values are: month, day, year, start time, star time period, end time, end time period.
Since it is a dynamic input - there could be any number of subarrays on a real submission.
My goal is to have an array of unix timestamps that I can use to do validations on the form submission. One validation will be 'is the current date more than 6 months past the last submitted date'.
The following code demonstrates how I am able to produce timestamps.
I'm looking for a method of adding an unlimited number of timestamps to my array.
I'm also looking for a method of targeting timestamps, once I have them.
// Create an array to collect timestamps
var sessions = new Array();
// Ready the Zero Prepend-er so dates are always correct
function twoDigitFormat( num ) {
return ( num.toString().length < 2 ? "0"+num : num ).toString();
}
// Loop through entries array to get each entry array
for ( i = 0; i < entries.length; i++ ) {
var entry = entries[i];
// Loop through each entry array to get the values
for ( j = 0; j < entry.length; j++ ) {
var value = entry[j];
// get all of the parts
var month = twoDigitFormat(entry[0]);
var day = twoDigitFormat(entry[1]);
var year = entry[2];
var stime = entry[3];
var stimeperiod = entry[4];
var etime = entry[5];
var etimeperiod = entry[6];
}
// Make Human Timestamps for each entry array
var sessionStartString = month+'-'+day+'-'+year+' '+stime+''+stimeperiod;
var sessionEndString = month+'-'+day+'-'+year+' '+etime+''+etimeperiod;
// I'm using moments.js for time handling
// Make Session Moments for each timestamp
var sStartMoment = moment( sessionStartString, "MM-DD-YYYY HH:mm a");
var sEndMoment = moment( sessionEndString, "MM-DD-YYYY HH:mm a");
// Make UNIX format moments for each timestamp
var sStartUnix = sStartMoment.unix();
var sEndUnix = sEndMoment.unix();
// Add each UNIX timestamp to the sessions array
// How do I add arrays with a variable as a key? I don't want to
// specify the key. Someone should be able to create 10 entries,
// or 20 entries, or .. whatever count.
sessions[0] = new Array ( sStartUnix );
sessions[1] = new Array ( sEndUnix );
}
// Get the current time (and as UNIX)
var now = moment();
var nowUnix = now.unix();
// Loop through sessions
for ( l = 0; l < sessions.length; l++ ) {
var session = sessions[l];
// How do I get things out of the array of timestamps?
// My current code results in session[key] being UNDEFINED?
var lastSession = session[session.length-1];
}
// Do stuff - like math, to run validations
// I know this isn't correct, but the idea will be to get
// a difference in hours
var lastNowDiff = nowUnix - lastSession;
if ( lastNowDiff > 4320 ) {
alert('The submission date must be within 6 months.');
}
I have it running in a Fiddle if you have a moment to check it out.
Use array's push method.
Example:
var entries = new Array();
entries.push(new Array( 1, 1, 2016, "9:00", "am", "5:00", "pm"));
You can add any number of arrays like this.
Complete Fiddle: https://jsfiddle.net/jryven/ovc2f1b7/
Use the JavaScript Date object for parsing and validating.

Function to iterate over an array of dates produces unexpected results

I have a CloudCode function that is called from my iOS app. The function is supposed to create a "checkin" record and return a string to represent the last 30 days of check-ins and missed days.
The strange thing is that sometimes I get the expected results and sometimes I do not. It makes me think that there is some issue with the may I am using timezones - since that could result in a different set of "days in the past" depending on what time I run this function and what time of day I checked-in in the past. But I'm baffled and could use some help here.
It's also confusing me that I do not see all of my console.log() results appear in the parse log. Is that normal?? For example, in the for loop, I can uncomment the console.log entry and call the function but I will not see all of the days in the past listed - but they are included in the final array and text string.
Here is my complete function. Any help and suggestions are appreciated.
/* Function for recording a daily check in
*
* Calculates the number of days missed and updates the string used to display the check-in pattern.
* If no days missed then we increment the current count
*
* Input:
* "promiseId" : objectID,
* "timeZoneDifference" : String +07:00
*
* Output:
* JSON String eg. {"count":6,"string":"000000000000001111101010111111"}
*
*/
Parse.Cloud.define("dailyCheckIn", function(request, response) {
var promiseId = request.params.promiseId;
var timeZoneDifference = request.params.timeZoneDifference;
var currentUser = Parse.User.current();
if (currentUser === undefined) {
response.error("You must be logged in.");
}
if (timeZoneDifference === undefined || timeZoneDifference === "") {
//console.log("timeZoneDifference missing. Set to -07:00");
timeZoneDifference = '' + '-07:00'; // PacificTime as string
}
var moment = require('cloud/libs/moment.js');
// Query for the Promise
var Promise = Parse.Object.extend("Promise");
var queryforPromise = new Parse.Query(Promise);
queryforPromise.get(promiseId, {
success: function(promis) {
// Initialize
var dinarowString = "";
var dinarowCount = 0;
// Last Check In date from database (UTC)
var lastCheckInUTC = promis.get("lastCheckIn");
if (lastCheckInUTC === undefined) {
lastCheckInUTC = new Date(2015, 1, 1);
}
// Use moment() to convert lastCheckInUTC to local timezone
var lastCheckInLocalized = moment(lastCheckInUTC.toString()).utcOffset(timeZoneDifference);
//console.log('lastCheckIn: ' + lastCheckInUTC.toString());
//console.log('lastCheckInLocalized: ' + lastCheckInLocalized.format());
// Use moment() to get "now" in UTC timezone
var today = moment().utc(); // new Date();
//console.log('today: ' + today.format());
// Use moment() to get "now" in local timezone
var todayLocalized = today.utcOffset(timeZoneDifference);
//console.log('todayLocalized: ' + todayLocalized.format());
// 30 days in the past
var thirtydaysago = moment().utc().subtract(30, 'days');
//console.log("thirtydaysago = " + thirtydaysago.format());
// 30 days in the past in local timezone
var thirtydaysagoLocalized = thirtydaysago.utcOffset(timeZoneDifference);
//console.log('thirtydaysagoLocalized: ' + thirtydaysagoLocalized.format());
// Calculate the number of days since last time user checked in
var dayssincelastcheckin = todayLocalized.diff(lastCheckInLocalized, 'days');
//console.log("Last check-in was " + dayssincelastcheckin + " days ago");
// Function takes an array of Parse.Objects of type Checkin
// itterate over the array to get a an array of days in the past as numnber
// generate a string of 1 and 0 for the past 30 days where 1 is a day user checked in
function dinarowStringFromCheckins(checkins) {
var days_array = [];
var dinarowstring = "";
// Create an array entry for every day that we checked in (daysago)
    for (var i = 0; i < checkins.length; i++) {
var checkinDaylocalized = moment(checkins[i].get("checkInDate")).utcOffset(timeZoneDifference);
var daysago = todayLocalized.diff(checkinDaylocalized, 'days');
// console.log("daysago = " + daysago);
days_array.push(daysago);
}
console.log("days_array = " + days_array);
// Build the string with 30 day of hits "1" and misses "0" with today on the right
    for (var c = 29; c >= 0; c--) {
if (days_array.indexOf(c) != -1) {
//console.log("days ago (c) = " + c + "-> match found");
dinarowstring += "1";
} else {
dinarowstring += "0";
}
}
return dinarowstring;
}
// Define ACL for new Checkin object
var checkinACL = new Parse.ACL();
checkinACL.setPublicReadAccess(false);
checkinACL.setReadAccess(currentUser, true);
checkinACL.setWriteAccess(currentUser, true);
// Create a new entry in the Checkin table
var Checkin = Parse.Object.extend("Checkin");
var checkin = new Checkin();
checkin.set("User", currentUser);
checkin.set("refPromise", promis);
checkin.set("checkInDate", today.toDate());
checkin.setACL(checkinACL);
checkin.save().then(function() {
// Query Checkins
var Checkin = Parse.Object.extend("Checkin");
var queryforCheckin = new Parse.Query(Checkin);
queryforCheckin.equalTo("refPromise", promis);
queryforCheckin.greaterThanOrEqualTo("checkInDate", thirtydaysago.toDate());
queryforCheckin.descending("checkInDate");
queryforCheckin.find().then(function(results) {
var dinarowString = "000000000000000000000000000000";
var dinarowCount = 0;
if (results.length > 0) {
dinarowString = dinarowStringFromCheckins(results);
dinarowIndex = dinarowString.lastIndexOf("0");
if (dinarowIndex === -1) { // Checked in every day in the month!
// TODO
// If the user has checked in every day this month then we need to calculate the
// correct streak count in a different way
dinarowString = "111111111111111111111111111111";
dinarowCount = 999;
} else {
dinarowCount = 29 - dinarowIndex;
}
}
// Update the promise with new value and save
promis.set("dinarowString", dinarowString);
promis.set("dinarowCount", dinarowCount);
promis.set("lastCheckIn", today.toDate());
promis.save().then(function() {
response.success(JSON.stringify({
count: dinarowCount,
string: dinarowString
}));
});
}, function(reason) {
console.log("Checkin query unsuccessful:" + reason.code + " " + reason.message);
response.error("Something went wrong");
});
}); // save.then
},
error: function(object, error) {
console.error("dailyCheckIn failed: " + error);
response.error("Unable to check-in. Try again later.");
}
});
});
There's too much going on in your question to answer adequately, but I will be nice and at least point out a few errors that you should look into:
You take input in terms of a fixed offset, but then you are doing operations that subtract 30 days. It's entirely possible that you will cross a daylight saving time boundary, in which case the offset will have changed.
See "Time Zone != Offset" in the timezone tag wiki. In moment, you can use time zones names like "America/Los_Angeles" with the moment-timezone add-on.
From your example, I'm not even sure if time zone even matters or not for your use case.
You should not convert the Date to a string just to parse it again. Moment can accept a Date object, assuming the Date object was created correctly.
moment(lastCheckInUTC.toString()).utcOffset(timeZoneDifference)
becomes
moment(lastCheckInUTC).utcOffset(timeZoneDifference)
Since Date.toString() returns a locale-specific, implementation-specific format, you'll also see you have a warning in the debug console from moment.
As for the rest, we can't run your program and reproduce the results, so there's not much we can do to help. You need to start by debugging your own program, and then try to reproduce your error in a Minimal, Complete, and Verifiable example. Chances are, you'll solve your own problem along the way. If not, then you will have something in a better state to share with us.
I am answering my own question as I have found the solution.
I had two questions. The first was "why do I get unexpected (incorrect) results" and I suspected that it was related to the way I am using timezones. I would see different results from day to day depending on what time I check in.
The problem is actually related to the way that moment().diff() works. Diff does not calculate "days" the way I expected it to. If I compare 2am today with 11pm yesterday diff will say 0 days because it is less than 24 hours diff. If I compare 1am on Thursday with 8pm on the previous Monday, diff will report 2 days - not 3 as I expected. It's a precision issue. Diff thinks 2.4 days is 2 days ago. But it is more than 2 therefor it is 3 days ago.
We found that the easiest solution is to compare the two dates at midnight rather than at the actual time of day that is recorded in the database. This yields correct results for days. The rest of the code is working fine.
//Find start time of today's day
var todayLocalizedStart = todayLocalized.startOf('day');
    for (var i = 0; i < checkins.length; i++) {
var checkinDaylocalized = moment(checkins[i].get("checkInDate")).utcOffset(timeZoneDifference);
//Find start time of checkIn day
var checkinDaylocalizedStart = checkinDaylocalized.startOf('day');
//Find number of days
var daysago = todayLocalizedStart.diff(checkinDaylocalizedStart, 'days');
// console.log("daysago = " + daysago);
days_array.push(daysago);
}
The second question I had was "is it normal to not see every console.log at runtime". I've talked with other Parse.com users and they report that Parse is inconsistent in logging. I was spending a lot of time debugging "problems" that were simply Parse not logging correctly.
Thanks to everyone that contributed to the answer.
I did make one other change - but it was not a bug. I replaced the query limit from 30 days in the past to simply "30". It's just a bit simpler with one less calculation.

Categories