1

I have a function that when called, it will add 7 days to the inputted date. The format for the date is YYYY-MM-DD (i.e. 2022-03-02)

for(let i = 0; i < repeatCount; i++)
{
    date = addWeek(date);
}

function addWeek(date)
{
    let temp = new Date(date);
    //console.log("Old Date: ");
    //console.log(temp.toISOString().split('T')[0])
    //console.log(temp.getDate());
    temp.setDate(temp.getDate() + 7);

    console.log("New Date: ");
    console.log(temp.toISOString().split('T')[0])

    //console.log("returning date");
    return temp.toISOString().split('T')[0];
}

For some reason, when the function is called as part of a repeat (React Web Application that involves recurring events), the addWeek function will not increment correctly a single time but then increment correctly the rest of the time.

Here's the input from my most recent log when I set repeatCount to 5:

Old Date:
2022-03-04
New Date:
2022-03-11

Old Date:
2022-03-11
New Date:
2022-03-17

Old Date:
2022-03-17
New Date:
2022-03-24

Old Date:
2022-03-24
New Date:
2022-03-31

Old Date:
2022-03-31
New Date:
2022-04-07

As you've probably noticed, it increments the week correctly with the exception of the second repeat. I've tested this multiple times with different dates, and each time, it is only the second iteration that is incremented incorrectly. Everything else works fine.

Please help. I'm losing my mind over this.

I forgot to add earlier: addWeek takes the date as a string input.

Kered
  • 11
  • 3
  • Hello, you can use https://github.com/iamkun/dayjs/ to manipulate Date in an easy way. Also, you should add a JSFiddle with an executable example or something similar. – Maxi Schvindt Mar 04 '22 at 22:35
  • 2
    Does this answer your question? [How do I add one day to a Calendar object and also account for daylight savings time?](https://stackoverflow.com/questions/45222363/how-do-i-add-one-day-to-a-calendar-object-and-also-account-for-daylight-savings) Also see [How to add days to date?](https://stackoverflow.com/questions/563406/how-to-add-days-to-date) – kmoser Mar 04 '22 at 22:44
  • @kmoser How does this Q&A translate to JS, exactly? – Sebastian Simon Mar 04 '22 at 22:47
  • 1
    The second repeat is crossing the date when we switch to Daylight Saving Time. I'll bet that's the reason. – Barmar Mar 04 '22 at 22:59
  • @Barmar You were right. It was the Daylight Savings that threw it off. – Kered Mar 04 '22 at 23:01
  • @Barmar I guess the follow-up question would be "How do I account for Daylight Savings?" – Kered Mar 04 '22 at 23:12
  • Do all your date processing in UTC. – Barmar Mar 04 '22 at 23:17
  • @Kered Did you read [How to add days to date?](https://stackoverflow.com/questions/563406/how-to-add-days-to-date) It explains the DST issue. – kmoser Mar 04 '22 at 23:27
  • As Barmar says, use UTC methods so `temp.setUTCDate(temp.getUTCDate() + 7)` because yyyy-mm-dd is parsed as UTC and *toISOString* returns UTC, so the *get* and *set* methods should be UTC too. See [*Why does Date.parse give incorrect results?*](https://stackoverflow.com/questions/2587345/why-does-date-parse-give-incorrect-results) – RobG Mar 05 '22 at 07:09

3 Answers3

1

This is a Daylight Savings Time problem. Dates in JavaScript are inherently local, so when you use setDate() it tries to keep the same time of day on the new date, accounting for shifts in Daylight Savings Time. But that means the time of day will be different when compared to UTC time (which toISOString() converts to). The actual value of temp on the second output in your example is 2022-03-17T23:00Z, one hour before the date you were looking for. But your code strips off the time element so you end up one day off instead.

Instead of using setDate(), use the Date constructor:

    temp = new Date(temp.getFullYear(), temp.getMonth(), temp.getDate() + 7);

var date = new Date('2022-03-02');
const repeatCount = 5;
for(let i = 0; i < repeatCount; i++)
{
    date = addWeek(date);
}

function addWeek(date)
{
    let temp = new Date(date);
    temp = new Date(temp.getFullYear(), temp.getMonth(), temp.getDate() + 7);

    console.log("New Date: ", temp);
    console.log(temp.toISOString().split('T')[0])

    //console.log("returning date");
    return temp.toISOString().split('T')[0];
}
StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
-1

https://jsfiddle.net/4wm1vz9d/1/

function addWeek(date)
{
    date.setDate(date.getDate()+7)
}

let date = new Date();
console.log(date)
for(let i = 0; i < 5; i++)
{
    addWeek(date)
    console.log(date)
}
Maxi Schvindt
  • 1,432
  • 1
  • 11
  • 20
  • 2
    Why use an external jsfiddle when you can use a Stack Snippet here? – Barmar Mar 04 '22 at 23:00
  • 2
    Don't just post code. Explain the problem, and how your code fixes it. – Barmar Mar 04 '22 at 23:02
  • Because I like JSFiddle. The original code returns a date without the hour part and as string, and probably for that reason, the code doesn't work correctly after the first iteration, because it sets the hour using a default value and not the real (defined in Date object), generating a discrepancy. – Maxi Schvindt Mar 05 '22 at 14:15
-1

Phew. Javascript is sometimes weird. Seems like the date get's inaccurate because of the conversion to a ISO String. Try returning the temp Date object instead of the string. Then convert it after adding the weeks. It may have something to do with the other values which the Object provides...

Daveloper
  • 31
  • 2
  • 2
    It's not a question of JS being "sometimes weird". The problem is that it crosses a DST threshold, which causes the time to be an hour earlier, which prevents the extra day from being added. This is explained in [How to add days to date?](https://stackoverflow.com/questions/563406/how-to-add-days-to-date) – kmoser Mar 04 '22 at 23:23
  • @kmoser—the problem is the mix of UTC and local computations. If the OP uses only one or the other then it "works". – RobG Mar 05 '22 at 07:39