0
votes

I am trying to make a cloud function in firebase that does something every day, week, month or year for max. 1 year into the future. Somehow the date looping doesnt work. Does anyone know why this is? My Code:

//Format date to yyyy-mm-dd
  const splitDate = date.split('-');
  const year = splitDate[2];
  const month = splitDate[1];
  const day = splitDate[0];

  const nextYear = [parseInt(year) + 1, parseInt(month)  - 1, parseInt(day)];

  let curDate = new Date(year, parseInt(month) - 1, day);

  while(true){
    //increase the date of the appointment by the specified amount of time each iteration
    if (recurring === 'daily') {
        curDate.setDate(curDate.getDate() + 1);
    } else if (recurring === 'weekly') {
        curDate.setDate(curDate.getDate() + 7);
    } else if (recurring === 'monthly') {
        curDate.setMonth(curDate.getMonth() + 1);
    } else if(recurring === 'yearly') {
        curDate.setFullYear(curDate.getFullYear() + 1);
    } else{
        console.log('recurring value was not entered or invalid, function aborted');
      break;
    }
    console.log(curDate);

    //Test if end date is passed. if so, stop function
    if (nextYear[0] < curDate.getFullYear()) {
      break;
    } else if (nextYear[0] == curDate.getFullYear()) {
        if (nextYear[1] < curDate.getMonth() + 1) {
            break;
        } else if (nextYear[1] == curDate.getMonth()) {
            if (nextYear[2] < curDate.getDate()) {
              break;
            }
        }
    }

    //format new data, add a field that indicates this appointment does not need a creation email

    //Add the appointment with the new data in the appointments collection
  }
  return true;
})

This code almost works, but it doesnt get exactly the right date. It stops at the following when testing daily.

2021-09-01T00:00:00.000Z 

It also misses a week when trying weekly. I think it is because of the date checking not being correct. The monthly and yearly do work and weekly and daily end on the correct month. Does anyone know why it instantly does break when it hits the right month in the right year?

1

1 Answers

1
votes

There are several issues that I've noticed within your code:

1 - When testing your code it didn't seem that the date was being calculated correctly. I have modified it the following way in order to fix that:

let curDate = new Date(year, month, day);

while(true){
    //increase the date of the appointment by the specified amount of time each iteration
    if (recurring === 'daily') {
        curDate.setDate(curDate.getDate() + 7);
    } else if (recurring === 'weekly') {
        curDate.setDate(curDate.getDate() + 7);
    } else if (recurring === 'monthly') {
        curDate.setMonth(curDate.getMonth() + 7);
    } else if(recurring === 'yearly') {
        curDate.setFullYear(curDate.getFullYear() + 7);
    } else{
        console.log('recurring value was not entered or invalid, function aborted');
      break;
    }
    console.log(curDate);
...

Note, that I have removed the formatDate using the individual date and time component values instead, as passing an array to new Date() was giving me a wrong month (it was reading 8 as August, while in JS is should represent September since months start from 0).


2 - The getYear() method is deprecated, you should use the getFullYear() instead.


3 - You should change the less-than signs to the greater-than signs for the day and month in your last If-Else statement within the loop, so it looks like this:

----------

EDIT

Looking further into this issue, it seems that your last If-Else statement was actually correct initially. Bringing back the less-than signs should resolve the new issue for you:

if (nextYear[0] < curDate.getFullYear()) {
  break;
} else if (nextYear[0] == curDate.getFullYear()) {
    if (nextYear[1] < curDate.getMonth()) {
        break;
    } else if (nextYear[1] == curDate.getMonth()) {
        if (nextYear[2] < curDate.getDate()) {
          break;
        }
    }
}

Let me know if it helps.