I have written a JavaScript function which generates some year/month entries going 24 months back in time for a js chart. I need every month even if there is no data.
function getLast24Months() {
let result = [];
let now = new Date();
for (let i = 0; i < 24; i++) {
let yyyy = now.getFullYear();
let mm = now.getMonth() + 1;
mm = mm < 10 ? `0${mm}` : `${mm}`;
result.unshift(`${yyyy}-${mm}`);
now.setMonth(now.getMonth() - 1);
}
return result;
}
Usually this works great but today I noticed there were two months in 2023-03.
Why It Fails:
Lack of Reset: There’s no explicit reset to the first day of the current month before the loop starts. While new Date() initializes to the current date and time, it doesn’t guarantee that the month’s first day is targeted, especially when manipulating months.
Misinterpretation of setMonth: The setMonth method changes the month of a Date object, but it doesn’t automatically adjust the day of the month to the first day of the new month. This means that when you subtract a month from a date that is not the first day of the month, the resulting date will be incorrect.
Setting date to 1st of the month does the trick:
function getLast24Months() {
const result = [];
const now = new Date();
now.setDate(1);
for (let i = 0; i < 24; i++) {
let yyyy = now.getFullYear();
let mm = now.getMonth() + 1;
mm = mm < 10 ? `0${mm}` : `${mm}`;
result.unshift(`${yyyy}-${mm}`);
now.setMonth(now.getMonth() - 1);
}
return result;
}