使用以下(或类似的DateRange
类)。
Class DateRange
Implements IEnumerable(Of DateTime)
Public Sub New(startDate As DateTime, endDate As DateTime)
me.StartDate = startDate
me.EndDate = endDate
End Sub
Public ReadOnly Property StartDate() As DateTime
Public ReadOnly Property EndDate() As DateTime
Public Function GetEnumerator() As IEnumerator(Of DateTime) Implements IEnumerable(of DateTime).GetEnumerator
Return Enumerable.Range(0, 1 + EndDate.Subtract(StartDate).Days).[Select](Function(offset) StartDate.AddDays(offset)).GetEnumerator()
End Function
Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
Return GetEnumerator()
End Function
End Class
这个类的重要部分是它是可枚举的。也就是说,它返回开始日期和结束日期之间的日期序列(包括在for each
循环中使用)。
然后你可以用这样的代码来得到你想要的东西:
Dim ranges = New List(Of DateRange)()
ranges.Add(New DateRange(#2017/1/1#,#2017/1/10#))
ranges.Add(New DateRange(#2017/1/8#,#2017/1/20#))
Dim merged = ranges.SelectMany(Function(r) r.AsEnumerable()).Distinct().OrderBy(Function(dt) dt)
Console.WriteLine($"{merged.Count()} days: ")
For Each [date] As DateTime In merged
Console.WriteLine([date].ToShortDateString())
Next
Console.ReadLine()
这使用LINQ SelectMany
功能,所有在该DateRange
实例压扁日期的列表(由IEnuemrable
DateRange
创建)列表到DateTime
的单个列表。然后它获取不同的(唯一的)值,并对列表进行排序。
输出显示来自包含2个实例的列表的输出。第一个是2017年1月1日至2017年1月10日,第二个是2017年1月8日至2017年1月20日。这些范围在第8,9和10日重叠。如您所见,这些重叠日期只包含一次。
以下输出产生:
20天:
2017年1月1日
2017年1月2日
2017年1月3日
2017年1月4日
1 /二千○十七分之五
2017年1月6日
2017年1月7日
2017年1月8日
2017年1月9日
2017年1月10日
2017年1月11日
2017年1月12日
2017年1月13日
2017年1月14日
2017年1月15日
2017年1月16日
2017年1月17日
2017年1月18日
2017年1月19日
二零一七年一月二十零日
当你迭代时,你可以把重叠的日期放在列表或字典中,这样你就知道哪些已经被计数了 – Plutonix
我会先得到一个没有重叠的范围列表。在其他列表中循环并合并重叠范围。然后你可以得到天数。 –