Reputation: 3272
I'm trying to write a program which will calculate the bill amount for every month. Considering 30/360 model. i.e The amount used for invoicing is based on a 30 day month, regardless of whether the month has 28, 30 or 31 days. I'm calculating the number of days between start date(date when a member enrolled) to end date(Date when the member disenrolled). The cost per day is $25 Here is a small table for eg:
**Dates are in (MM/DD).
Start Date | End Date | No. of Days | Total Amount
05/01 | 05/31 | 30 | ($25/30)*30=25
05/10 | 05/31 | 22 | ($25/30)*22=18.33
05/10 | 06/10 | 22 | ($25/30)*22=18.33
05/01 | 05/12 | 12 | ($25/30)*12=10
05/06 | 05/15 | 10 | ($25/30)*10=8.33
Expected result for Row 3 = ($25/30)*22=18.33
Current Result = ($25/30)*31=25.83
With the code below, I'm able to get the result as expected, except for the highlighted case. How do I place a restriction to make the calculation until the end of the month? I mean if the start date is 05/10 and end date is 06/10, calculate until 05/31 based on the number of days(22).
public static void Main(string[] args)
{
var start = new DateTime(2016, 05, 10);
var finish = new DateTime(2016, 05, 28);
var date1 = start.Day == 31 ? 30 : start.Day;
var date2 = finish.Day == 31 && (start.Day == 30 || start.Day == 31) ? 30 : finish.Day;
var actualDaysDiff = (finish - start).TotalDays;
int newDaysDiff = ((360 * (finish.Year - start.Year)) + (30 * (finish.Month - start.Month)) + (date2 - date1))+1;
Console.WriteLine("The number of days are "+ newDaysDiff);
float invoiceAmount = 0;
invoiceAmount = (float)(25.0/30)*newDaysDiff;
Console.WriteLine("Total Invoice for this month : "+ invoiceAmount);
}
Eg: I don't want to calculate the number of days between start date and end date. I want to calculate the total cost from start date to end of that particular month. If a customer subscribes to a product on May 10 and ends his subscription on June 10th. The cost is billed on monthly basis. So The customer is billed by calculating the cost from May 10th to May 31st. The billing for the rest of the days happens in June cycle and so on
Upvotes: 2
Views: 3610
Reputation: 49
public static int GetDays(DateTime start, DateTime end) {
int newDaysDiff = ((360 * (end.Year - start.Year)) + (30 * ((end.Month - start.Month) == 0 ? 0 : (end.Month - start.Month) - 1)));
int j = 0;
if (start.Month == end.Month && start.Year == end.Year) {
if (start.Day == 1 && end.Day == 31) {
j = (end.Day - start.Day);
}
else {
j = (end.Day - start.Day) + 1;
}
}
else {
if (start.Day == 1) {
j = j + 30;
}
else {
j = j + DateTime.DaysInMonth(start.Year, start.Month) - start.Day + 1;
}
if (end.Day == 30 || end.Day == 31) {
j = j + 30;
}
else {
j = j + end.Day;
}
}
newDaysDiff = newDaysDiff + j;
return newDaysDiff;
}
Upvotes: 1
Reputation: 6155
You could use this for calculating the total days between two dates
var start = new DateTime(2016, 05, 01);
var finish = new DateTime(2016, 05, 31);
var daysBetween = (finish - start).TotalDays + 1;
daysBetween = daysBetween > 30 ? 30 : daysBetween;
Upvotes: 0
Reputation: 460108
If i've understood your requirement you only want to calculate the amount for the start-date month. Then following should work which is also simpler and more concise:
int startDateDays = DateTime.DaysInMonth(start.Year, start.Month);
if (finish.Month != start.Month || finish.Year != start.Year)
finish = new DateTime(start.Year, start.Month, startDateDays);
int newDaysDiff = (finish - start).Days + 1;
if (newDaysDiff >= startDateDays)
newDaysDiff = 30;
float invoiceAmount = (float)(25.0 / 30) * newDaysDiff;
With this approach your highlighted row which is a full month will be treated as 22 days.
Upvotes: 1
Reputation: 454
i ran your code and it actually says its 31 days. with:
var start = new DateTime(2016, 05, 10);
var finish = new DateTime(2016, 06, 10);
as mentioned in the comments above, if you are trying to find from 5/10 to 5/31 it´s also right, its 22 days
Upvotes: 1