C# 如何查找datetime范围中缺少的datetime
我在C#方面是个新手,在某种逻辑上我有一个日期范围(假设一个月,即2018-06-01到2018-06-30) 我有一份小范围约会的清单:C# 如何查找datetime范围中缺少的datetime,c#,C#,我在C#方面是个新手,在某种逻辑上我有一个日期范围(假设一个月,即2018-06-01到2018-06-30) 我有一份小范围约会的清单: STARTDATE ENDDATE 2018-06-04 2018-06-06 2018-06-11 2018-06-14 2018-06-17 2018-06-20 假设需要将上述日期从原始的一个月范围(2018-06-01至2018-06-30)中阻止。因此,作为输出,我需要一些逻辑来返回未被阻止的可用日期范围 因此,输出需要如下所示: STARTD
STARTDATE ENDDATE
2018-06-04 2018-06-06
2018-06-11 2018-06-14
2018-06-17 2018-06-20
假设需要将上述日期从原始的一个月范围(2018-06-01至2018-06-30)中阻止。因此,作为输出,我需要一些逻辑来返回未被阻止的可用日期范围
因此,输出需要如下所示:
STARTDATE ENDDATE
2018-06-01 2018-06-03
2018-06-07 2018-06-10
2018-06-15 2018-06-16
2018-06-18 2018-06-19
2018-06-21 2018-06-30
因此,我需要一些C#专家指导我应该如何实现这一点。我不是要代码,但如果有人写了类似的逻辑,那么请分享想法或提供任何相同的参考
我主要关心的是我应该使用列表、字典、数据表还是其他什么?你可以使用Linq,除了FilteredList=BiggerList.except(SmallerList).ToList()
我会选择排除日期的列表,允许日期的列表。
然后,正如@PiJei所说的,只需按排除的日期过滤该月的列表
我借鉴了皮杰的建议。然后用一种方法扩展该方法,以获得起始范围内的天数,并用一种方法构建日期的最终范围
首先,让我们构建示例数据:
var月=每一天(开始、结束)
为了做到这一点,我每天都在使用借用的方法
最后,我使用这个列表并构建结果的范围
var ranges = GetRanges(withoutExcluded);
为此,我创建了一个简单的助手Range
类和GetRanges
方法,用于分析日期,如果它们是连续的日期,则构建单个范围
助手范围类:
public class Range
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
}
助手GetRanges
方法:
public static IEnumerable<Range> GetRanges(IEnumerable<DateTime> dates)
{
var start = dates.First();
var end = dates.First();
var prev = dates.First();
var next = DateTime.Now;
foreach(var d in dates.Skip(1))
{
next = d;
var diff = next - prev;
if (diff.TotalDays > 1)
{
yield return new Range { Start = start, End = end };
start = d;
}
prev = d;
end = d;
}
yield return new Range { Start = start, End = end };
}
我将把结果的适当格式留给您。但逻辑是正确的。
如果您不知道下面我粘贴整个解决方案时会发生什么情况:
class Program
{
static void Main(string[] args)
{
var start = new DateTime(2018, 06, 01);
var end = new DateTime(2018, 06, 30);
var month = EachDay(start, end);
var start1 = new DateTime(2018, 06, 04);
var end1 = new DateTime(2018, 06, 06);
var sub1 = EachDay(start1, end1);
var start2 = new DateTime(2018, 06, 11);
var end2 = new DateTime(2018, 06, 14);
var sub2 = EachDay(start2, end2);
var start3 = new DateTime(2018, 06, 17);
var end3 = new DateTime(2018, 06, 20);
var sub3 = EachDay(start3, end3);
var withoutExcluded = month.Except(sub1).Except(sub2).Except(sub3);
var ranges = GetRanges(withoutExcluded);
foreach (var r in ranges)
{
Console.WriteLine($"range: {r.Start} {r.End}");
}
}
//https://stackoverflow.com/a/1847601/3330348
public static IEnumerable<DateTime> EachDay(DateTime from, DateTime thru)
{
for (var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
yield return day;
}
public static IEnumerable<Range> GetRanges(IEnumerable<DateTime> dates)
{
var start = dates.First();
var end = dates.First();
var prev = dates.First();
var next = DateTime.Now;
foreach (var d in dates.Skip(1))
{
next = d;
var diff = next - prev;
if (diff.TotalDays > 1)
{
yield return new Range { Start = start, End = end };
start = d;
}
prev = d;
end = d;
}
yield return new Range { Start = start, End = end };
}
public class Range
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
}
}
类程序
{
静态void Main(字符串[]参数)
{
var开始=新日期时间(2018年6月1日);
var end=新日期时间(2018年6月30日);
var月=每一天(开始、结束);
var start1=新的日期时间(2018,06,04);
var end1=新的日期时间(2018,06,06);
var sub1=每一天(开始1,结束1);
var start2=新的日期时间(2018,06,11);
var end2=新的日期时间(2018,06,14);
var sub2=每一天(开始2,结束2);
var start3=新的日期时间(2018,06,17);
var end3=新日期时间(2018年6月20日);
var sub3=每一天(开始3,结束3);
var WithoutExclude=月份。除(子1)。除(子2)。除(子3);
var范围=GetRanges(不排除);
foreach(范围内的var r)
{
WriteLine($“范围:{r.Start}{r.End}”);
}
}
//https://stackoverflow.com/a/1847601/3330348
公共静态IEnumerable EachDay(日期时间从,日期时间到)
{
对于(var日=起始日期;日期1)
{
产生返回新范围{Start=Start,End=End};
开始=d;
}
prev=d;
end=d;
}
产生返回新范围{Start=Start,End=End};
}
公共类范围
{
公共日期时间开始{get;set;}
公共日期时间结束{get;set;}
}
}
可能重复的I可能会使用a来执行您试图执行的操作。您似乎在寻找的逻辑是,只需从所述月份的第一个日期开始,循环浏览“次要日期范围”列表并检查开始日期如果月初不等于“次要日期范围”中的第一个元素,则您有开始日期的第一个元素,您可以继续循环天数以查找第一个间隔的结束日期。冲洗并重复到月底。我认为您示例中结果中的范围不正确:2018-06-18 2018-06-19
不确定,范围不是单元组或单元格。可以说,STARTDATE和ENDDATE是不同的列或字段。
public class Range
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
}
public static IEnumerable<Range> GetRanges(IEnumerable<DateTime> dates)
{
var start = dates.First();
var end = dates.First();
var prev = dates.First();
var next = DateTime.Now;
foreach(var d in dates.Skip(1))
{
next = d;
var diff = next - prev;
if (diff.TotalDays > 1)
{
yield return new Range { Start = start, End = end };
start = d;
}
prev = d;
end = d;
}
yield return new Range { Start = start, End = end };
}
range: 01/06/2018 00:00:00 03/06/2018 00:00:00
range: 07/06/2018 00:00:00 10/06/2018 00:00:00
range: 15/06/2018 00:00:00 16/06/2018 00:00:00
range: 21/06/2018 00:00:00 30/06/2018 00:00:00
class Program
{
static void Main(string[] args)
{
var start = new DateTime(2018, 06, 01);
var end = new DateTime(2018, 06, 30);
var month = EachDay(start, end);
var start1 = new DateTime(2018, 06, 04);
var end1 = new DateTime(2018, 06, 06);
var sub1 = EachDay(start1, end1);
var start2 = new DateTime(2018, 06, 11);
var end2 = new DateTime(2018, 06, 14);
var sub2 = EachDay(start2, end2);
var start3 = new DateTime(2018, 06, 17);
var end3 = new DateTime(2018, 06, 20);
var sub3 = EachDay(start3, end3);
var withoutExcluded = month.Except(sub1).Except(sub2).Except(sub3);
var ranges = GetRanges(withoutExcluded);
foreach (var r in ranges)
{
Console.WriteLine($"range: {r.Start} {r.End}");
}
}
//https://stackoverflow.com/a/1847601/3330348
public static IEnumerable<DateTime> EachDay(DateTime from, DateTime thru)
{
for (var day = from.Date; day.Date <= thru.Date; day = day.AddDays(1))
yield return day;
}
public static IEnumerable<Range> GetRanges(IEnumerable<DateTime> dates)
{
var start = dates.First();
var end = dates.First();
var prev = dates.First();
var next = DateTime.Now;
foreach (var d in dates.Skip(1))
{
next = d;
var diff = next - prev;
if (diff.TotalDays > 1)
{
yield return new Range { Start = start, End = end };
start = d;
}
prev = d;
end = d;
}
yield return new Range { Start = start, End = end };
}
public class Range
{
public DateTime Start { get; set; }
public DateTime End { get; set; }
}
}