以下を使用してください(または同様の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()
これは、内のすべてのDateRange
のインスタンスから(IEnuemrable
DateRange
によって作成された)日付のリストを平らにするためにLINQ SelectMany
機能を使用していますDateTime
の単一のリストに一覧表示します。次に、別個の(一意の)値を取得し、リストをソートします。
出力には、2つのDateRange
インスタンスを含むリストからの出力が表示されます。 1つは2017年1月1日から2017年1月10日までで、2017年1月8日から2017年1月20日までの2番目のものです。これらの範囲は8,9,10で重複しています。ご覧のとおり、これらの重複した日付は一度だけ含まれています。
次の出力が生成される:
20日:2017年1月1日
2017年1月2日2017年1月3日
2017年1月4日
1/2017分の5
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日
2017年1月20日
重複した日付をリストまたは辞書に入れて、すでに数えられているものを知ることができます – Plutonix
最初に重複のない範囲のリストを取得します。ループし、他のリストの範囲をマージしてオーバーラップします。その後、あなたは日数を得ることができます。 –