Skip to content
Advertisement

Dates stuck in month loops

The dates go to one month either side and then get stuck in loops. Starting in June, it will go fine to end of July, or start of May, but then loop back to the end/start of those months instead of going further. globalDate is a React state defined const [globalDate, setGlobalDate] = useState(new Date());

Code Snippet:

//decreasing
const newDate = new Date();
newDate.setDate(globalDate.getDate() - 1);
if (globalDate.getMonth() !== newDate.getMonth()) {
    newDate.setMonth(globalDate.getMonth());
}
if (globalDate.getDate() <= 1) {
    newDate.setMonth(globalDate.getMonth() - 1);
    newDate.setDate(daysInMonth[newDate.getMonth()]);
}
setGlobalDate(newDate);

//increasing
const newDate = new Date();
newDate.setDate(globalDate.getDate() + 1);
if (globalDate.getMonth() !== newDate.getMonth()) {
    newDate.setMonth(globalDate.getMonth());
}
if (globalDate.getDate() >= daysInMonth[globalDate.getMonth()]) {
    newDate.setMonth(globalDate.getMonth() + 1);
    newDate.setDate(1);
}
setGlobalDate(newDate);

Full page source : https://github.com/Westsi/thynkr/blob/master/frontend/web/js/src/Planner.js

Advertisement

Answer

The problem in the first code block (“decreasing”) occurs when newDate.setMonth() is executed when newDate has a date that is the last day of the month, and the previous month has fewer days. So for instance, it happens when newDate is 31 May at the moment this call to setMonth is made. That call will adjust the date to 31 April, but that date automatically translates to 1 May as April only has 30 days, and so you get stuck in the month of May.

To avoid this kind of problems, just start with globalDate immediately and subtract or add one day. That’s all. The overflowing into a next/previous month is something that JavaScript already deals with automatically. So instead of trying to do this yourself (and run into trouble), let JavaScript do this for you:

Decreasing logic:

const newDate = new Date(globalDate); // starting point!
newDate.setDate(globalDate.getDate() - 1);  // month overflow happens automatically!
setGlobalDate(newDate); // That's it!

Increasing logic:

const newDate = new Date(globalDate); // starting point!
newDate.setDate(globalDate.getDate() + 1);  // month overflow happens automatically!
setGlobalDate(newDate); // That's it!
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement