有没有一种优化的方法可以让两个约会之间有工作周?
本文关键字:两个 约会 工作周 之间 一种 优化 有没有 方法 | 更新日期: 2023-09-27 18:02:38
只是想知道是否有一种更优化和/或更整洁的方式(例如使用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);
}
这将给我以下日期范围…
- 开始:2015年7月01日结束:2015年7月03日
- 开始:2015年7月6日结束:2015年7月10日
- 开始:2015年7月13日结束:2015年7月17日
- 开始:2015年7月20日结束:2015年7月24日
- 开始:2015年7月27日结束:2015年7月31日
- 开始:2015年8月03日结束:2015年8月07日
- 开始:2015年8月10日结束:2015年8月14日
- 开始:2015年8月17日结束:2015年8月21日
- 开始时间:2015年8月24日结束时间:2015年8月28日
- 开始:2015年8月31日结束:2015年9月01日
注意:第一周和最后一周故意不是完整的周(它们遵守给定的日期范围)。
编辑这里提供的解决方案给出了两个日期之间的天数,但我感兴趣的是获取日期范围的集合。
还有,我不需要考虑任何假期。
谢谢,
使用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;
}
}
}
}
小提琴
这是基于Eric的公认答案,所以请给他点赞。我刚刚修改了他的解决方案,以处理可能长达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()));