Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deep understanding: How code structure affects the content of date arrays created with loops

Background explanation

I have asked a question concerning defining an date array using a loop.

The array is defined on basis of a declared variable named "dateinterval". The way I designed the code resulted in an error message in relation to another loop and another user provided another loop for me which solved this.

Now that I have closely compared the two different solutions I simply do not understand why they do not produce the same outcome.

My code

I developed the below code to define an array of dates in UTC format. However the outcome is an array of dates in millisecs since January 1, 1970, 00:00:00. So in other words a number.

for (var i=0; i < difference; i++){
    dateinterval[dateinterval.length] = dateinterval[0].setDate(datointerval[0].getDate() + i);
};

The proper solution

The below code is the proper one provided to me by another user (thank you again!) This code defines an array of UTC dates.

for (var i = 0; i < difference; i++) {
    var dt = new Date(dateinterval[0]);
    dt.setDate(dt.getDate() + i);
    dateinterval[dateinterval.length] = dt;
};

What I don't understand

I have almost become blind from staring at the two different solutions to figure out what the difference is and I just don't get it.

To my untrained eyes it seems that the two pieces of code perform exactly the same operation and that the only difference is how they are structured. I have been informed that setDate returns millisecs and that in my code these millisecs were assigned to the array. But in the proper solution the variable DT is also assigned a setDate value which - as I understand it - should also be in millisecs. So why does the line:

dateinterval[dateinterval.length] = dt;

not assign millisecs to the dateinterval array?

Can anyone explain this to me so that I can better understand Javascript and not just replicate working solutions?

like image 643
rabbitco Avatar asked Apr 28 '15 10:04

rabbitco


1 Answers

When you do:

dateinterval[dateinterval.length] = dateinterval[0].setDate(datointerval[0].getDate() + i);

you are assigning the return value of dateinterval[0].setDate(…) to dateinterval[…]. That return value is the timeclip or internal timevalue of the Date object (which is milliseconds since 1 January, 1970). See ECMA-262 §20.3.4.20.

So you need to modify the Date first:

dateinterval[0].setDate(datointerval[0].getDate() + i);

then assign a reference to the object:

dateinterval[dateinterval.length] = dateinterval[0];

Edit

It may help to see a simple case.

// Create a new Date for 2015-01-01
var date = new Date(2015,0,1);

// Change the date to 2015-01-02
var x    = date.setDate(2);

// The return value from the method is the internal timevalue
console.log(x);

// Check the timevalue
console.log(new Date(x)); // 2 January, 2015

The OP seems to expect that setDate returns the original Date object, but it doesn't, it returns the timevalue. The original function will work if the return value from setDate is converted to a Date:

dateinterval[dateinterval.length] = new Date(dateinterval[0].setDate(datointerval[0].getDate() + i));

however that throws away the original Date object and creates a new one.

like image 160
RobG Avatar answered Oct 23 '22 01:10

RobG