只是想知道是否有更优化和/或更简洁的方式(使用LINQ)编写下面的内容以获取两个日期之间的营业周日期范围列表?
这就是我目前所拥有的......
// Some storage
public class Bucket
{
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
}
// Other code removed for brevity ...
DateTime start = new DateTime(2015, 7, 1);
DateTime end = new DateTime(2015, 9, 1);
DayOfWeek firstDayOfWeek = DayOfWeek.Monday;
DayOfWeek lastDayOfWeek = DayOfWeek.Friday;
var buckets = new List<Bucket>();
var currentDate = start;
DateTime startOfBucket = currentDate;
DateTime endOfBucket = currentDate;
while (currentDate <= end)
{
var currentDayOfWeek = currentDate.DayOfWeek;
// Skip days outside the business week
if (currentDayOfWeek >= firstDayOfWeek && currentDayOfWeek <= lastDayOfWeek)
{
if (currentDayOfWeek == firstDayOfWeek)
{
// Start a new bucket
startOfBucket = currentDate;
}
if ((currentDayOfWeek == lastDayOfWeek) || (currentDate == end))
{
// End of bucket
endOfBucket = currentDate;
// Create bucket
buckets.Add(new Bucket()
{
StartDate = startOfBucket,
EndDate = endOfBucket
});
}
}
currentDate = currentDate.AddDays(1);
}
这将给我以下日期范围...
N.B。第一周和最后一周故意不是整周(他们遵守给定的日期范围)。
修改 提供的解决方案here给出了两个日期之间的天数,但我有兴趣获取日期范围的集合。
另外,我不需要考虑任何假期。
谢谢,
答案 0 :(得分:1)
使用linq非常方便
var startDate = new DateTime(2015, 7, 1);
var endDate = new DateTime(2015, 9, 1);
var workDates = Enumerable.Range(0, (int)(endDate - startDate).TotalDays + 1)
.Select(i => startDate.AddDays(i))
.Where(date => (date.DayOfWeek != DayOfWeek.Saturday && date.DayOfWeek != DayOfWeek.Sunday))
.Select(i => i);
var display = workDates
.GroupAdjacentBy((x, y) => x.AddDays(1) == y)
.Select(g => string.Format("Start: {0:dd/MMM/yyyy} End: {1:dd/MMM/yyyy}", g.First(), g.Last()));
使用扩展方法GroupAdjacentBy<T>
public static class IEnumerableExtension
{
public static IEnumerable<IEnumerable<T>> GroupAdjacentBy<T>(
this IEnumerable<T> source, Func<T, T, bool> predicate)
{
using (var e = source.GetEnumerator())
{
if (e.MoveNext())
{
var list = new List<T> { e.Current };
var pred = e.Current;
while (e.MoveNext())
{
if (predicate(pred, e.Current))
{
list.Add(e.Current);
}
else
{
yield return list;
list = new List<T> { e.Current };
}
pred = e.Current;
}
yield return list;
}
}
}
}
答案 1 :(得分:0)
这是基于Eric's accepted answer所以请给他任何upvote。我刚刚修改了他的解决方案来处理可能长达7天的工作周,也可以用一个可以包装周末的工作周。
var startDate = new DateTime(2015, 7, 1);
var endDate = new DateTime(2015, 9, 1);
DayOfWeek firstDayOfWeek = DayOfWeek.Monday;
DayOfWeek lastDayOfWeek = DayOfWeek.Friday;
var workDates = Enumerable.Range(0, (int)(endDate - startDate).TotalDays + 1)
.Select(i => startDate.AddDays(i))
.Where(date =>
// Normal work weeks where first day of week is before last (numerically) e.g. Monday -> Friday or Sunday -> Saturday
(firstDayOfWeek < lastDayOfWeek && date.DayOfWeek >= firstDayOfWeek && date.DayOfWeek <= lastDayOfWeek) ||
// Cater for business weeks whose start and end dates wrap over the weekend e.g. Thursday -> Tuesday
(lastDayOfWeek < firstDayOfWeek && (date.DayOfWeek >= firstDayOfWeek || date.DayOfWeek <= lastDayOfWeek)))
.Select(i => i);
var display = workDates
.GroupAdjacentBy((x, y) => x.AddDays(1) == y && !(x.DayOfWeek == lastDayOfWeek && y.DayOfWeek == firstDayOfWeek))
.Select(g => string.Format("Start: {0:dd/MMM/yyyy} End: {1:dd/MMM/yyyy}", g.First(), g.Last()));