Here is a function that takes the day of the month in the given date and determines which other date of the month would be needed in the output (either 15 more or 15 less). Then it generates dates alternating between those two date-of-the-month, and when it is the lesser of those two, incrementing the month. In case a date is invalid and automatically overflows into the next month, it is corrected to the last day of the intended month.
In case the day number from the given start date is not the desired date number for (half of) the next months in the schedule, you can pass that desired day as extra, optional argument. For instance, if the start date you give is 2023-02-28, but for the other months you prefer to use 30 as day, then you could pass 30 as argument.
To format the date in the output, it is better to not use toISODateString
as that interprets the date as a UTC Date, while new Date("2022-04-29")
interprets the given string as a date in the local time zone. This can lead to surprises in some time zones. So I would suggest using toLocaleDateString
with a locale that produces your desired format.
Here is the code:
function createSchedule(date, count, day=0) {
date = new Date(date);
day ||= date.getDate();
let k = +(day > 15);
let days = k ? [day - 15, day] : [day, day + 15];
let result = [];
for (let i = 0; i < count; i++) {
k = 1 - k;
date.setDate(days[k]);
// When date overflows into next month, take last day of month
if (date.getDate() !== days[k]) date.setDate(0);
if (!k) date.setMonth(date.getMonth() + 1);
result.push(date.toLocaleDateString("en-SE"));
}
return result;
}
var dateRelease = new Date("2022-04-29");
var result = createSchedule(dateRelease, 25);
console.log(result);
// Example using third argument
dateRelease = new Date("2023-02-28");
var result = createSchedule(dateRelease, 25, 30);
console.log(result);