The problem you have is that you push references to the date1 object. When you change the date on it in your loop, you update the object, but all references still point to the same object.
You need to either push a text representation of your date, or a copy of your date1 object
for (var i=0; date1 <= date2; date1.setDate(date1.getDate() + 1), i++) {
alldates.push(new Date(date1));
}
alert(alldates.join('\n'));
As suggested, with a while loop
while( date1 <= date2 ) {
alldates.push(new Date(date1));
date1.setDate( date1.getDate() +1 );
}
Answer from jaudette on Stack OverflowThe problem you have is that you push references to the date1 object. When you change the date on it in your loop, you update the object, but all references still point to the same object.
You need to either push a text representation of your date, or a copy of your date1 object
for (var i=0; date1 <= date2; date1.setDate(date1.getDate() + 1), i++) {
alldates.push(new Date(date1));
}
alert(alldates.join('\n'));
As suggested, with a while loop
while( date1 <= date2 ) {
alldates.push(new Date(date1));
date1.setDate( date1.getDate() +1 );
}
Your array is storing the references for the single date object and everytime when setDate is called each of them are getting updated with new date value.
So it will be better to push the new date object in array like this,
var date1 = new Date("Sep 23, 2013 12:00:00"); // Monday
var date2 = new Date("Sep 26, 2013 12:00:00"); // Thursday
var alldates = [];
// pushing first date
alldates.push(new Date(date1.setDate(date1.getDate())));
for (var i=0; date1 <= date2; i++) {
alldates.push(new Date(date1.setDate(date1.getDate() + 1)));
}
alert(alldates.join('\n'));
Date.prototype.addDays = function(days) {
var date = new Date(this.valueOf());
date.setDate(date.getDate() + days);
return date;
}
function getDates(startDate, stopDate) {
var dateArray = new Array();
var currentDate = startDate;
while (currentDate <= stopDate) {
dateArray.push(new Date (currentDate));
currentDate = currentDate.addDays(1);
}
return dateArray;
}
Here is a functional demo http://jsfiddle.net/jfhartsock/cM3ZU/
I looked all the ones above. Ended up writing myself. You do not need momentjs for this. A native for loop is enough and makes most sense because a for loop exists to count values in a range.
One Liner:
const getDaysArray = function(s,e) {const a=[];for(const d=new Date(s);d<=new Date(e);d.setDate(d.getDate()+1)){ a.push(new Date(d));}return a;};
Long Version
const getDaysArray = function(start, end) {
const arr = [];
for(const dt=new Date(start); dt<=new Date(end); dt.setDate(dt.getDate()+1)){
arr.push(new Date(dt));
}
return arr;
};
List dates in between:
const daylist = getDaysArray(new Date("2018-05-01"),new Date("2018-07-01"));
daylist.map((v)=>v.toISOString().slice(0,10)).join("")
/*
Output:
"2018-05-01
2018-05-02
2018-05-03
...
2018-06-30
2018-07-01"
*/
Days from a past date until now:
const daylist = getDaysArray(new Date("2018-05-01"),new Date());
daylist.map((v)=>v.toISOString().slice(0,10)).join("")
When you do q.setTime( ... ) you are modifying the Date object itself. You are pushing the same object into the array at each iteration, hence modifying it modifies the entire array.
If you only want the string representations of the dates only, you can do:
let initialTime = new Date("2018-03-09Z08:00:00")
,endTime = new Date("2018-03-14Z08:00:00")
,arrTime = []
;
for (let q = initialTime; q <= endTime; q.setDate(q.getDate() + 1)) {
arrTime.push(q.toString());
}
console.log(arrTime);
Or, if you want to have an array of actual Date instances:
let initialTime = new Date("2018-03-09Z08:00:00")
,endTime = new Date("2018-03-14Z08:00:00")
,arrTime = []
,dayMillisec = 24 * 60 * 60 * 1000
;
for (let q = initialTime; q <= endTime; q = new Date(q.getTime() + dayMillisec)) {
arrTime.push(q);
}
console.log(arrTime);
first of all you can not compare two dates using ==
second problem is you need to create a new Date object each time you push one to the array ex. .push(new Date(q.getTime())
the next problem is you aren't properly adding a day to the last day each time before you push into the array
do something like
pseudo code ---
var dates = [];
while( firstDate < secondDate ){
// this line modifies the original firstDate reference which you want to make the while loop work
firstDate.setDate(firstDate.getDate() + 1);
// this pushes a new date , if you were to push firstDate then you will keep updating every item in the array
dates.push(new Date(firstDate);
}
The variable i never changes once set, so you're constantly writing to the same index.
Also, your counter variable is never used. Consider using your counter variable as the index as it will be unique for each iteration. Alternatively, if you want to continue using the date as an index, add the line i = firstDate.toDate(); to the top of your for loop.
For the latter, your loop should look like this:
var counter = 1;
var arr = [];
var i = firstDate.toDate();
for(counter; firstDate < secondDate; counter++){
i = firstDate.toDate();
arr[i]=firstDate.toDate();
console.log(firstDate.toDate());
firstDate.add(1, "day");
}
console.log(arr[2]);
I suggest adding a console log to your loop (as above) if you're having problems, to see which dates are being added as they are being added.
Since the difference between first and second date is unknown beforehand you could use a while loop instead
while( firstDate.isBefore(secondDate) ) {
arr.push(firstDate.toDate());
firstDate.add(1, 'day');
}
Move var currentDate = new Date(); inside for loop. Otherwise you are modifying the same object and adding 50 references of it in the array.
In the end you see the the same object printed 50 times with the last updated date value.
You can do as Yogendra suggests, or change:
> dates.push(currentDate);
to
dates.push(new Date(currentDate));
to get a different date object for each member of the array.
No, now.setDate(now.getDate() - index) actually was the rigth approach. Yet it does not return the new day, but the new [internal] timestamp of the now Date instance. Make it two steps:
now.setDate(now.getDate() - 1); // sets the date to the previous day each time
date.push(now.getDate());
// set the date first, and then push the Date object's getDate value into the array.
function pastweek(d){
var now= d || new Date(),
i= 6,
dates= [now.getDate()];
while(i--){
now.setDate(now.getDate()-1);
dates.push(now.getDate());
}
return dates.reverse();
}
/*
pastweek(new Date(2012,9,5))
returned value: (Array)
29,30,1,2,3,4,5
*/
/*
pastweek()
returned value: (Array)
17,18,19,20,21,22,23
*/
The ES5 spec details the new Date(value) form of the Date constructor. In the algorithm for handling this form, value is converted to a primitive value by calling the [[DefaultValue]] internal method of the object.
Converting an array to a primitive value is basically done by converting the array to a string. Converting an array to a string (Array.prototype.toString) is effectively the same as calling dateArray.join().
Therefore, your call to the Date constructor will effectively look like this:
var dateObject = new Date("2012,6,5");
If the string can be recognised by the Date.parse method, you will end up with a Date instance.
This form of the Date constructor is also listed on MDN as new Date(dateString).
Firefox seems to fail when you pass an array, but it succeeds if you pass the string representation of that array. I would say that that's probably a Firefox bug, but I may be misinterpreting the ES5 spec.
You can use Spread Syntax in ES6.
let dateArray = [2012, 6, 5];
let dateObject = new Date(...dateArray);
console.log('Spread:', dateObject);
console.log('Direct:', new Date(2012, 6, 5));
Your bug is because you are assigning the return value from Array.prototype.forEach to exerciseLog.
Array.prototype.forEach does not return anything.
You want to use Array.prototype.map.
exerciseLog = exerciseLog.map(x => x.date.toLocaleDateString());
@Miles Grover and @BlueWater86 thank you for the help. I tried map before and it didn't work but now it does.
exerciseLog = exerciseLog.map(x => x.date.toLocaleDateString());
returned only the formatted dates, so I had to do this to keep the rest of the object info:
exerciseLog = exerciseLog.map(x => "description: " + x.description + ", duration: " + x.duration + ", date: " + x.date.toLocaleDateString());
If what you want is an array ["1:00", "1:15", ...] then why not just build that? It has nothing to do with "hours" and "minutes", only with "getting some obviously sequential numbers" right:
cost arr = [];
for (let i=0; i < 24; i++) {
for (let j=0; j < 4; j++) {
arr.push(`${i}:${j === 0 ? `00` : 15*j}`);
}
}
Done. Find your current time nearest a 15 minute block:
const d = new Date(),
h = d.getHours(),
m = 15 * Math.floor(d.getMinutes() / 15),
stamp = `${h}:${m === 0 ? `00` : m}`;
And just reorder the timeslots:
const pos = arr.indexOf(stamp);
let timelist = [];
if (pos > -1) {
timelist = [
...arr.slice(pos),
...arr.slice(0,pos)
];
}
Try this:
var timeArray = [],
d = new Date(),
h = d.getHours(),
m = d.getMinutes(),
meridiem = ['AM','PM'];
for (var i = h; i < 24; ++i) {
for (var j = i==h ? Math.ceil(m/15) : 0; j < 4; ++j) {
timeArray.push(i%12 + ':' + (j*15||'00') + ' ' + meridiem[i/12|0]);
}
}