Subscription based monthly start and end dates between two dates

Calculate monthly start and end date between provided start and end date using apex function. Calculate subscription based dates between two dates.

Recently while working with integration project with Stripe, I come up the scenario to auto generate payment records for each month between start date and end date. To understand what I want to explain, see below example:

Lets say the start date is 22 June 2020 and end date is 10 September 2020. The goal is to calculate number of month with their start and end dates like below:

  • 22 June 2020 to 30 June 2020
  • 1 July 2020 to 31 July 2020
  • 1 August 2020 to 31 August 2020
  • 1 September 2020 to 10 September 2020

Hope you get more clarity what I am explaining.

Apex Function:

public static list<list<Date>> getRecurringDates(Date StartDate, Date EndDate){
	list<list<Date>> RecurringDates = new list<list<Date>>();
	for(Integer i = 0 ; i < (StartDate.monthsBetween(EndDate) + 1); i++){
		//month start and end date
		MonthStartDate = StartDate.toStartofMonth().addMonths(i);
		MonthEndDate = StartDate.addMonths(1+i).toStartofMonth().addDays(-1);
		
		TempStartDate = MonthStartDate;
		TempEndDate = MonthEndDate;
		if(i == 0){
			//payment start and end date      
			TempStartDate = StartDate;
			TempEndDate = StartDate.addMonths(1).toStartofMonth().addDays(-1);
		}
		else if(i == L.Start_of_Lease__c.monthsBetween(L.End_of_Lease__c)){
			//payment start and end date      
			TempStartDate = EndDate.toStartofMonth();
			TempEndDate = EndDate;
		}
		RecurringDates.add(new list<Date>{TempStartDate, TempEndDate});
	}
	return RecurringDates;
}

Explanation:

  • getRecurringDates is the static method accepting two arguments, StartDate and EndDate. As name suggests, you need to pass start and end date to function.
  • Using StartDate.monthsBetween(EndDate), we are finding total number of months between two dates and iterating for each month.
  • MonthStartDate and MonthEndDate variables holding start date and end date of month for each for iteration.
  • TempStartDate and TempEndDate are holding actual start and end date of provided date values. If its first iteration, TempStartDate is set to provided start date. If its last iteration, TempEndDate is set to provided end date. All other subsequent values are set to Month’s start and end date.
  • Returning the list of another list having start and end date combination. Each outer list index will be having each month’s start and end date.

Feel free to comment any other optimized way you have!