1

I am developing a interest calculator in C#. I need to know the number of days between 2 dates

So, I am calculating something like this :

    DateTime dt1 = DateTime.ParseExact(DateTime.Now.Date.ToString("dd-MM-yy"), "dd-MM-yy", CultureInfo.InvariantCulture).Date;
    DateTime dt2 = DateTime.ParseExact(Duration, "dd-MM-yy", CultureInfo.InvariantCulture).Date;

    Double no_days = (dt1 - dt2).TotalDays;

However, depending on the month, the number of days would vary. So, Feb 15 to Mar 15 constitute a month even though the number of days is less than 30.

Any ide how I can determine the number of months elapsed ? The interest calculation is done at the end of the month duration.

Thanks

Kiran
  • 8,034
  • 36
  • 110
  • 176

4 Answers4

8

I can't think of any cleaner way than this:

((dt1.Year - dt2.Year) * 12) + (dt1.Month - dt2.Month) - (dt1.Day < dt2.Day?1:0);

And even then, I'm not sure if I've maybe missed some edge cases.

Damien_The_Unbeliever
  • 234,701
  • 27
  • 340
  • 448
1

There are not a lot of clear answers on this because you are always assuming things.

This solution calculates between two dates the months between assuming you want to save the day of month for comparison, (meaning that the day of the month is considered in the calculation)

Example, if you have a date of 30 Jan 2012, 29 Feb 2012 will not be a month but 01 March 2013 will.

It's been tested pretty thoroughly, probably will clean it up later as we use it, but here:

private static int TotalMonthDifference(DateTime dtThis, DateTime dtOther)
{
    int intReturn = 0;
    bool sameMonth = false;

    if (dtOther.Date < dtThis.Date) //used for an error catch in program, returns -1
        intReturn--;

    int dayOfMonth = dtThis.Day; //captures the month of day for when it adds a month and doesn't have that many days
    int daysinMonth = 0; //used to caputre how many days are in the month

    while (dtOther.Date > dtThis.Date) //while Other date is still under the other
    {
        dtThis = dtThis.AddMonths(1); //as we loop, we just keep adding a month for testing
        daysinMonth = DateTime.DaysInMonth(dtThis.Year, dtThis.Month); //grabs the days in the current tested month

        if (dtThis.Day != dayOfMonth) //Example 30 Jan 2013 will go to 28 Feb when a month is added, so when it goes to march it will be 28th and not 30th
        {
            if (daysinMonth < dayOfMonth) // uses day in month max if can't set back to day of month
                dtThis.AddDays(daysinMonth - dtThis.Day);
            else
                dtThis.AddDays(dayOfMonth - dtThis.Day);
        }
        if (((dtOther.Year == dtThis.Year) && (dtOther.Month == dtThis.Month))) //If the loop puts it in the same month and year
        {
            if (dtOther.Day >= dayOfMonth) //check to see if it is the same day or later to add one to month
                intReturn++;
            sameMonth = true; //sets this to cancel out of the normal counting of month
        }
        if ((!sameMonth)&&(dtOther.Date > dtThis.Date))//so as long as it didn't reach the same month (or if i started in the same month, one month ahead, add a month)
            intReturn++;
    }
    return intReturn; //return month
}
GreatNate
  • 191
  • 8
0

I ended up writing my own routine. I hope it will help others. Let me know if there is a easier way to calculate the months between 2 dates.

DateTime dt1 = DateTime.ParseExact(DateTime.Now.Date.ToString("dd-MM-yy"), "dd-MM-yy", CultureInfo.InvariantCulture).Date;
DateTime dt2 = DateTime.ParseExact(Duration, "dd-MM-yy", CultureInfo.InvariantCulture).Date;

DateTime temp = dt2;
int no_months = 0;
while ((dt1 - temp).TotalDays > 0)
{
    temp = temp.AddMonths(1);
    no_months++;
}

if (no_months > 0)
{
    no_months = no_months - 1;
}

Thanks

Kiran
  • 8,034
  • 36
  • 110
  • 176
0
int MonthsElapsed = ((DateB.AddDays(1).Year - DateA.AddDays(1).Year) * 12) +
                    (DateB.AddDays(1).Month - DateA.AddDays(1).Month) -
                    (DateB.AddDays(1).Day < DateA.AddDays(1).Day ? 1 : 0);

This formula is making some assumptions:

  1. A full month is the span between the day of DateA and the same day of a future month. (e.g., 1/15-2/15 = 1 month, 1/15-3/15 = 2 months, et seq.) We'll call this the trigger date.
  2. The last day of any month that does not contain the trigger date is equivalent to the trigger date. (1/28...1/31 through 2/28 are all equivalent to 1 month.)
  3. The first elapsed month occurs after 1 full month has passed. (When I do interest calculations, the first month of interest accrues on DateA, so I add 1 to this formula.)

The .AddDays(1) is used to account for end-of-month scenarios where a DateB doesn't contain the trigger day. I can't think of a more graceful, in-line method of accounting for that.

StrykerJW
  • 21
  • 4