【问题标题】:Difference in months between two dates两个日期之间的月差
【发布时间】:2011-06-06 01:21:12
【问题描述】:

C#中如何计算两个日期的月差?

C# 中是否有等效于 VB 的 DateDiff() 方法。我需要找到相隔数年的两个日期之间的月份差异。文档说我可以使用TimeSpan,例如:

TimeSpan ts = date1 - date2;

但这给了我以天为单位的数据。 我不想把这个数字除以 30,因为不是每个月都是 30 天,而且由于两个操作数的值彼此相差很大,恐怕除以 30 可能会给我一个错误的值.

有什么建议吗?

【问题讨论】:

  • 定义“月差”,“May 1,2010”和“June 16,2010”的月差是多少? 1.5、1 还是其他?
  • 或者,为了进一步强调这一点,2010 年 12 月 31 日和 2011 年 1 月 1 日之间的月份差异是多少?根据白天的不同,这可能只有 1 秒的差异;你会把这算作相差一个月吗?
  • 这里是简单而简短的代码,以防万一,你仍然无法得到答案,看这个POSTstackoverflow.com/questions/8820603/…
  • 丹尼:1 个月零 15 天。 stakx:0个月零1天。重点是获取 month 组件。这对我来说似乎很明显,是一个很好的问题。

标签: c# .net vb.net date


【解决方案1】:

我正在从事一个项目,该项目只需要几年和几个月的时间。这是一个可能有帮助的解决方案。

/// <summary>
/// Get the total months between two date.  This will count whole months and not care about the day.
/// </summary>
/// <param name="firstDate">First date.</param>
/// <param name="lastDate">Last date.</param>
/// <returns>Number of month apart.</returns>
private static int GetTotalMonths(DateOnly firstDate, DateOnly lastDate)
{
    int yearsAppart = lastDate.Year - firstDate.Year;
    int monthsAppart = lastDate.Month - firstDate.Month;
    return (yearsAppart * 12) + monthsAppart;
}

private static int GetTotalMonths(DateTime firstDate, DateTime lastDate)
{
    return GetTotalMonths(DateOnly.FromDateTime(firstDate), DateOnly.FromDateTime(lastDate));
}

【讨论】:

    【解决方案2】:

    单线解决方案

    首先,检查两个日期是否都在当前年份,如果不是,则获取整年的月份,然后从开始和结束年份添加月份。

    DateTime dateFrom = new DateTime(2019, 2, 1);
    DateTime dateTo = new DateTime(2021, 5, 25);
    

    第一个月

    var monthCount = dateFrom.Year != dateTo.Year ? ((dateTo.Year - dateFrom.Year - 1) * 12) + (13 - dateFrom.Month + dateTo.Month) : dateTo.Month - dateFrom.Month + 1;
    

    结果 = 28

    没有第一个月

    monthCount = dateFrom.Year != dateTo.Year ? ((dateTo.Year - dateFrom.Year - 1) * 12) + (12 - dateFrom.Month + dateTo.Month) : dateTo.Month - dateFrom.Month;
    

    结果 = 27

    【讨论】:

      【解决方案3】:

      如果您只关心月份和年份,并且想要同时触摸两个日期(例如,您想要通过 JAN/2021 到 AGO/2022),您可以使用这个:

      int numberOfMonths= (Year2 > Year1 ? ( Year2 - Year1 - 1) * 12 + (12 - Month1) + Month2 + 1 : Month2 - Month1 + 1); 
      

      例子:

      Year1/Month1: 2021/10   
      Year2/Month2: 2022/08   
      numberOfMonths = 11;
      

      或同一年:

      Year1/Month1: 2021/10   
      Year2/Month2: 2021/12   
      numberOfMonths = 3;
      

      如果您只想触摸其中一个,请同时删除 + 1。

      【讨论】:

        【解决方案4】:

        计算所有天数的疯狂方法,非常精确

        帮助类:

        public class DaysInMonth
        {
            public int Days { get; set; }
            public int Month { get; set; }
            public int Year { get; set; }
            public bool Full { get; set; }
        }
        

        功能:

            public static List<DaysInMonth> MonthsDelta(DateTime start, DateTime end)
            {
                
                var dates = Enumerable.Range(0, 1 + end.Subtract(start).Days)
                  .Select(offset => start.AddDays(offset))
                  .ToArray();
        
                DateTime? prev = null;
                int days = 0;
        
                List < DaysInMonth > list = new List<DaysInMonth>();
        
                foreach (DateTime date in dates)
                {
                    if (prev != null)
                    {
                        if(date.Month!=prev.GetValueOrDefault().Month)
                        {
                            DaysInMonth daysInMonth = new DaysInMonth();
                            daysInMonth.Days = days;
                            daysInMonth.Month = prev.GetValueOrDefault().Month;
                            daysInMonth.Year = prev.GetValueOrDefault().Year;
                            daysInMonth.Full = DateTime.DaysInMonth(daysInMonth.Year, daysInMonth.Month) == daysInMonth.Days;
                            list.Add(daysInMonth);
                            days = 0;
                        }
                    }
                    days++;
                    prev = date;
                }
        
                //------------------ add last
                if (days > 0)
                {
                    DaysInMonth daysInMonth = new DaysInMonth();
                    daysInMonth.Days = days;
                    daysInMonth.Month = prev.GetValueOrDefault().Month;
                    daysInMonth.Year = prev.GetValueOrDefault().Year;
                    daysInMonth.Full = DateTime.DaysInMonth(daysInMonth.Year, daysInMonth.Month) == daysInMonth.Days;
                    list.Add(daysInMonth);
                }
        
                return list;
            }
        

        【讨论】:

          【解决方案5】:

          除了所有给出的答案,我发现这段代码非常简单。由于 DateTime.MinValue 是 1/1/1,我们必须从月、年和日中减去 1。

          var timespan = endDate.Subtract(startDate);
          var tempdate = DateTime.MinValue + timespan;
          
          var totalMonths = (tempdate.Year - 1) * 12 + tempdate.Month - 1;
          
          var totalDays = tempdate.Day - 1;
          if (totalDays > 0)
          {
              totalMonths = totalMonths + 1;
          }
          

          【讨论】:

            【解决方案6】:

            您可以使用野田时间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);
            

            【讨论】:

              【解决方案7】:

              这个简单的静态函数计算两个日期时间之间的月份分数,例如

              • 1.1。到 31.1。 = 1.0
              • 1.4。到 15.4。 = 0.5
              • 16.4。到 30.4。 = 0.5
              • 1.3。到 1.4。 = 1 + 1/30

              该函数假定第一个日期小于第二个日期。为了处理负时间间隔,可以通过在开头引入符号和变量交换来轻松修改函数。

              public static double GetDeltaMonths(DateTime t0, DateTime t1)
              {
                   DateTime t = t0;
                   double months = 0;
                   while(t<=t1)
                   {
                       int daysInMonth = DateTime.DaysInMonth(t.Year, t.Month);
                       DateTime endOfMonth = new DateTime(t.Year, t.Month, daysInMonth);
                       int cutDay = endOfMonth <= t1 ? daysInMonth : t1.Day;
                       months += (cutDay - t.Day + 1) / (double) daysInMonth;
                       t = new DateTime(t.Year, t.Month, 1).AddMonths(1);
                   }
                   return Math.Round(months,2);
               }
              

              【讨论】:

                【解决方案8】:

                似乎 DateTimeSpan 解决方案让很多人满意。我不知道。让我们考虑一下:

                开始日期 = 1972/2/29 结束日期 = 1972/4/28。

                基于 DateTimeSpan 的答案是:

                1 年、2 个月和 0 天

                我实现了一个方法,并基于此答案是:

                1 年 1 个月 28 天

                显然那里没有整整两个月。我想说,因为我们在开始日期的月底,所以剩下的实际上是整个 3 月加上结束日期(4 月)当月过去的天数,所以 1 个月和 28 天。

                如果您到目前为止阅读并感兴趣,我在下面发布了方法。我在 cmets 中解释我所做的假设,因为几个月的概念是一个移动的目标。多次测试,看看答案是否有意义。我通常选择相邻年份的考试日期,一旦我验证答案,我就会来回移动一两天。到目前为止它看起来不错,我相信你会发现一些错误:D。代码可能看起来有点粗糙,但我希望它足够清晰:

                static void Main(string[] args) {
                        DateTime EndDate = new DateTime(1973, 4, 28);
                        DateTime BeginDate = new DateTime(1972, 2, 29);
                        int years, months, days;
                        GetYearsMonthsDays(EndDate, BeginDate, out years, out months, out days);
                        Console.WriteLine($"{years} year(s), {months} month(s) and {days} day(s)");
                    }
                
                    /// <summary>
                    /// Calculates how many years, months and days are between two dates.
                    /// </summary>
                    /// <remarks>
                    /// The fundamental idea here is that most of the time all of us agree
                    /// that a month has passed today since the same day of the previous month.
                    /// A particular case is when both days are the last days of their respective months 
                    /// when again we can say one month has passed.
                    /// In the following cases the idea of a month is a moving target.
                    /// - When only the beginning date is the last day of the month then we're left just with 
                    /// a number of days from the next month equal to the day of the month that end date represent
                    /// - When only the end date is the last day of its respective month we clearly have a 
                    /// whole month plus a few days after the the day of the beginning date until the end of its
                    /// respective months
                    /// In all the other cases we'll check
                    /// - beginingDay > endDay -> less then a month just daysToEndofBeginingMonth + dayofTheEndMonth
                    /// - beginingDay < endDay -> full month + (endDay - beginingDay)
                    /// - beginingDay == endDay -> one full month 0 days
                    /// 
                    /// </remarks>
                    /// 
                    private static void GetYearsMonthsDays(DateTime EndDate, DateTime BeginDate, out int years, out int months, out int days ) {
                        var beginMonthDays = DateTime.DaysInMonth(BeginDate.Year, BeginDate.Month);
                        var endMonthDays = DateTime.DaysInMonth(EndDate.Year, EndDate.Month);
                        // get the full years
                        years = EndDate.Year - BeginDate.Year - 1;
                        // how many full months in the first year
                        var firstYearMonths = 12 - BeginDate.Month;
                        // how many full months in the last year
                        var endYearMonths = EndDate.Month - 1;
                        // full months
                        months = firstYearMonths + endYearMonths;           
                        days = 0;
                        // Particular end of month cases
                        if(beginMonthDays == BeginDate.Day && endMonthDays == EndDate.Day) {
                            months++;
                        }
                        else if(beginMonthDays == BeginDate.Day) {
                            days += EndDate.Day;
                        }
                        else if(endMonthDays == EndDate.Day) {
                            days += beginMonthDays - BeginDate.Day;
                        }
                        // For all the other cases
                        else if(EndDate.Day > BeginDate.Day) {
                            months++;
                            days += EndDate.Day - BeginDate.Day;
                        }
                        else if(EndDate.Day < BeginDate.Day) {                
                            days += beginMonthDays - BeginDate.Day;
                            days += EndDate.Day;
                        }
                        else {
                            months++;
                        }
                        if(months >= 12) {
                            years++;
                            months = months - 12;
                        }
                    }
                

                【讨论】:

                  【解决方案9】:

                  这个解决方案解决了我的问题:

                  static void Main(string[] args)
                          {
                              var date1 = new DateTime(2018, 12, 05);
                              var date2 = new DateTime(2019, 03, 01);
                  
                              int CountNumberOfMonths() => (date2.Month - date1.Month) + 12 * (date2.Year - date1.Year);
                  
                              var numberOfMonths = CountNumberOfMonths();
                  
                              Console.WriteLine("Number of months between {0} and {1}: {2} months.", date1.ToString(), date2.ToString(), numberOfMonths.ToString());
                  
                              Console.ReadKey();
                  
                              //
                              // *** Console Output:
                              // Number of months between 05/12/2018 00:00:00 and 01/03/2019 00:00:00: 3 months.
                              //
                  
                          }
                  

                  【讨论】:

                    【解决方案10】:

                    简单快速地计算两个日期之间的总月数。 如果您只想获得不同的月份,而不是计算起始日期中的月份 - 只需从代码中删除 +1。

                    public static int GetTotalMonths(DateTime From, DateTime Till)
                            {
                                int MonthDiff = 0;
                    
                                for (int i = 0; i < 12; i++)
                                {
                                    if (From.AddMonths(i).Month == Till.Month)
                                    {
                                        MonthDiff = i + 1;
                                        break;
                                    }
                                }
                    
                                return MonthDiff;
                            }
                    

                    【讨论】:

                      【解决方案11】:

                      基于上述出色的 DateTimeSpan 工作,我对代码进行了一些规范化;这似乎工作得很好:

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

                      【讨论】:

                      • 当与CompareDates(x, y)比较时x={01/02/2019 00:00:00}y={01/05/2020 00:00:00}然后Months给我2
                      【解决方案12】:

                      这是一个返回DateTimeSpan 的综合解决方案,类似于TimeSpan,除了它包括除时间组件之外的所有日期组件。

                      用法:

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

                      输出:

                      年数:1
                      月数:5
                      天数:27
                      营业时间:1
                      分钟:36
                      秒数:50
                      毫秒:0

                      为方便起见,我将逻辑集中到 DateTimeSpan 结构中,但您可以将方法 CompareDates 移动到任何您认为合适的位置。另请注意,哪个日期早于另一个日期并不重要。

                      public struct DateTimeSpan
                      {
                          public int Years { get; }
                          public int Months { get; }
                          public int Days { get; }
                          public int Hours { get; }
                          public int Minutes { get; }
                          public int Seconds { get; }
                          public int Milliseconds { get; }
                      
                          public 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;
                          }
                      
                          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();
                              int officialDay = current.Day;
                      
                              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);
                                              if (current.Day < officialDay && officialDay <= DateTime.DaysInMonth(current.Year, current.Month))
                                                  current = current.AddDays(officialDay - current.Day);
                                          }
                                          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;
                          }
                      }
                      

                      【讨论】:

                      • @KirkWoll 谢谢。但是为什么 DateTimeSpan 返回 34 days 这个日期时差实际上是 35 timeanddate.com/date/…
                      • @Deeptechtons,不错。您提请我注意了几个问题,都与开始日期有关 31 和日期“经过”几个月而天数更少。我已经颠倒了逻辑(因此它从早到晚,反之亦然),现在在不修改当前日期的情况下累积月份(因此通过中间月份的天数更少)仍然不完全确定理想的结果是什么应该是在比较 10/31/201211/30/2012 时。现在结果是1 月。
                      • @KirkWoll 感谢您的更新,也许我还有一些问题让我在一些测试后确认它干得好:)
                      • 我为一个类似的问题写了一个答案stackoverflow.com/a/17537472/1737957,该问题测试了建议的答案(并发现它们中的大多数都不起作用)。这个答案是少数有效的答案之一(根据我的测试套件)。在我的回答中链接到 github。
                      • @KirkWoll - 此答案似乎不适用于起始日期的日期值高于截止日期的月份或源日期是闰日的极端情况。尝试2020-02-292021-06-29 - 它返回“1y 4m 1d”,但值应该是“1y 4m 0d”,对吧?
                      【解决方案13】:
                      public partial class Form1 : Form
                      {
                          public Form1()
                          {
                              InitializeComponent();
                          }
                      
                          private void button1_Click(object sender, EventArgs e)
                          {
                      
                              label3.Text = new DateDifference(Convert.ToDateTime("2018-09-13"), Convert.ToDateTime("2018-11-15")).ToString();
                              label2.Text = new DateDifference(Convert.ToDateTime("2018-10-12"), Convert.ToDateTime("2018-11-15")).ToString();
                      
                              DateDifference oDateDifference = new DateDifference(Convert.ToDateTime("2018-11-12"));
                             label1.Text  =   oDateDifference.ToString();
                      
                          }
                      }
                      
                      
                      
                      
                      public class DateDifference
                      {
                          public DateTime start { get; set; }
                          public DateTime currentDAte { get; set; }
                          public DateTime origstart { get; set; }
                          public DateTime origCurrentDAte { get; set; }
                      
                          int days { get; set; }
                          int months { get; set; }
                          int years { get; set; }
                      
                          public DateDifference(DateTime postedDate, DateTime currentDAte)
                          {
                              this.start = this.removeTime(postedDate);
                              this.currentDAte = this.removeTime(currentDAte);
                              this.origstart = postedDate;
                              this.origCurrentDAte = currentDAte;
                      
                          }
                      
                          public DateDifference(DateTime postedDate)
                          {
                              DateTime currentDate_ = DateTime.Now;
                              this.start = this.removeTime(postedDate);
                              this.currentDAte = this.removeTime(currentDate_);
                              this.origstart = postedDate;
                              this.origCurrentDAte = currentDate_;
                              if (start > this.currentDAte)
                              {
                                  throw new Exception("Current date is greater than date posted");
                              }
                              this.compute();
                          }
                      
                          void compute()
                          {
                              while (this.start.Year <= this.currentDAte.Year)
                              {
                                  if (this.start.Year <= this.currentDAte.Year && (this.start.AddMonths(1) <= this.currentDAte))
                                  {
                                      ++this.months;
                                      this.start = this.start.AddMonths(1);
                                  }
                      
                                  if ((this.start.Year == this.currentDAte.Year) && (this.start >= this.currentDAte.AddMonths(-1) && this.start <= this.currentDAte))
                                  {
                                      break;
                                  }
                              }
                      
                              while (this.start.DayOfYear < this.currentDAte.DayOfYear)
                              {
                                  ++this.days;
                                  this.start = start.AddDays(1);
                              }
                      
                              if (this.months > 11)
                              {
                                  while (this.months > 11)
                                  {
                                      ++this.years;
                                      this.months = months - 12;
                                  }
                              }
                      
                          }
                      
                      
                          public override string ToString()
                          {
                              if (this.start > this.currentDAte)
                              {
                                  throw new Exception("Current date is greater than date posted");
                              }
                              String ret = this.ComposeTostring();
                              this.reset();
                              return ret;
                          }
                      
                          private String ComposeTostring()
                          {
                              this.compute();
                              if (this.years > 0)
                              {
                                  if (this.months > 0)
                                  {
                                      if (this.days > 0)
                                      {
                                          return String.Format("{0} year{1}, {2} month{3} && {4} Day{5} ago", this.years, plural(this.years), this.months, plural(this.months), this.days, plural(this.days));
                                      }
                                      return String.Format("{0} year{1}, {2} month{3} ago", this.years, plural(this.years), this.months, plural(this.months));
                                  }
                                  else
                                  {
                                      if (this.days > 0)
                                      {
                                          return String.Format("{0} year{1},{2} day{3} ago", this.years, plural(this.years), this.days, plural(this.days));
                                      }
                      
                                      return String.Format("{0} year{1} ago", this.years, plural(this.years));
                      
                                  }
                              }
                      
                              if (this.months > 0)
                              {
                                  if (this.days > 0)
                                  {
                                      return String.Format("{0} month{1}, {2} day{3} ago", this.months, plural(this.months), this.days, plural(this.days));
                                  }
                                  else
                                  {
                                      return String.Format("{0} month{1} ago", this.months, plural(this.months));
                                  }
                              }
                      
                              if ((this.origCurrentDAte - this.origstart).Days > 0)
                              {
                                  int daysDiff = (this.origCurrentDAte - this.origstart).Days;
                                  this.origstart = this.origstart.AddDays(daysDiff);
                                  int HoursDiff = (this.origCurrentDAte - this.origstart).Hours;
                                  return String.Format("{0} day{1}, {2} hour{3} ago", daysDiff, plural(daysDiff), HoursDiff, plural(HoursDiff));
                      
                              }
                              else if ((this.origCurrentDAte - this.origstart).Hours > 0)
                              {
                                  int HoursDiff = (this.origCurrentDAte - this.origstart).Hours;
                                  this.origstart = this.origstart.AddHours(HoursDiff);
                                  int MinDiff = (this.origCurrentDAte - this.origstart).Minutes;
                                  return String.Format("{0} hour{1}, {2} minute{3} ago", HoursDiff, plural(HoursDiff), MinDiff, plural(MinDiff));
                              }
                              else if ((this.origCurrentDAte - this.origstart).Minutes > 0)
                              {
                      
                                  int MinDiff = (this.origCurrentDAte - this.origstart).Minutes;
                                  this.origstart = this.origstart.AddMinutes(MinDiff);
                                  int SecDiff = (this.origCurrentDAte - this.origstart).Seconds;
                                  return String.Format("{0} minute{1}, {2} second{3} ago", MinDiff, plural(MinDiff), SecDiff, plural(SecDiff));
                              }
                              else if ((this.origCurrentDAte - this.origstart).Seconds > 0)
                              {
                                  int sec = (this.origCurrentDAte - this.origstart).Seconds;
                                  return String.Format("{0} second{1}", sec, plural(sec));
                              }
                      
                              return "";
                          }
                      
                          String plural(int val)
                          {
                              return (val > 1 ? "s" : String.Empty);
                          }
                      
                          DateTime removeTime(DateTime dtime)
                          {
                              dtime = dtime.AddHours(-dtime.Hour);
                              dtime = dtime.AddMinutes(-dtime.Minute);
                              dtime = dtime.AddSeconds(-dtime.Second);
                              return dtime;
                          }
                      
                          public void reset()
                          {
                      
                              this.days = 0;
                              this.months = 0;
                              this.years = 0;
                              this.start = DateTime.MinValue;
                              this.currentDAte = DateTime.MinValue;
                              this.origstart = DateTime.MinValue;
                              this.origCurrentDAte = DateTime.MinValue;
                          }
                      }
                      

                      【讨论】:

                        【解决方案14】:

                        简单的修复。 100% 有效

                                var exactmonth = (date1.Year - date2.Year) * 12 + date1.Month - 
                                date2.Month +  (date1.Day >= date2.Day ? 0 : -1);
                                Console.WriteLine(exactmonth);
                        

                        【讨论】:

                        【解决方案15】:

                        这是一个至少对我有用的简单解决方案。不过它可能不是最快的,因为它在循环中使用了很酷的 DateTime 的 AddMonth 功能:

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

                        【讨论】:

                          【解决方案16】:

                          这方面没有很多明确的答案,因为你总是在假设事情。

                          此解决方案计算两个日期之间的月份,假设您要保存月份中的某天以进行比较,(意味着在计算中考虑了月份中的某天)

                          例如,如果您的日期是 2012 年 1 月 30 日,则 2012 年 2 月 29 日不是一个月,而是 2013 年 3 月 1 日。

                          它已经过非常彻底的测试,可能会在我们使用时清理它,但在这里:

                          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
                          }
                          

                          【讨论】:

                            【解决方案17】:

                            我对两个日期之间总月差的理解有整数部分和小数部分(日期很重要)。

                            整体部分是完整的月差。

                            对我来说,小数部分是开始月份和结束月份之间一天的百分比(到一个月的全天)的差异。

                            public static class DateTimeExtensions
                            {
                                public static double TotalMonthsDifference(this DateTime from, DateTime to)
                                {
                                    //Compute full months difference between dates
                                    var fullMonthsDiff = (to.Year - from.Year)*12 + to.Month - from.Month;
                            
                                    //Compute difference between the % of day to full days of each month
                                    var fractionMonthsDiff = ((double)(to.Day-1) / (DateTime.DaysInMonth(to.Year, to.Month)-1)) -
                                        ((double)(from.Day-1)/ (DateTime.DaysInMonth(from.Year, from.Month)-1));
                            
                                    return fullMonthsDiff + fractionMonthsDiff;
                                }
                            }
                            

                            有了这个扩展,结果如下:

                            2/29/2000 TotalMonthsDifference 2/28/2001 => 12
                            2/28/2000 TotalMonthsDifference 2/28/2001 => 12.035714285714286
                            01/01/2000 TotalMonthsDifference 01/16/2000 => 0.5
                            01/31/2000 TotalMonthsDifference 01/01/2000 => -1.0
                            01/31/2000 TotalMonthsDifference 02/29/2000 => 1.0
                            01/31/2000 TotalMonthsDifference 02/28/2000 => 0.9642857142857143
                            01/31/2001 TotalMonthsDifference 02/28/2001 => 1.0
                            

                            【讨论】:

                              【解决方案18】:

                              我只需要一些简单的东西来满足,例如。仅输入月份/年份的就业日期,因此需要不同的年份和月份。这就是我使用的,这里仅用于有用

                              public static YearsMonths YearMonthDiff(DateTime startDate, DateTime endDate) {
                                  int monthDiff = ((endDate.Year * 12) + endDate.Month) - ((startDate.Year * 12) + startDate.Month) + 1;
                                  int years = (int)Math.Floor((decimal) (monthDiff / 12));
                                  int months = monthDiff % 12;
                                  return new YearsMonths {
                                      TotalMonths = monthDiff,
                                          Years = years,
                                          Months = months
                                  };
                              }
                              

                              .NET Fiddle

                              【讨论】:

                                【解决方案19】:

                                最精确的方法是按月份返回差异:

                                private double ReturnDiffereceBetweenTwoDatesInMonths(DateTime startDateTime, DateTime endDateTime)
                                {
                                    double result = 0;
                                    double days = 0;
                                    DateTime currentDateTime = startDateTime;
                                    while (endDateTime > currentDateTime.AddMonths(1))
                                    {
                                        result ++;
                                
                                        currentDateTime = currentDateTime.AddMonths(1);
                                    }
                                
                                    if (endDateTime > currentDateTime)
                                    {
                                        days = endDateTime.Subtract(currentDateTime).TotalDays;
                                
                                    }
                                    return result + days/endDateTime.GetMonthDays;
                                }
                                

                                【讨论】:

                                  【解决方案20】:

                                  我写了一个函数来完成这个,因为其他方法不适合我。

                                  public string getEndDate (DateTime startDate,decimal monthCount)
                                  {
                                      int y = startDate.Year;
                                      int m = startDate.Month;
                                  
                                      for (decimal  i = monthCount; i > 1; i--)
                                      {
                                          m++;
                                          if (m == 12)
                                          { y++;
                                              m = 1;
                                          }
                                      }
                                      return string.Format("{0}-{1}-{2}", y.ToString(), m.ToString(), startDate.Day.ToString());
                                  }
                                  

                                  【讨论】:

                                  • 请用英语回答(相对于任何发明的语言......)
                                  • 为什么不直接做 startDate.AddMonths(monthCount).ToShortDateString()?无论如何,这并不能回答最初提出的问题!
                                  • 哦,对不起@TabbyCool,这段代码在我的程序中运行良好!程序员规则说:首先代码有效,然后优化! tanx 为你的评论 :)
                                  【解决方案21】:

                                  如果您想要确切的整月数,始终为正数(2000-01-15、2000-02-14 返回 0),考虑到整月是指您到达下个月的同一天(类似于年龄计算)

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

                                  编辑原因:旧代码在某些情况下不正确,例如:

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

                                  【讨论】:

                                  • 为了避免对其他人造成混淆,我认为这个解决方案是不正确的。使用测试用例:new { From = new DateTime(2015, 12, 31), To = new DateTime(2015, 6, 30), Result = 6 } 测试将失败,结果为 5。
                                  • 添加了我建议的修复的快速要点here
                                  • 我不确定我明白了,我的函数应该返回 6:dotnetfiddle.net/MRZNnC
                                  • 我在这里手动复制了测试用例,它有一个错误。失败的规范应该是:new { From = new DateTime(2015, 12, 31), To = new DateTime(2016, 06, 30), Result = 6 }。 “错误”存在于to.Day &lt; from.Day 代码中,它没有考虑到月份可以在不同的“月份中的某天”结束。在这种情况下,从 2015 年 12 月 31 日到 2016 年 6 月 30 日,整个 6 个月将过去(因为 6 月有 30 天),但您的代码将返回 5。
                                  • 在我看来,这是预期的行为,或者至少是我所期望的行为。我准确地说,当您到达同一天(或在这种情况下为下个月)时,整整一个月。
                                  【解决方案22】:

                                  有 3 种情况:同年、上年和其他年份。

                                  如果月份中的哪一天无关紧要......

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

                                  【讨论】:

                                    【解决方案23】:

                                    这对我需要它有用。就我而言,月份中的哪一天并不重要,因为它总是恰好是每月的最后一天。

                                    public static int MonthDiff(DateTime d1, DateTime d2){
                                        int retVal = 0;
                                    
                                        if (d1.Month<d2.Month)
                                        {
                                            retVal = (d1.Month + 12) - d2.Month;
                                            retVal += ((d1.Year - 1) - d2.Year)*12;
                                        }
                                        else
                                        {
                                            retVal = d1.Month - d2.Month;
                                            retVal += (d1.Year - d2.Year)*12;
                                        }
                                        //// 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;
                                    }
                                    

                                    【讨论】:

                                      【解决方案24】:
                                      public static int PayableMonthsInDuration(DateTime StartDate, DateTime EndDate)
                                      {
                                          int sy = StartDate.Year; int sm = StartDate.Month; int count = 0;
                                          do
                                          {
                                              count++;if ((sy == EndDate.Year) && (sm >= EndDate.Month)) { break; }
                                              sm++;if (sm == 13) { sm = 1; sy++; }
                                          } while ((EndDate.Year >= sy) || (EndDate.Month >= sm));
                                          return (count);
                                      }
                                      

                                      此解决方案用于租赁/订阅计算,其中差异并不意味着是减法,而是这两个日期内的跨度。

                                      【讨论】:

                                        【解决方案25】:

                                        在我的情况下,需要计算从开始日期到下个月的前一天或从月初到月底的完整月份。


                                        例如:从 2018 年 1 月 1 日到 2018 年 1 月 31 日是一个完整的月份
                                        Ex2:从 2018 年 5 月 1 日到 2018 年 4 月 2 日是整整一个月

                                        所以基于此,这是我的解决方案:

                                        public static DateTime GetMonthEnd(DateTime StartDate, int MonthsCount = 1)
                                        {
                                            return StartDate.AddMonths(MonthsCount).AddDays(-1);
                                        }
                                        public static Tuple<int, int> CalcPeriod(DateTime StartDate, DateTime EndDate)
                                        {
                                            int MonthsCount = 0;
                                            Tuple<int, int> Period;
                                            while (true)
                                            {
                                                if (GetMonthEnd(StartDate) > EndDate)
                                                    break;
                                                else
                                                {
                                                    MonthsCount += 1;
                                                    StartDate = StartDate.AddMonths(1);
                                                }
                                            }
                                            int RemainingDays = (EndDate - StartDate).Days + 1;
                                            Period = new Tuple<int, int>(MonthsCount, RemainingDays);
                                            return Period;
                                        }
                                        

                                        用法:

                                        Tuple<int, int> Period = CalcPeriod(FromDate, ToDate);
                                        

                                        注意:在我的情况下,需要计算完整月份后的剩余天数,因此如果不是您的情况,您可以忽略天数结果,甚至可以将方法返回从元组更改为整数。

                                        【讨论】:

                                          【解决方案26】:

                                          假设月份中的哪一天不相关(即 2011.1.1 和 2010.12.31 之间的差异为 1),date1 > date2 给出正值, date2 > date1 给出负值

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

                                          或者,假设您想要两个日期之间的大致“平均月数”,以下应该适用于除非常大的日期差异之外的所有日期。

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

                                          注意,如果您要使用后一种解决方案,那么您的单元测试应该说明您的应用程序设计使用的最广泛的日期范围,并相应地验证计算结果。


                                          更新(感谢Gary

                                          如果使用“平均月数”方法,用于“每年平均天数”的稍微更准确的数字是 365.2425

                                          【讨论】:

                                          • @Kurru - 365 / 12 只是一个月平均天数的近似度量。这是一个不准确的衡量标准。对于较小的日期范围,可以容忍这种不准确性,但对于非常大的日期范围,这种不准确性可能会变得很严重。
                                          • 我认为有必要考虑Day组件。像这样(date1.Year - date2.Year) * 12 + date1.Month - date2.Month + (date1.Day &gt;= date2.Day ? 0 : -1)
                                          • @DrunkCoder 这取决于给定系统的要求。在某些情况下,您的解决方案可能确实是最佳选择。例如。重要的是要考虑当两个日期跨越一个月 31 天、一个月 30 天、二月 28 天或二月 29 天时会发生什么。如果您的公式结果能够满足系统的要求,那么它显然是正确的选择。如果不是,则需要其他内容。
                                          • 为了支持亚当所说的,我花了数年时间为精算师编写代码。一些计算是除以天数,四舍五入得到每月数字。有时计算月份假设每个日期都从月初开始,相应地计算整个月份。在计算日期方面没有最佳方法。除非是您正在为其编写代码的客户,否则请将其推回链条并澄清,可能由您的客户会计师进行。
                                          • 365.2425 是公历中更准确的天数,如果您使用的是公历的话。但是,到 DateTime.MaxValue(10000 年 1 月 1 日)时,相差仅约 59 天。此外,根据您的观点en.wikipedia.org/wiki/Year,一年的定义可能会有很大不同。
                                          【解决方案27】:

                                          这是对 Kirk Woll 的回答。我还没有足够的声望点来回复评论...

                                          我喜欢 Kirk 的解决方案,并且打算无耻地将其撕掉并在我的代码中使用它,但当我仔细查看它时,我意识到它太复杂了。不必要的切换和循环,以及一个毫无意义的公共构造函数。

                                          这是我的重写:

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

                                          用法1,大同小异:

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

                                          用法2,类似:

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

                                          【讨论】:

                                            【解决方案28】:

                                            这是我发现准确的月份差异的贡献:

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

                                            用法:

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

                                            您可以创建另一个名为 DiffYears 的方法,并在 while 循环中应用与上述完全相同的逻辑和 AddYears 而不是 AddMonths。

                                            【讨论】:

                                              【解决方案29】:

                                              LINQ 解决方案,

                                              DateTime ToDate = DateTime.Today;
                                              DateTime FromDate = ToDate.Date.AddYears(-1).AddDays(1);
                                              
                                              int monthCount = Enumerable.Range(0, 1 + ToDate.Subtract(FromDate).Days)
                                                                  .Select(x => FromDate.AddDays(x))
                                                                  .ToList<DateTime>()
                                                                  .GroupBy(z => new { z.Year, z.Month })
                                                                  .Count();
                                              

                                              【讨论】:

                                                【解决方案30】:

                                                这是一个更简洁的解决方案,仅使用 VB.Net DateDiff 表示年、月、日。您也可以在 C# 中加载 DateDiff 库。

                                                date1 必须是

                                                VB.NET

                                                Dim date1 = Now.AddDays(-2000)
                                                Dim date2 = Now
                                                Dim diffYears = DateDiff(DateInterval.Year, date1, date2) - If(date1.DayOfYear > date2.DayOfYear, 1, 0)
                                                Dim diffMonths = DateDiff(DateInterval.Month, date1, date2) - diffYears * 12 - If(date1.Day > date2.Day, 1, 0)
                                                Dim diffDays = If(date2.Day >= date1.Day, date2.Day - date1.Day, date2.Day + (Date.DaysInMonth(date1.Year, date1.Month) - date1.Day))
                                                

                                                C#

                                                DateTime date1 = Now.AddDays(-2000);
                                                DateTime date2 = Now;
                                                int diffYears = DateDiff(DateInterval.Year, date1, date2) - date1.DayOfYear > date2.DayOfYear ? 1 : 0;
                                                int diffMonths = DateDiff(DateInterval.Month, date1, date2) - diffYears * 12 - date1.Day > date2.Day ? 1 : 0;
                                                int diffDays = date2.Day >= date1.Day ? date2.Day - date1.Day : date2.Day + (System.DateTime.DaysInMonth(date1.Year, date1.Month) - date1.Day);
                                                

                                                【讨论】:

                                                  猜你喜欢
                                                  • 2014-04-07
                                                  • 2010-12-04
                                                  • 2022-10-02
                                                  • 2012-05-12
                                                  • 1970-01-01
                                                  • 1970-01-01
                                                  相关资源
                                                  最近更新 更多