Paul Gowder
Paul Gowder

Reputation: 2539

Confusing JS loop behavior with dates

The following code, which I tweaked from this prior SO answer, attempts to loop over the range from 2/5/13 to 2/10/13, including both endpoints.

var start = new Date("02/05/2013");
var end = new Date("02/10/2013");

var output = [];
var loop = new Date(start);
alert(loop)
while(loop < end){           
    output.push(loop);
    var newDate = loop.setDate(loop.getDate() + 1);
    loop = new Date(newDate);
}
var strings = JSON.stringify(output);

var pgraf = document.createElement('p');
var ptext = document.createTextNode(strings)
pgraf.appendChild(ptext)
document.body.appendChild(pgraf);

For some reason that I don't understand, however, while the alert before the loop alerts 2/5/13 as one would expect, the first item in the actual output array is 2/6/13. So the string ultimately appended to the dom is

["2013-02-06T07:00:00.000Z","2013-02-07T07:00:00.000Z","2013-02-08T07:00:00.000Z","2013-02-09T07:00:00.000Z","2013-02-10T07:00:00.000Z"]

So that's mystery #1.

Mystery #2: I tried to trim this code down a little bit, by replacing everything from the creation of the output array to the end of the loop with:

var output = [start];
while(start < end){           
    var newDate = start.setDate(start.getDate() + 1);
    start = new Date(newDate);
    output.push(start);

}

But this time, the output is even weirder: it doesn't include the initial value of the start variable at all, but does include the last value twice.

["2013-02-06T07:00:00.000Z","2013-02-07T07:00:00.000Z","2013-02-08T07:00:00.000Z","2013-02-09T07:00:00.000Z","2013-02-10T07:00:00.000Z","2013-02-10T07:00:00.000Z"]

Clearly I don't understand what's happening in the loop here. But I've been programming in non-JS languages for a few years now---I like to think I understand how loops work! Can anyone tell me what I'm screwing up here?

Upvotes: 1

Views: 53

Answers (1)

IrkenInvader
IrkenInvader

Reputation: 4050

The loop variable you are modifying in the last line of your while loop is still the same loop you inserted into the array at the start.

If you make a new Date(loop) and insert that instead you won't get that side effect.

setDate modifies the date you call it on so the third line if your loop is unnecessary.

Lastly if you want to include both start and end, use <= instead of <

var start = new Date("02/05/2013");
var end = new Date("02/10/2013");

var output = [];
var loop = new Date(start);

while(loop <= end){           
    output.push(new Date(loop));
    loop.setDate(loop.getDate() + 1);
}

console.log(output)

Upvotes: 3

Related Questions