C#中日期范围内的天数,不包括周末和其他日期

Dan*_*Dan 7 c# date

我有一个像这样的C#方法:

public static int DaysLeft(DateTime startDate, DateTime endDate, Boolean excludeWeekends, String excludeDates)
{
}
Run Code Online (Sandbox Code Playgroud)

它应该做的是计算startDate和endDate之间的天数,但是可选地需要排除周末和其他日期(以逗号分隔的日期字符串传递).

我完全不知道如何解决这个问题.我的直觉是从startDate循环到endDate并进行一些字符串比较,但从我可以发现的结果来看,C#不允许以这种方式循环日期 - 或者至少它不是一种非常优雅的做事方式.

Jon*_*eet 10

哦,循环日期真的很容易 - 这根本不是问题:

// I'm assuming you want <= to give an *inclusive* end date...
for (DateTime date = start; date <= end; date = date.AddDays(1))
{
     // Do stuff with date
}
Run Code Online (Sandbox Code Playgroud)

您也可以轻松编写IEnumerable<DateTime>,并使用foreach.

如果可能的话,我会尽量避免在这里进行字符串操作 - 从根本上说这些日期不是字符串,所以如果你可以尽可能地在问题域中工作,它会让事情变得更容易.

当然,有可能比循环更有效的方法,但它们将更难以正确.如果循环在性能方面没问题,我会坚持这一点.

作为我自己的开源项目的快速插件,Noda Time有一组代表日期和时间的更多样化 - 在这种情况下你可以使用LocalDate.这样你就不用担心如果"开始"的时间晚于"结束"的时间等会发生什么.另一方面,Noda Time还没有真正完成......你需要的位数为此已准备就绪,应该可以正常工作,但API可能在未来仍然可能发生变化.

编辑:如果你确实需要经常循环日期,你可能想要这样的扩展方法(把它放在顶级非泛型静态类):

public static IEnumerable<DateTime> To(this DateTime start, DateTime end)
{
    Date endDate = end.Date;
    for (DateTime date = start.Date; date <= endDate; date = date.AddDays(1))
    {
        yield return date;            
    }
}
Run Code Online (Sandbox Code Playgroud)

然后:

foreach (DateTime date in start.To(end))
{
    ...
}
Run Code Online (Sandbox Code Playgroud)


McA*_*den 9

这是一个包含排除日期,周末和循环的示例.我确实将字符串excludeDates更改为List.应该添加一些空检查.

    public static int DaysLeft(DateTime startDate, DateTime endDate, Boolean excludeWeekends, List<DateTime> excludeDates)
    {
        int count = 0;
        for (DateTime index = startDate; index < endDate; index = index.AddDays(1))
        {
            if (excludeWeekends && index.DayOfWeek != DayOfWeek.Sunday && index.DayOfWeek != DayOfWeek.Saturday)
            {
                bool excluded = false; ;
                for (int i = 0; i < excludeDates.Count; i++)
                {
                    if (index.Date.CompareTo(excludeDates[i].Date) == 0)
                    {
                        excluded = true;
                        break;
                    }
                }

                if (!excluded)
                {
                    count++;
                }
            }
        }

        return count;
    }
Run Code Online (Sandbox Code Playgroud)

编辑:我想指出,我会认为这是一个快速而肮脏的方法 - 如果你不经常这样做.如果你执行这么多,并且startDate和endDate之间的距离相当大,那么按照其他一个答案中的说明进行数学运算会好得多.建议这样可以了解迭代日期.