计算两个日期之间相隔的天数,这两个日期是不同月份的。

3
我需要计算两个日期(DateTime)之间的天数,但有一个小变化。我想知道这两天所跨越的每个月份中有多少天。有没有简单的方法可以做到这一点?
示例:
我有起始日期为2011年3月30日和结束日期为2011年4月5日,那么结果应该是这样的:
var result = new Dictionary<DateTime, int>
             {
                { new DateTime(2011, 3, 1), 2 },
                { new DateTime(2011, 4, 1), 5 }
             };

你的意思是{3,2},{4,5}吗?此外,这些日期是否应该在连续的两个月份中?如果不是,那么如果这两个日期跨越了几年,字典的键应该是年份+月份吗? - Paolo Tedesco
你的意思是 {3 => 2, 4 => 5} 吗?在字典中,不能有相同的键出现两次。 - carlosfigueira
@Paolo:是的,对不起。谢谢。 - Carles Company
所有的月份都在同一年内吗?如果不是,那么像2011年1月和2012年1月这样重复出现的月份怎么办? - Yet Another Geek
又一个极客:你说得对。我会更正这个例子... - Carles Company
7个回答

3
您可以尝试这样做:

您可以尝试类似以下的方法:

using System;
using System.Collections.Generic;

static class Program {

    // return dictionary tuple<year,month> -> number of days
    static Dictionary<Tuple<int, int>, int> GetNumberOfDays(DateTime start, DateTime end) {
        // assumes end > start
        Dictionary<Tuple<int, int>, int> ret = new Dictionary<Tuple<int, int>, int>();
        DateTime date = end;
        while (date > start) {
            if (date.Year == start.Year && date.Month == start.Month) {
                ret.Add(
                    Tuple.Create<int, int>(date.Year, date.Month),
                    (date - start).Days + 1);
                break;
            } else {
                ret.Add(
                    Tuple.Create<int, int>(date.Year, date.Month),
                    date.Day);
                date = new DateTime(date.Year, date.Month, 1).AddDays(-1);
            }
        }
        return ret;
    }

    static void Main(params string[] args) {
        var days = GetNumberOfDays(new DateTime(2011, 3, 1), new DateTime(2011, 4, 1));
        foreach (var m in days.Keys) {
            Console.WriteLine("{0}/{1} : {2} days", m.Item1, m.Item2, days[m]);
        }
    }

}

几乎,在第一个月,如果我输入30/03/2011作为开始日期,它返回1,但应该是2,但很容易纠正。谢谢。 - Carles Company

1
你可以使用 .NET 时间周期库 中的 Month 类:
// ----------------------------------------------------------------------
public Dictionary<DateTime,int> CountMonthDays( DateTime start, DateTime end )
{
  Dictionary<DateTime,int> monthDays = new Dictionary<DateTime, int>();

  Month startMonth = new Month( start );
  Month endMonth = new Month( end );

  if ( startMonth.Equals( endMonth ) )
  {
    monthDays.Add( startMonth.Start, end.Subtract( start ).Days );
    return monthDays;
  }

  Month month = startMonth;
  while ( month.Start < endMonth.End )
  {
    if ( month.Equals( startMonth ) )
    {
      monthDays.Add( month.Start, month.DaysInMonth - start.Day + 1 );
    }
    else if ( month.Equals( endMonth ) )
    {
      monthDays.Add( month.Start, end.Day );
    }
    else
    {
      monthDays.Add( month.Start, month.DaysInMonth );
    }
    month = month.GetNextMonth();
  }

  return monthDays;
} // CountMonthDays

使用方法:

// ----------------------------------------------------------------------
public void CountDaysByMonthSample()
{
  DateTime start = new DateTime( 2011, 3, 30 );
  DateTime end = new DateTime( 2011, 4, 5 );

  Dictionary<DateTime, int> monthDays = CountMonthDays( start, end );
  foreach ( KeyValuePair<DateTime, int> monthDay in monthDays )
  {
    Console.WriteLine( "month {0:d}, days {1}", monthDay.Key, monthDay.Value );
  }
  // > month 01.03.2011, days 2
  // > month 01.04.2011, days 5
} // CountDaysByMonthSample

1

简单,但不快速:

    DateTime StartDate = new DateTime(2011, 3, 30);
    DateTime EndDate = new DateTime(2011, 4, 5);

    int[] DaysPerMonth = new int[12];

    while (EndDate > StartDate)
    {
        DaysPerMonth[StartDate.Month]++;
        StartDate = StartDate.AddDays(1);
    }

1
这是我的解决方案。我进行了快速检查,似乎可以正常工作...如果有任何问题,请告诉我:
    public Dictionary<DateTime, int> GetMontsBetween(DateTime startDate, DateTime EndDate)
    {
        Dictionary<DateTime, int> rtnValues = new Dictionary<DateTime, int>();
        DateTime startMonth = new DateTime(startDate.Year, startDate.Month, 1);
        DateTime endMonth = new DateTime(EndDate.Year, EndDate.Month, 1);
        //some checking
        if (startDate >= EndDate)
        {
            rtnValues.Add(startMonth, 0); // Or return null;
        }
        else if (startDate.Month == EndDate.Month && startDate.Year == EndDate.Year)
        {
            rtnValues.Add(startMonth, EndDate.Day - startDate.Day);
        }
        else
        {
            //Add first month remaining days
            rtnValues.Add(startMonth, DateTime.DaysInMonth(startDate.Year, startDate.Month) - startDate.Day);
            //Add All months days inbetween
            for (DateTime st = startMonth.AddMonths(1); st < endMonth; st = st.AddMonths(1))
            {
                rtnValues.Add(new DateTime(st.Year, st.Month, 1), DateTime.DaysInMonth(st.Year, st.Month) );
            }
            //Add last month days
            rtnValues.Add(new DateTime(EndDate.Year, EndDate.Month, 1), EndDate.Day);
        }
        return rtnValues;
    }

几乎可以返回第一个月的1,应该是2。只需在两个地方更改startDate.DaystartDate.Day + 1即可。 - Jakob Möllås

1

这是一个小例子,展示了如何使用内置的DateTime.DaysInMonth方法准确地计算出两个日期之间的总月数和天数。该方法可以给我们每个月的天数,从而实现100%的准确性。

DateTime date1 = DateTime.Now.AddDays(60);
DateTime date2 = DateTime.Now;
TimeSpan ts = date1 - date2;
int totalDays = int.Parse(ts.TotalDays.ToString("0"));
int totalMonths = Math.Abs((date1.Month - date2.Month) + 12 * (date1.Year - date2.Year));
int months = 0;
int days = 0;
int totalDaysInMonths = 0;
for (int i = totalMonths; i > 0; i--)
{
    int month = date2.Month + i;
    int year = date1.Year;
    if (month > 12)
    {
        year++;
        int newMonth = month - 12;
        month = newMonth;
    }

    totalDaysInMonths = totalDaysInMonths + DateTime.DaysInMonth(year, month);
}

if (totalDays > totalDaysInMonths)
{
    months = totalMonths - 1;
    days = totalDays - totalDaysInMonths;
}

else if (totalDays < totalDaysInMonths)
{
    months = totalMonths - 1;
    int tempTotalDaysInMonths = 0;
    for (int i = months; i > 0; i--)
    {
        int month = date2.Month + i;
        int year = date1.Year;
        if (month > 12)
        {
            year++;
            int newMonth = month - 12;
            month = newMonth;
        }

        tempTotalDaysInMonths = tempTotalDaysInMonths + DateTime.DaysInMonth(year, month);
    }


    days = totalDays - tempTotalDaysInMonths;
}

else
{
    months = totalMonths;
}

return string.Format("{0} months and {1} days", months, days);

0

使用LinqPad进行快速而不太规范的尝试:

DateTime start = DateTime.Parse("03/30/2011");
DateTime end = new DateTime(2011,04,05,23,59,59);

var startNextMonthFirstDay = new DateTime(start.Year, start.Month+1, 1);

var diffForStartMonth = (startNextMonthFirstDay - start);

var totalDiff = (end-start);

var diff = Math.Round(totalDiff.TotalDays);

var diffForEndMonth = diff - diffForStartMonth.Days;


Dictionary<DateTime, int> result = new Dictionary<DateTime, int>();
result.Add(new DateTime(start.Year, start.Month, 1), diffForStartMonth.Days);
result.Add(new DateTime(end.Year, end.Month, 1), (int)diffForEndMonth);

//Dictionary<DateTime,int>{{new DateTime(2011,3,1),2},{new DateTime(2011,4,1),5}}

result.Dump();

-2
DateTime dt1 = new DateTime(2011, 12, 12);
DateTime dt2 = new DateTime(2011, 06, 12);

TimeSpan ts = dt1.Subtract(dt2);

String s = ts.Days.ToString();

MessageBox.Show(s);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接