0

I'm trying to calculate dates for monthly subscriptions. I've seen many answers to use some variance of:

const oneMonthFromNow = new Date(new Date().setMonth(new Date().getMonth()+1));

But when I test this for edge cases it doesn't work as expected, some examples:

  • Today: 31st march => Expected: 30th of April => Output: 1st of may (since 31 doesn't exist...?)
  • Today: 30th January => Expected: 28th of February => Output: 2nd of March (what about leap years??)

Any ideas on how I can make this work without adding exception rules?

denislexic
  • 10,786
  • 23
  • 84
  • 128
  • 1
    see: [What is the best way to determine the number of days in a month with JavaScript?](https://stackoverflow.com/questions/315760/what-is-the-best-way-to-determine-the-number-of-days-in-a-month-with-javascript), or use a library: [date-fns: addMonths](https://date-fns.org/v2.19.0/docs/addMonths) – pilchard Mar 31 '21 at 23:10

1 Answers1

1

I would do something along the lines of:

function isLeapYear(year){
  return year % 4 === 0 && (year % 400 === 0 || year % 100 !== 0);
}
function lastMonthDay(jsMonth, year){
  switch(jsMonth){
    case 1:
      return isLeapYear(year) ? 29 : 28;
    case 3: case 5: case 8: case 10:
      return 30;
    default:
      return 31;
  }
}
const dt = new Date('January 30, 2022');
console.log(lastMonthDay(dt.getMonth()+1, dt.getFullYear()));
StackSlave
  • 10,613
  • 2
  • 18
  • 35
  • `lastMonthDay = date.setMonth(date.getMonth() + 1, 0)`. It doesn't matter what day it's run on or how many days are in the month, it will reliably return the last day of the month. – RobG Apr 01 '21 at 03:21
  • @RobG ... I don't see it. I tried your example, changing out `date` for my `dt`, but it does not return the correct last day of the month. Do tell. – StackSlave Apr 01 '21 at 23:36
  • `let d = new Date(2021, 2, 31); d.setMonth(d.getMonth() + 1, 0); console.log(d.getDate())` shows 31. You can do the same with Jan 30 and 31, and any other month with a date that is more than the days in the following month. – RobG Apr 02 '21 at 09:36
  • @RobG, I tried your methodology. It didn't work to find the last day of February. – StackSlave Apr 04 '21 at 09:27
  • Then you're doing something wrong. `let d = new Date(2021,1,20); d.setMonth(d.getMonth() + 1, 0);` returns a date for 28 February. Please post the non–working code. – RobG Apr 05 '21 at 11:40