Jay
Jay

Reputation: 5084

Calculating days left until the next specified day

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 :)

Upvotes: 2

Views: 592

Answers (5)

juharr
juharr

Reputation: 32276

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.

Upvotes: 1

D. Stewart
D. Stewart

Reputation: 471

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.

Upvotes: 1

Matt Wilko
Matt Wilko

Reputation: 27322

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

Upvotes: 1

rory.ap
rory.ap

Reputation: 35280

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;
    }
}

Upvotes: 3

Matias Cicero
Matias Cicero

Reputation: 26281

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;

Upvotes: 2

Related Questions