Update: mi sono accorto che il codice messo nel container era illeggibile... per cui l'ho tolto...
Come promesso, ecco la mia struttura per la gestione di intervalli di date.
Il corsivo deriva dal fatto che la classe è ispirata dal pattern Range, di cui ho implementato quello che mi serviva. Parte del lavoro l'ho già trovato "pronto" in questo thread. Se non è riutilizzo del codice questo....
Public Structure DateRange
Public Enum IntervalType
Milliseconds
Second
Minute
Hour
Day
End Enum
Public Enum Direction
Foward
Backward
End Enum
Private _start As DateTime
Public Property Start() As DateTime
Get
Return _start
End Get
Set(ByVal value As DateTime)
_start = value
End Set
End Property
Private _end As DateTime
Public Property [End]() As DateTime
Get
Return _end
End Get
Set(ByVal value As DateTime)
_end = value
End Set
End Property
Public Sub New(ByVal start As DateTime, ByVal [end] As DateTime)
_start = start
_end = [end]
End Sub
Public ReadOnly Property IsEmpty() As Boolean
Get
Return _start.CompareTo(Nothing) = 0 AndAlso _end.CompareTo(Nothing) = 0
Return _start.Equals(Nothing) AndAlso _end.Equals(Nothing)
End Get
End Property
Public Function Contains(ByVal value As DateTime) As Boolean
Dim dateValue As DateTime = value
Return _start.CompareTo(dateValue) <= 0 AndAlso dateValue.CompareTo(_end) <= 0
End Function
Public Function Contains(ByVal other As DateRange) As Boolean
Return Me.Contains(other._start) AndAlso Me.Contains(other._end)
End Function
Public Function Intersect(ByVal other As DateRange) As Boolean
Return Not (Me.Contains(other)) OrElse other.Contains(_start) OrElse other.Contains(_end)
End Function
Public Function Overlaps(ByVal other As DateRange) As Boolean
Return Me.Contains(other) OrElse other.Contains(_start) OrElse other.Contains(_end)
End Function
Public Function Intersection(ByVal other As DateRange) As DateRange
If Not Me.Overlaps(other) Then Return Nothing
If Me.Contains(other) Then Return other
If other.Contains(Me) Then Return Me
If Me.Start > other.Start Then
Return New DateRange(Me.Start, other.End)
Else
Return New DateRange(other.Start, Me.End)
End If
End Function
Public Function Subtraction(ByVal other As DateRange) As IList(Of DateRange)
Dim ret As New List(Of DateRange)
If Me.Overlaps(other) AndAlso Not other.Contains(Me) AndAlso Not Me.Equals(other) Then
If Me.Contains(other) Then
If Not Me.Start = other.Start Then ret.Add(New DateRange(Me.Start, other.Start))
If Not Me.End = other.End Then ret.Add(New DateRange(other.End, Me.End))
Else
If Me.Start >= other.Start Then
ret.Add(New DateRange(other.End, Me.End))
Else
ret.Add(New DateRange(Me.Start, other.End))
End If
End If
End If
Return ret
End Function
Public Function Total(ByVal intervalType As IntervalType) As Double
Select Case intervalType
Case intervalType.Day
Return _end.Subtract(_start).TotalDays
Case intervalType.Hour
Return _end.Subtract(_start).TotalHours
Case intervalType.Milliseconds
Return _end.Subtract(_start).TotalMilliseconds
Case intervalType.Minute
Return _end.Subtract(_start).TotalMinutes
Case intervalType.Second
Return _end.Subtract(_start).TotalSeconds
End Select
End Function
Public Function Extend(ByVal value As Integer, ByVal intervalType As IntervalType, ByVal direction As Direction) As DateRange
Select Case intervalType
Case intervalType.Day
If direction = DateRange.Direction.Backward Then
Return New DateRange(_start.AddDays(-1 * value), _end)
Else
Return New DateRange(_start, _end.AddDays(value))
End If
Case intervalType.Hour
If direction = DateRange.Direction.Backward Then
Return New DateRange(_start.AddHours(-1 * value), _end)
Else
Return New DateRange(_start, _end.AddHours(value))
End If
Case intervalType.Minute
If direction = DateRange.Direction.Backward Then
Return New DateRange(_start.AddMinutes(-1 * value), _end)
Else
Return New DateRange(_start, _end.AddMinutes(value))
End If
Case intervalType.Second
If direction = DateRange.Direction.Backward Then
Return New DateRange(_start.AddSeconds(-1 * value), _end)
Else
Return New DateRange(_start, _end.AddSeconds(value))
End If
Case intervalType.Milliseconds
If direction = DateRange.Direction.Backward Then
Return New DateRange(_start.AddMilliseconds(-1 * value), _end)
Else
Return New DateRange(_start, _end.AddMilliseconds(value))
End If
End Select
End Function
Public Function Shift(ByVal value As Integer, ByVal intervalType As IntervalType, ByVal direction As Direction) As DateRange
Select Case intervalType
Case intervalType.Day
If direction = DateRange.Direction.Foward Then
Return New DateRange(_start.AddDays(value), _end.AddDays(value))
Else
Return New DateRange(_start.AddDays(-1 * value), _end.AddDays(-1 * value))
End If
Case intervalType.Hour
If direction = DateRange.Direction.Foward Then
Return New DateRange(_start.AddHours(value), _end.AddHours(value))
Else
Return New DateRange(_start.AddHours(-1 * value), _end.AddHours(-1 * value))
End If
Case intervalType.Minute
If direction = DateRange.Direction.Foward Then
Return New DateRange(_start.AddMinutes(value), _end.AddMinutes(value))
Else
Return New DateRange(_start.AddMinutes(-1 * value), _end.AddMinutes(-1 * value))
End If
Case intervalType.Second
If direction = DateRange.Direction.Foward Then
Return New DateRange(_start.AddSeconds(value), _end.AddSeconds(value))
Else
Return New DateRange(_start.AddSeconds(-1 * value), _end.AddSeconds(-1 * value))
End If
Case intervalType.Milliseconds
If direction = DateRange.Direction.Foward Then
Return New DateRange(_start.AddMilliseconds(value), _end.AddMilliseconds(value))
Else
Return New DateRange(_start.AddMilliseconds(-1 * value), _end.AddMilliseconds(-1 * value))
End If
End Select
End Function
Public Overrides Function GetHashCode() As Integer
Return _start.GetHashCode() Xor _end.GetHashCode()
End Function
Public Overloads Overrides Function Equals(ByVal obj As Object) As Boolean
If TypeOf obj Is DateRange Then
Return Equals(DirectCast(obj, DateRange))
Else
Return False
End If
End Function
Public Overloads Function Equals(ByVal other As DateRange) As Boolean
Return _start.Equals(other._start) AndAlso _end.Equals(other._end)
End Function
End Structure