2

In a scenario where you would need to calculate the next 'Billing date' if the DAY (2nd, 25th, etc) is known, how can you calculate the number of days left until the next bill payment?

Explanation:

Tom's bill gets generated on the 4th of every month

What's the best way/logic to calculate the days left until the next bill? For example, if today is the 28th of this month, the result would be 6 days left

What we know:

Bill Generation Date is known

Today's Date is known

What I've done so far:

int billingDay = 4; //The day the bill gets generated every month
DateTime today = DateTime.Today; //Today's date

How would I continue this to calculate the next billing date?

P.S: Sorry if this sounds lame, I just couldn't wrap my head around it :)

Community
  • 1
  • 1
Jay
  • 4,873
  • 7
  • 72
  • 137
  • You might find this SO post useful: http://stackoverflow.com/questions/1607336/calculate-difference-between-two-dates-number-of-days – Matt Dalzell Aug 09 '16 at 14:23
  • 1
    [DaysInMonth](https://msdn.microsoft.com/de-de/library/system.datetime.daysinmonth(v=vs.110).aspx) will help you at the first point. Just get the actual count of the days in the current month. Then `Today's date - actual count` and add the billingDay. – Christoph K Aug 09 '16 at 14:24
  • Wow love all the responses. Thank you for taking the time everyone :) – Jay Aug 09 '16 at 15:05

5 Answers5

3

I think this works:

private int GetNumDaysToNextBillingDate(int billingDayOfMonth)
{
    DateTime today = DateTime.Today;

    if (today.Day <= billingDayOfMonth)
    {
        return (new DateTime(today.Year, today.Month, billingDayOfMonth) - today).Days;
    }
    else
    {
        var oneMonthFromToday = today.AddMonths(1);

        var billingDateNextMonth = 
            new DateTime(oneMonthFromToday.Year, 
            oneMonthFromToday.Month, billingDayOfMonth);

        return (billingDateNextMonth - today).Days;
    }
}
rory.ap
  • 34,009
  • 10
  • 83
  • 174
  • 1
    I personally prefer this one, it seems to handle all the issues pointed out by the viewers. Thank you bro :) Thanks everyone else for your solutions as well! – Jay Aug 09 '16 at 15:05
  • You're welcome! Although it's more lines than some of the other answers, I think it's easier to understand which is important, too. It reads like a book. One-line statements can get confusing pretty quickly (especially when they wrap!). – rory.ap Aug 09 '16 at 15:11
2

How about:

int billingDay = 4;
DateTime today = DateTime.UtcNow;
DateTime billing = today.Day >= billingDay
                   ? new DateTime(today.AddMonths(1).Year, today.AddMonths(1).Month, billingDay)
                   : new DateTime(today.Year, today.Month, billingDay);
TimeSpan left = billing - today;
Matias Cicero
  • 25,439
  • 13
  • 82
  • 154
1

This link might help you :

https://msdn.microsoft.com/en-us/library/system.datetime.daysinmonth(v=vs.110).aspx

What you can do is something like this:

        int daysUntilBill = 0;
        int billingDay = 4;
        DateTime today = DateTime.Today;
        if (billingDay > today.Day) {
            daysUntilBill = billingDay - today.Day;
        } else {
            int daysLeftInMonth = DateTime.DaysInMonth(today.Year, today.Month) - today.Day;
            daysUntilBill = billingDay + daysLeftInMonth;
        }

or slightly more concise

        int daysUntilBill = (billingDay >= today.Day) 
            ? billingDay - today.Day 
            : billingDay + DateTime.DaysInMonth(today.Year, today.Month) - today.Day;

This properly handles the year ending too, since it doesn't try to wrap around.

D. Stewart
  • 471
  • 4
  • 15
1

First you need to determine if the current date is on or before the billing day and if it is just subtract the current day of the month. Otherwise you have to determine the next billing date in the following month.

public int DaysToNextBill(int billingDay)
{
    var today = DateTime.Today;

    if(today.Day <= billingDay)
        return billingDay - today.Day;

    var nextMonth = today.AddMonth(1);
    var nextBillingDate = new DateTime(nextMonth.Year, nextMonth.Month, billingDay)
    return (nextBillingDate - today).Days;
}

The only thing left to deal with is if billingDay is greater than the number of days in the current or following month.

juharr
  • 31,741
  • 4
  • 58
  • 93
1

This uses a loop but is less prone to error as it takes into account month and year changes:

    int DaysUntilBilling(int billingDay, DateTime referenceDate)
    {
        int count = 0;
        while (referenceDate.AddDays(count).Day != billingDay)
        {
            count++;               
        };
        return count;
    }

You of course don't need to pass a DateTime in as an argument if you are always using today's date, but this helps to test that that for different inputs, you get the desired output:

int billingDay = 4;
DaysUntilBilling(billingDay, DateTime.Now); //26 (today is 9th Aug 2016)
DaysUntilBilling(billingDay, new DateTime(2016, 09, 03); //1
DaysUntilBilling(billingDay, new DateTime(2016, 09, 04); //0
DaysUntilBilling(billingDay, new DateTime(2016, 08, 05); //30
DaysUntilBilling(billingDay, new DateTime(2016, 12, 19); //16
Matt Wilko
  • 26,994
  • 10
  • 93
  • 143