Skip to content
Advertisement

Why does Javascript’s Date.getDate() .setDate() behave so unpredictably?

Hobbyist coder here, and this problem is above my pay grade. I’m trying to build a dynamic html / css calendar, where the cells are filled in based on today’s date. I get today’s date, and then try to add days to fill in another 13 days (looping thru html elements.innerHTML).

If I try to setDate(30 + 2) and then getDate(). The code works fine. Javascript figures out that June ends at the 30th day, and the result is 2 as desired (July 2nd)

But this only works if there’s only one call, if I have a loop, or call this code multiple times, then the result is different. Is there some async stuff gumming up the works? Here’s code: If you leave the “result2” call and comment the others, works great, but multiple calls, things break and numbers get repeated. Please help!

const theDate = new Date();
    const todaysDate = 30;
    
    theDate.setDate(todaysDate + 1);
    let result1 = theDate.getDate();
    
    theDate.setDate(todaysDate + 2);
    let result2 = theDate.getDate();
    
    theDate.setDate(todaysDate + 3);
    let result3 = theDate.getDate();
    
    theDate.setDate(todaysDate + 4);
    let result4 = theDate.getDate();
    
    console.log(result1);
    console.log(result2);
    console.log(result3);
    console.log(result4);

Advertisement

Answer

In answer to your question, the setDate() function is behaving so strangely for you because each time you are setting the date you are setting it relative to the previous setting, so incrementing each time by 31, 32, or 33 days instead of by 1, 2, or 3. See the brilliant answer by @Quentin for more information, this finding was entirely his and I just wanted to mention the root cause in my answer as well as my own fix to your problem.


An alternative solution if you just want to generate the dates:

const dayOfMonth = 30;
const date = new Date();
date.setDate(dayOfMonth);
console.log("Date:", date);

let timestamp = Date.parse(date);

for (let i = 1; i <= 14; i++) {
  const newTimestamp = timestamp + i * (1000 * 60 * 60 * 24);
  const newDate = new Date(newTimestamp);
  console.log("New date:", newDate);
}

This method will manipulate the timestamp and generate new dates for each of the timestamps added to the number of milliseconds in a day.

You could use your date logic within the loop to populate the calendar as you mentioned.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement