Dennis,
| I don't understand the
| reason for using ranges for determining if a date is between two dates.
Martin Fowler I believe answers that question at:
| >
http://www.martinfowler.com/ap2/range.html
Here are my thoughts on it, in a David Letterman style top 10 list ;-)
10) It has to do with Object Thinking & OO; Abstraction, Encapsulation, Code
Reuse, Duplication.
9) With Kerry's code you have two independent variables floating around,
which are related via the expression. being independent, means that can
change independently possibly inappropriately.
8) With Kerry's code you have an expression that is possibly duplicated all
over your program. Doesn't necessarily leverage code reuse
7) DateRange & TimeRange *encapsulate* special logic in them to ensure that
the Date part or the Time part of a DateTime are handled correctly!
6) With a Range object you have a single variable which has specific
attributes & behavior (an Abstraction).
5) The Range object has a Start, End properties and also Contains & Overlaps
methods or behaviors (Encapsulation).
4) With a Range object you are thinking in terms of an Object, the Range
itself. You ask the range if this value is contained within it.
3) With a Range object the expression is confined to the Range.Contains
method. In fact the overloaded Range.Contains method & the Range.Overlaps
method are implemented in terms of the first Range.Contains method avoiding
duplication.
2) With a Range object, you only need to test the Range type "once", then
you are "assured" that Range will always return the results you want. Code
reuse, verifiable.
1) More importantly I consider the usage of the Range object to be more
readable.
Given:
Dim date1 As DateTime = "12/1/2005"
Dim date2 As DateTime = "12/31/2005"
Dim december2005 As New Range(Of DateTime)(#12/1/2005#, #12/31/2005#)
Dim myDate As DateTime = DateTime.Now
Which of the following more directly shows that you are checking to see if
December 2005 contains myDate?
If december2005.Contains(myDate) Then
If myDate >= date1 And myDate <= date2 Then
Even if you rename date1 & date2 to start & finish, you need to think about
what the expression means...
BTW: I used "Contains" rather then "Between" or "Includes" to be consistent
with the rest of the Framework, so simply seeing "Contains" above should
give you a clue that
"december2005.Contains(myDate)" is doing something similar to
"list.Contains(key)"...
Now if you only have a single place where you are checking a Range for a
Value, then yes a Range object may be overkill, however if you are checking
a Range for a Value in a number of places, such as time entry, time
accounting, insurance products, or anything else that deals with a
"calendar", then I would expect the Range will simplify & clarify your code!
BTW: If you look closely you will see that the Range.Contains method is
effectively the same expression as Kerry's code. The Range simply
encapsulates Kerry's date1 & date2 variables & his expression into a single
Type.
If myDate >= date1 And myDate <= date2 Then
| > Return m_start.CompareTo(value) <= 0 AndAlso
value.CompareTo(m_end)
| > <= 0
To be useful this Type then has other behavior added to it (the overloaded
Contains, the Overlaps, Equality, properties). Also the Range is designed as
Immutable, meaning you need to create an entirely new Range rather then
modifying an existing Range.
When I converted the Range(Of T) to DateRange, I left the
IComparable.CompareTo methods in instead of unwrapping them to the
overloaded operators. The Range(Of T) itself cannot use the overloaded
operators.
--
Hope this helps
Jay [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley -
http://www.tsbradley.net
"Dennis" <De****@discussions.microsoft.com> wrote in message
news:C8**********************************@microsof t.com...
| Just curious but is there something wrong with the code offered by Kerry?
| His seems a lot more direct and shorter to implement. I don't understand
the
| reason for using ranges for determining if a date is between two dates.
| --
| Dennis in Houston
|
|
| "Jay B. Harlow [MVP - Outlook]" wrote:
|
| > Dave,
| > I would use a Range Pattern:
| >
http://www.martinfowler.com/ap2/range.html
| >
| > Dim december2005 As New Range(Of DateTime)(#12/1/2005#,
#12/31/2005#)
| > If december2005.Contains(DateTime.Now) Then
| > ' do something exciting because its December!
| > End If
| >
| >
| > I have a Range(Of T) defined at (usable in VS 2005):
| >
http://www.tsbradley.net/Cookbook/Ge...ericRange.aspx
| >
| >
| > I have a TimeRange defined at (usable in VS 2002, 2003 & 2005):
| >
http://www.tsbradley.net/Cookbook/Pa...timeRange.aspx
| >
| >
| > If you want a "plain" DateRange that is usable in VS 2002, 2003 or 2005,
you
| > can use something like:
| >
| > '
| > ' Copyright © 2005, Jay B. Harlow, All Rights Reserved.
| > '
| > Option Strict On
| > Option Explicit On
| >
| > Public Structure DateRange
| >
| > Private ReadOnly m_start As DateTime
| > Private ReadOnly m_end As DateTime
| >
| > Public Sub New(ByVal start As DateTime, ByVal [end] As DateTime)
| > m_start = start.Date
| > m_end = [end].Date
| > End Sub
| >
| > Public ReadOnly Property Start() As DateTime
| > Get
| > Return m_start
| > End Get
| > End Property
| >
| > Public ReadOnly Property [End]() As DateTime
| > Get
| > Return m_end
| > End Get
| > End Property
| >
| > Public ReadOnly Property IsEmpty() As Boolean
| > Get
| > Return m_start.CompareTo(Nothing) = 0 AndAlso
| > m_end.CompareTo(Nothing) = 0
| > Return m_start.Equals(Nothing) AndAlso m_end.Equals(Nothing)
| > End Get
| > End Property
| >
| > Public Function Contains(ByVal value As DateTime) As Boolean
| > value = value.Date
| > Return m_start.CompareTo(value) <= 0 AndAlso
value.CompareTo(m_end)
| > <= 0
| > End Function
| >
| > Public Function Contains(ByVal value As DateRange) As Boolean
| > Return Me.Contains(value.m_start) AndAlso
Me.Contains(value.m_end)
| > End Function
| >
| > Public Function Overlaps(ByVal value As DateRange) As Boolean
| > Return Me.Contains(value) OrElse value.Contains(m_start) OrElse
| > value.Contains(m_end)
| > End Function
| >
| > Public Overrides Function GetHashCode() As Integer
| > Return m_start.GetHashCode() Xor m_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 m_start.Equals(other.m_start) AndAlso
| > m_end.Equals(other.m_end)
| > End Function
| >
| > End Structure
| >
| > NOTE: Range(Of DateTime) will include both the Date & the Time values of
a
| > DateTime, the above DateRange only considers the Date part of a
DateTime.
| > While the above TimeRange only consider the Time part of a DateTime.
| >
| > --
| > Hope this helps
| > Jay [MVP - Outlook]
| > ..NET Application Architect, Enthusiast, & Evangelist
| > T.S. Bradley -
http://www.tsbradley.net
| >
| >
| > <df********@hotmail.com> wrote in message
| > news:11**********************@o13g2000cwo.googlegr oups.com...
| > | Anyone have some code that will do this?
| > |
| > | Dave
| > |
| >
| >
| >