我应该如何在日期时间范围内找到丢失的日期时间



我是 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 to 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所说,只需按排除的日期过滤月份列表即可。

https://dotnetfiddle.net/2fv8bY

我借用了PiJei的建议。然后使用方法扩展它,以获取起始范围内的天数,并使用一种方法构建日期的最终范围。

首先,让我们构建示例数据: 变量月份 = 每天(开始、结束(;

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);

为此,我正在使用从这个答案中借用EachDay方法。

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;
}

为了获得我称之为withoutExcluded的最终列表,我只需运行以下命令:

var withoutExcluded = month.Except(sub1).Except(sub2).Except(sub3);

最后,我获取此列表并构建结果范围。

var ranges = GetRanges(withoutExcluded);

为此,我创建了一个简单的帮助程序Range类和GetRanges方法,用于分析日期,如果它们是连续日期,则构建单个范围。

Range帮助程序:

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 };
}

最终结果如下所示:

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; }
}
}

最新更新