我有一个像这样的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)
这是一个包含排除日期,周末和循环的示例.我确实将字符串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之间的距离相当大,那么按照其他一个答案中的说明进行数学运算会好得多.建议这样可以了解迭代日期.