Difference in months between two dates

前端 未结 30 1182
天命终不由人
天命终不由人 2020-11-22 11:02

How to calculate the difference in months between two dates in C#?

Is there is equivalent of VB\'s DateDiff() method in C#. I need to find difference in

相关标签:
30条回答
  • 2020-11-22 11:37

    This is in response to Kirk Woll's answer. I don't have enough reputation points to reply to a comment yet...

    I liked Kirk's solution and was going to shamelessly rip it off and use it in my code, but when I looked through it I realized it's way too complicated. Unnecessary switching and looping, and a public constructor that is pointless to use.

    Here's my rewrite:

    public class DateTimeSpan {
        private DateTime _date1;
        private DateTime _date2;
        private int _years;
        private int _months;
        private int _days;
        private int _hours;
        private int _minutes;
        private int _seconds;
        private int _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; } }
    
        public DateTimeSpan(DateTime date1, DateTime date2) {
            _date1 = (date1 > date2) ? date1 : date2;
            _date2 = (date2 < date1) ? date2 : date1;
    
            _years = _date1.Year - _date2.Year;
            _months = (_years * 12) + _date1.Month - _date2.Month;
            TimeSpan t = (_date2 - _date1);
            _days = t.Days;
            _hours = t.Hours;
            _minutes = t.Minutes;
            _seconds = t.Seconds;
            _milliseconds = t.Milliseconds;
    
        }
    
        public static DateTimeSpan CompareDates(DateTime date1, DateTime date2) {
            return new DateTimeSpan(date1, date2);
        }
    }
    

    Usage1, pretty much the same:

    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 = new DateTimeSpan(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);
    }
    

    Usage2, similar:

    void Main()
    {
        DateTime compareTo = DateTime.Parse("8/13/2010 8:33:21 AM");
        DateTime now = DateTime.Parse("2/9/2012 10:10:11 AM");
        Console.WriteLine("Years: " + DateTimeSpan.CompareDates(compareTo, now).Years);
        Console.WriteLine("Months: " + DateTimeSpan.CompareDates(compareTo, now).Months);
        Console.WriteLine("Days: " + DateTimeSpan.CompareDates(compareTo, now).Days);
        Console.WriteLine("Hours: " + DateTimeSpan.CompareDates(compareTo, now).Hours);
        Console.WriteLine("Minutes: " + DateTimeSpan.CompareDates(compareTo, now).Minutes);
        Console.WriteLine("Seconds: " + DateTimeSpan.CompareDates(compareTo, now).Seconds);
        Console.WriteLine("Milliseconds: " + DateTimeSpan.CompareDates(compareTo, now).Milliseconds);
    }
    
    0 讨论(0)
  • 2020-11-22 11:38

    Here is my contribution to get difference in Months that I've found to be accurate:

    namespace System
    {
         public static class DateTimeExtensions
         {
             public static Int32 DiffMonths( this DateTime start, DateTime end )
             {
                 Int32 months = 0;
                 DateTime tmp = start;
    
                 while ( tmp < end )
                 {
                     months++;
                     tmp = tmp.AddMonths( 1 );
                 }
    
                 return months;
            }
        }
    }
    

    Usage:

    Int32 months = DateTime.Now.DiffMonths( DateTime.Now.AddYears( 5 ) );
    

    You can create another method called DiffYears and apply exactly the same logic as above and AddYears instead of AddMonths in the while loop.

    0 讨论(0)
  • 2020-11-22 11:40

    Assuming the day of the month is irrelevant (i.e. the diff between 2011.1.1 and 2010.12.31 is 1), with date1 > date2 giving a positive value and date2 > date1 a negative value

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

    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)
    

    Note, if you were to use the latter solution then your unit tests should state the widest date range which your application is designed to work with and validate the results of the calculation accordingly.


    Update (with thanks to Gary)

    If using the 'average months' method, a slightly more accurate number to use for the 'average number of days per year' is 365.2425.

    0 讨论(0)
  • 2020-11-22 11:40

    You could do

    if ( date1.AddMonths(x) > date2 )
    
    0 讨论(0)
  • 2020-11-22 11:40
    Public Class ClassDateOperation
        Private prop_DifferenceInDay As Integer
        Private prop_DifferenceInMonth As Integer
        Private prop_DifferenceInYear As Integer
    
    
        Public Function DayMonthYearFromTwoDate(ByVal DateStart As Date, ByVal DateEnd As Date) As ClassDateOperation
            Dim differenceInDay As Integer
            Dim differenceInMonth As Integer
            Dim differenceInYear As Integer
            Dim myDate As Date
    
            DateEnd = DateEnd.AddDays(1)
    
            differenceInYear = DateEnd.Year - DateStart.Year
    
            If DateStart.Month <= DateEnd.Month Then
                differenceInMonth = DateEnd.Month - DateStart.Month
            Else
                differenceInYear -= 1
                differenceInMonth = (12 - DateStart.Month) + DateEnd.Month
            End If
    
    
            If DateStart.Day <= DateEnd.Day Then
                differenceInDay = DateEnd.Day - DateStart.Day
            Else
    
                myDate = CDate("01/" & DateStart.AddMonths(1).Month & "/" & DateStart.Year).AddDays(-1)
                If differenceInMonth <> 0 Then
                    differenceInMonth -= 1
                Else
                    differenceInMonth = 11
                    differenceInYear -= 1
                End If
    
                differenceInDay = myDate.Day - DateStart.Day + DateEnd.Day
    
            End If
    
            prop_DifferenceInDay = differenceInDay
            prop_DifferenceInMonth = differenceInMonth
            prop_DifferenceInYear = differenceInYear
    
            Return Me
        End Function
    
        Public ReadOnly Property DifferenceInDay() As Integer
            Get
                Return prop_DifferenceInDay
            End Get
        End Property
    
        Public ReadOnly Property DifferenceInMonth As Integer
            Get
                Return prop_DifferenceInMonth
            End Get
        End Property
    
        Public ReadOnly Property DifferenceInYear As Integer
            Get
                Return prop_DifferenceInYear
            End Get
        End Property
    
    End Class
    
    0 讨论(0)
  • 2020-11-22 11:40

    There's 3 cases: same year, previous year and other years.

    If the day of the month does not matter...

    public int GetTotalNumberOfMonths(DateTime start, DateTime end)
    {
        // work with dates in the right order
        if (start > end)
        {
            var swapper = start;
            start = end;
            end = swapper;
        }
    
        switch (end.Year - start.Year)
        {
            case 0: // Same year
                return end.Month - start.Month;
    
            case 1: // last year
                return (12 - start.Month) + end.Month;
    
            default:
                return 12 * (3 - (end.Year - start.Year)) + (12 - start.Month) + end.Month;
        }
    }
    
    0 讨论(0)
提交回复
热议问题