全部,我有两组日期,我需要找到所有日期对,这些日期对具有小时连接的连续日期。我希望结果返回每个连续的一对或多对日期的开始和结束日期,以便稍后作为linq查询的参数对照包含所有可能日期的主列表。
下面:要评估的样本数据。期望的输出在底部。
由于
// The result should return all pairs of start/end times (hour) where dates are contiguous. Where a set has more than two pairs,
// the result would return the start time of the first start record and the end time of the latest end record.
var ranges = new List<DateRange>
{new DateRange(DateTime.Parse("1/19/2018 10:00 AM"), DateTime.Parse("1/19/2018 12:00 PM")),
new DateRange(DateTime.Parse("1/19/2018 12:00 PM"), DateTime.Parse("1/19/2018 02:00 PM")),
new DateRange(DateTime.Parse("1/19/2018 02:00 PM"), DateTime.Parse("1/19/2018 04:00 PM")),
new DateRange(DateTime.Parse("1/19/2018 07:00 PM"), DateTime.Parse("1/19/2018 08:00 PM")),
new DateRange(DateTime.Parse("1/19/2018 04:00 PM"), DateTime.Parse("1/19/2018 05:00 PM")),
new DateRange(DateTime.Parse("1/19/2018 10:00 PM"), DateTime.Parse("1/19/2018 11:00 PM"))
};
// Sample Result
// Set 1
// "1/19/2018 10:00 AM", "1/19/2018 05:00 PM"
// Set 2
// "1/19/2018 07:00 PM", "1/19/2018 08:00 PM"
// Set 3
// "1/19/2018 10:00 PM", "1/19/2018 11:00 PM"``
答案 0 :(得分:0)
示例代码不起作用。因此,我必须猜测你想做什么。您的示例数据看起来像是单个用户的一些登录/注销数据。
我的猜测:你没有重叠的intervalls - 每次开始都是独一无二的,并且在它结束之前没有其他开始。 例如:
1/18/2018 10 AM - 1/18/2018 11 AM
1/18/2018 11 AM - 1/18/2018 01 PM
您想将此合并到..
1/18/2018 10 AM - 1/18/2018 01 PM
这是不允许的,因为它重叠:
1/18/2018 10 AM - 1/18/2018 01 PM
1/18/2018 11 AM - 1/18/2018 02 PM
如果这是您想要做的,您应该编辑您的问题。但这可能是你的解决方案:
// A class for each intervall
public class MyIntervall
{
public MyIntervall(DateTime start, DateTime end)
{
this.Start = start;
this.End = end;
}
public DateTime Start { get; set; }
public DateTime End { get; set; }
}
public static void Main(params string[] args)
{
// Your data..
List<MyIntervall> intervalls = new List<MyIntervall>()
{
new MyIntervall(new DateTime(2018, 1, 19, 10, 0, 0), new DateTime(2018, 1, 19, 12, 0, 0)),
new MyIntervall(new DateTime(2018, 1, 19, 12, 0, 0), new DateTime(2018, 1, 19, 14, 0, 0)),
new MyIntervall(new DateTime(2018, 1, 19, 14, 0, 0), new DateTime(2018, 1, 19, 16, 0, 0)),
new MyIntervall(new DateTime(2018, 1, 19, 19, 0, 0), new DateTime(2018, 1, 19, 20, 0, 0)),
new MyIntervall(new DateTime(2018, 1, 19, 16, 0, 0), new DateTime(2018, 1, 19, 17, 0, 0)),
new MyIntervall(new DateTime(2018, 1, 19, 22, 0, 0), new DateTime(2018, 1, 19, 23, 0, 0))
};
MyIntervall lastIntervall = null;
List<MyIntervall> mergedIntervalls = new List<MyIntervall>();
// Loop through your list.
foreach (MyIntervall currenIntervall in intervalls.OrderBy(o => o.Start))
{
if (lastIntervall == null)
{
// Start-condition
lastIntervall = currenIntervall;
}
else if (lastIntervall.End == currenIntervall.Start)
{
// If the last intervall ends at the start of the next one, we merge them into one bigger intervall by moving the end.
lastIntervall.End = currenIntervall.End;
}
else
{
// If end doesn't match the next start, we know that the intervall is closed. Wo move to the next one.
mergedIntervalls.Add(lastIntervall);
lastIntervall = currenIntervall;
}
}
// In the end, we add the last intervall to the merge-list, because it has no following intervall.
mergedIntervalls.Add(lastIntervall);
// output our merge-result
int set = 0;
foreach (MyIntervall currenIntervall in mergedIntervalls)
{
Console.WriteLine("#{0}: Start {1}, End {2}", ++set, currenIntervall.Start, currenIntervall.End);
}
// this is the result of the merge
List<MyIntervall> resultList = new List<MyIntervall>()
{
new MyIntervall(new DateTime(2018, 1, 19, 10, 0, 0), new DateTime(2018, 1, 19, 17, 0, 0)),
new MyIntervall(new DateTime(2018, 1, 19, 19, 0, 0), new DateTime(2018, 1, 19, 20, 0, 0)),
new MyIntervall(new DateTime(2018, 1, 19, 22, 0, 0), new DateTime(2018, 1, 19, 23, 0, 0))
};
}