Difference in months between two dates

前端 未结 30 1183
天命终不由人
天命终不由人 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:45

    This is from my own library, will return the difference of months between two dates.

    public static int MonthDiff(DateTime d1, DateTime d2)
    {
        int retVal = 0;
    
        // Calculate the number of years represented and multiply by 12
        // Substract the month number from the total
        // Substract the difference of the second month and 12 from the total
        retVal = (d1.Year - d2.Year) * 12;
        retVal = retVal - d1.Month;
        retVal = retVal - (12 - d2.Month);
    
        return retVal;
    }
    
    0 讨论(0)
  • 2020-11-22 11:47

    If you want the exact number of full months, always positive (2000-01-15, 2000-02-14 returns 0), considering a full month is when you reach the same day the next month (something like the age calculation)

    public static int GetMonthsBetween(DateTime from, DateTime to)
    {
        if (from > to) return GetMonthsBetween(to, from);
    
        var monthDiff = Math.Abs((to.Year * 12 + (to.Month - 1)) - (from.Year * 12 + (from.Month - 1)));
    
        if (from.AddMonths(monthDiff) > to || to.Day < from.Day)
        {
            return monthDiff - 1;
        }
        else
        {
            return monthDiff;
        }
    }
    

    Edit reason: the old code was not correct in some cases like :

    new { From = new DateTime(1900, 8, 31), To = new DateTime(1901, 8, 30), Result = 11 },
    
    Test cases I used to test the function:
    
    var tests = new[]
    {
        new { From = new DateTime(1900, 1, 1), To = new DateTime(1900, 1, 1), Result = 0 },
        new { From = new DateTime(1900, 1, 1), To = new DateTime(1900, 1, 2), Result = 0 },
        new { From = new DateTime(1900, 1, 2), To = new DateTime(1900, 1, 1), Result = 0 },
        new { From = new DateTime(1900, 1, 1), To = new DateTime(1900, 2, 1), Result = 1 },
        new { From = new DateTime(1900, 2, 1), To = new DateTime(1900, 1, 1), Result = 1 },
        new { From = new DateTime(1900, 1, 31), To = new DateTime(1900, 2, 1), Result = 0 },
        new { From = new DateTime(1900, 8, 31), To = new DateTime(1900, 9, 30), Result = 0 },
        new { From = new DateTime(1900, 8, 31), To = new DateTime(1900, 10, 1), Result = 1 },
        new { From = new DateTime(1900, 1, 1), To = new DateTime(1901, 1, 1), Result = 12 },
        new { From = new DateTime(1900, 1, 1), To = new DateTime(1911, 1, 1), Result = 132 },
        new { From = new DateTime(1900, 8, 31), To = new DateTime(1901, 8, 30), Result = 11 },
    };
    
    0 讨论(0)
  • 2020-11-22 11:49

    Based on the excellent DateTimeSpan work done above, I've normalized the code a bit; this seems to work pretty well:

    public class DateTimeSpan
    {
      private DateTimeSpan() { }
    
      private DateTimeSpan(int years, int months, int days, int hours, int minutes, int seconds, int milliseconds)
      {
        Years = years;
        Months = months;
        Days = days;
        Hours = hours;
        Minutes = minutes;
        Seconds = seconds;
        Milliseconds = milliseconds;
      }
    
      public int Years { get; private set; } = 0;
      public int Months { get; private set; } = 0;
      public int Days { get; private set; } = 0;
      public int Hours { get; private set; } = 0;
      public int Minutes { get; private set; } = 0;
      public int Seconds { get; private set; } = 0;
      public int Milliseconds { get; private set; } = 0;
    
      public static DateTimeSpan CompareDates(DateTime StartDate, DateTime EndDate)
      {
        if (StartDate.Equals(EndDate)) return new DateTimeSpan();
        DateTimeSpan R = new DateTimeSpan();
        bool Later;
        if (Later = StartDate > EndDate)
        {
          DateTime D = StartDate;
          StartDate = EndDate;
          EndDate = D;
        }
    
        // Calculate Date Stuff
        for (DateTime D = StartDate.AddYears(1); D < EndDate; D = D.AddYears(1), R.Years++) ;
        if (R.Years > 0) StartDate = StartDate.AddYears(R.Years);
        for (DateTime D = StartDate.AddMonths(1); D < EndDate; D = D.AddMonths(1), R.Months++) ;
        if (R.Months > 0) StartDate = StartDate.AddMonths(R.Months);
        for (DateTime D = StartDate.AddDays(1); D < EndDate; D = D.AddDays(1), R.Days++) ;
        if (R.Days > 0) StartDate = StartDate.AddDays(R.Days);
    
        // Calculate Time Stuff
        TimeSpan T1 = EndDate - StartDate;
        R.Hours = T1.Hours;
        R.Minutes = T1.Minutes;
        R.Seconds = T1.Seconds;
        R.Milliseconds = T1.Milliseconds;
    
        // Return answer. Negate values if the Start Date was later than the End Date
        if (Later)
          return new DateTimeSpan(-R.Years, -R.Months, -R.Days, -R.Hours, -R.Minutes, -R.Seconds, -R.Milliseconds);
        return R;
      }
    }
    
    0 讨论(0)
  • 2020-11-22 11:51

    You can use Noda Time https://nodatime.org/

    LocalDate start = new LocalDate(2010, 1, 5);
    LocalDate end = new LocalDate(2012, 6, 1);
    Period period = Period.Between(start, end, PeriodUnits.Months);
    Console.WriteLine(period.Months);
    
    0 讨论(0)
  • 2020-11-22 11:52

    Here is a simple solution that works at least for me. It's probably not the fastest though because it uses the cool DateTime's AddMonth feature in a loop:

    public static int GetMonthsDiff(DateTime start, DateTime end)
    {
        if (start > end)
            return GetMonthsDiff(end, start);
    
        int months = 0;
        do
        {
            start = start.AddMonths(1);
            if (start > end)
                return months;
    
            months++;
        }
        while (true);
    }
    
    0 讨论(0)
  • 2020-11-22 11:53

    you can use the following extension: Code

    public static class Ext
    {
        #region Public Methods
    
        public static int GetAge(this DateTime @this)
        {
            var today = DateTime.Today;
            return ((((today.Year - @this.Year) * 100) + (today.Month - @this.Month)) * 100 + today.Day - @this.Day) / 10000;
        }
    
        public static int DiffMonths(this DateTime @from, DateTime @to)
        {
            return (((((@to.Year - @from.Year) * 12) + (@to.Month - @from.Month)) * 100 + @to.Day - @from.Day) / 100);
        }
    
        public static int DiffYears(this DateTime @from, DateTime @to)
        {
            return ((((@to.Year - @from.Year) * 100) + (@to.Month - @from.Month)) * 100 + @to.Day - @from.Day) / 10000;
        }
    
        #endregion Public Methods
    }
    

    Implementation !

    int Age;
    int years;
    int Months;
    //Replace your own date
    var d1 = new DateTime(2000, 10, 22);
    var d2 = new DateTime(2003, 10, 20);
    //Age
    Age = d1.GetAge();
    Age = d2.GetAge();
    //positive
    years = d1.DiffYears(d2);
    Months = d1.DiffMonths(d2);
    //negative
    years = d2.DiffYears(d1);
    Months = d2.DiffMonths(d1);
    //Or
    Months = Ext.DiffMonths(d1, d2);
    years = Ext.DiffYears(d1, d2); 
    
    0 讨论(0)
提交回复
热议问题