我正在制作一个个人项目,只返回我拥有的可用插槽。我有两个列表,一个包含所有可能的日期时间槽,另一个列表包含所有块日期时间。
现在我有以下代码,但是返回重叠记录(这与我想要的相反)
那么,我做错了什么,最好的方法是什么?
(我搜索,我找不到任何与非重叠日期时间相关的内容)
结果应该是这样的:
在public DateSpan(DateTime start, DateTime end)
{
StartDate = start;
EndDate = end;
}
public DateSpan(DateTime start, int duration)
{
StartDate = start;
EndDate = start.AddHours(duration);
}
public static void Main(string[] args)
{
var AvailableHours = new System.Collections.Generic.List<DateSpan>();
AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 1, 5, 0, 0), 2));
AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 2, 4, 0, 0), 2));
AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 2, 5, 0, 0), 2));
AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 2, 1, 30, 0), 2));
AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 4, 5, 0, 0), 2));
var BlockTimes = new System.Collections.Generic.List<DateSpan>();
BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 1, 10, 0, 0), 2));
BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 2, 5, 0, 0), 2));
BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 3, 5, 0, 0), 2));
BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 4, 4, 0, 0), 2));
var e = AvailableHours.SelectMany((DateSpan x) =>
{
var result = new List<DateSpan>();
foreach (var o in BlockTimes.Where(y => x.StartDate < y.StartDate && y.StartDate < x.EndDate).ToList())
{
result.Add(new DateSpan(new DateTime(Math.Max(x.StartDate.Ticks, o.StartDate.Ticks)), new DateTime(Math.Min(x.EndDate.Ticks, o.EndDate.Ticks))));
}
return result;
});
}
类中定义一个方法,该方法将知道如何确定两个日期跨度是否相交:
DateSpan
然后,使用此方法发现可用的时间段:
public bool Intersect(DateSpan other)
{
return (this.StartDate >= other.StartDate && this.StartDate <= other.EndDate) ||
(this.EndDate >= other.StartDate && this.EndDate <= other.EndDate);
}
根据你的问题的澄清,这似乎成功。它使用foreach循环而不是直接Linq,但对我来说,这使代码更具可读性,解决方案更直接:
private List<DateSpan> GetNonOverlappingTimes()
{
var AvailableHours = new System.Collections.Generic.List<DateSpan>();
AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 1, 5, 0, 0), 2));
AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 2, 4, 0, 0), 2));
AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 2, 5, 0, 0), 2));
AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 2, 1, 30, 0), 2));
AvailableHours.Add(new DateSpan(new DateTime(2018, 9, 4, 5, 0, 0), 2));
var BlockTimes = new System.Collections.Generic.List<DateSpan>();
BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 1, 10, 0, 0), 2));
BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 2, 5, 0, 0), 2));
BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 3, 5, 0, 0), 2));
BlockTimes.Add(new DateSpan(new DateTime(2018, 9, 4, 4, 0, 0), 2));
return AvailableHours.Where(x => BlockTimes.All(y => !x.Intersect(y))).ToList();
}
这给出了您所说的预期结果。