Months from Year Start.

Dear Experts,

I need to get the number of months from the date I specified my document, for example:

1)  If I create a document with a date of June 1, 2015, the number of months from 1/1/2015 is 5 (6/1/2015 -1/1/2015)

Can anyone help me dynamically compute it using C#.


Thanks.
JimiJ13I T ConsultantAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

sachiekCommented:
Two possible ways.

((date1.Year - date2.Year) * 12) + date1.Month - date2.Month

Open in new window


Or, assuming you want an approximate number of 'average months' between the two dates, the following should work for all but very huge date differences.

date1.Subtract(date2).Days / (365.25 / 12)

Open in new window

0
sachiekCommented:
With DateTimeSpan, similar to a TimeSpan, except that it includes all the date components in addition to the time components.

Usage:
void Main()
{
    DateTime compareTo = DateTime.Parse("8/13/2010 8:33:21 AM");
    DateTime now = DateTime.Parse("2/9/2012 10:10:11 AM");
    var dateSpan = DateTimeSpan.CompareDates(compareTo, now);
    Console.WriteLine("Years: " + dateSpan.Years);
    Console.WriteLine("Months: " + dateSpan.Months);
    Console.WriteLine("Days: " + dateSpan.Days);
    Console.WriteLine("Hours: " + dateSpan.Hours);
    Console.WriteLine("Minutes: " + dateSpan.Minutes);
    Console.WriteLine("Seconds: " + dateSpan.Seconds);
    Console.WriteLine("Milliseconds: " + dateSpan.Milliseconds);
}

Open in new window

0
sachiekCommented:
Timespan stuct as below

public struct DateTimeSpan 
{
    private readonly int years;
    private readonly int months;
    private readonly int days;
    private readonly int hours;
    private readonly int minutes;
    private readonly int seconds;
    private readonly int milliseconds;

    public DateTimeSpan(int years, int months, int days, int hours, int minutes, int seconds, int milliseconds)
    {
        this.years = years;
        this.months = months;
        this.days = days;
        this.hours = hours;
        this.minutes = minutes;
        this.seconds = seconds;
        this.milliseconds = milliseconds;
    }

    public int Years { get { return years; } }
    public int Months { get { return months; } }
    public int Days { get { return days; } }
    public int Hours { get { return hours; } }
    public int Minutes { get { return minutes; } }
    public int Seconds { get { return seconds; } }
    public int Milliseconds { get { return milliseconds; } }

    enum Phase { Years, Months, Days, Done }

    public static DateTimeSpan CompareDates(DateTime date1, DateTime date2) 
    {
        if (date2 < date1)
        {
            var sub = date1;
            date1 = date2;
            date2 = sub;
        }

        DateTime current = date1;
        int years = 0;
        int months = 0;
        int days = 0;

        Phase phase = Phase.Years;
        DateTimeSpan span = new DateTimeSpan();

        while (phase != Phase.Done) 
        {
            switch (phase) 
            {
                case Phase.Years:
                    if (current.AddYears(years + 1) > date2)
                    {
                        phase = Phase.Months;
                        current = current.AddYears(years);
                    }
                    else 
                    {
                        years++;
                    }
                    break;
                case Phase.Months:
                    if (current.AddMonths(months + 1) > date2) 
                    {
                        phase = Phase.Days;
                        current = current.AddMonths(months);
                    }
                    else 
                    {
                        months++;
                    }
                    break;
                case Phase.Days:
                    if (current.AddDays(days + 1) > date2) 
                    {
                        current = current.AddDays(days);
                        var timespan = date2 - current;
                        span = new DateTimeSpan(years, months, days, timespan.Hours, timespan.Minutes, timespan.Seconds, timespan.Milliseconds);
                        phase = Phase.Done;
                    }
                    else 
                    {
                        days++;
                    }
                    break;
            }
        }

        return span;
    }   
}

Open in new window

0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

sachiekCommented:
If you want only difference in the months then completely disregarding the date values.

Here is how can use this be done:

public static int MonthDifference(this DateTime lValue, DateTime rValue)
{
    return (lValue.Month - rValue.Month) + 12 * (lValue.Year - rValue.Year);
}

Open in new window


Returns a relative difference, meaning that if rValue is greater than lValue, then the return value will be negative. If you want an absolute difference, you can use this:

public static int MonthDifference(this DateTime lValue, DateTime rValue)
{
    return Math.Abs((lValue.Month - rValue.Month) + 12 * (lValue.Year - rValue.Year));
}

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Karrtik IyerSoftware ArchitectCommented:
I suggest you refer the below link and understand what infrastructure C# provides for date time manipulation.
https://msdn.microsoft.com/en-us/library/bb384267%28v=vs.110%29.aspx
0
Gustav BrockCIOCommented:
I believe you are looking for the count of "full months", not just the difference between calendar months.

The difference in calendar months is easy to find:
int months = (laterDate.Year - currentDate.Year) * 12 + laterDate.Month - currentDate.Month;

Open in new window


To find the difference in full months, use a method where you add the months to prevent errors when calculating on the ultimo dates of months, indeed for February:
        /// <summary>
        /// Calculates the difference in full months between the current System.DateTime object and a later date.
        /// </summary>
        /// <param name="currentDate">The date of birth.</param>
        /// <param name="laterDate">The date on which to calculate the age.</param>
        /// <returns>Difference in months to a later day. 0 is returned as minimum.</returns>
        public static int Months(this DateTime currentDate, DateTime laterDate)
        {
            int months;
            months = (laterDate.Year - currentDate.Year) * 12 + laterDate.Month - currentDate.Month;
            if (months > 0)
            {
                if (laterDate.Date < currentDate.Date.AddMonths(months))
                {
                    // The last month is not a full month.
                    // Reduce the month count by one.
                    months--;
                }
            }
            else
            {
                months = 0;
            }
            return months;
        }

Open in new window

This is an extension method to DateTime. Of course, you can remove static and this to use it as is.

If you wish a count in "decimal months" - which isn't an exact science but will show a difference if either date is moved just one day - you can use this method:
        /// <summary>
        /// Calculates the difference in decimal months between the current System.DateTime object and a later date.
        /// </summary>
        /// <param name="currentDate">The date of birth.</param>
        /// <param name="laterDate">The date on which to calculate the age.</param>
        /// <returns>Difference in decimal months to a later day. 0 is returned as minimum.</returns>
        public static double TotalMonths(DateTime currentDate, DateTime laterDate)
        {
            double months = 0;
            double firstPart = 0;
            double lastPart = 0;

            months = (laterDate.Year - currentDate.Year) * 12 + laterDate.Month - currentDate.Month;
            if (months > 0)
            {
                firstPart = (double)currentDate.Day / DateTime.DaysInMonth(currentDate.Year, currentDate.Month);
                lastPart = (double)laterDate.Day / DateTime.DaysInMonth(laterDate.Year, laterDate.Month);
            }
            else
            {
                months = 0;
            }
            return months - firstPart + lastPart;
        }

Open in new window

Of course, this can be turned into an extension of DateTime should you prefer so.

/gustav
0
JimiJ13I T ConsultantAuthor Commented:
Thanks sachiek! This particular solution was tested and works best for me.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.