Operators for System.DateTime, continued from
Part 3In this article I shall continue to deal with operators, but those specifically which
will allow assignment of System.DateTime values and System.Data.SqlTypes.SqlDateTime values to the DateTimeNull object or
vice-versa.
#Region "Operators for System.DateTime"
''' <summary>
''' Converts a System.DateTime structure to a DateTimeNull object.
''' </summary>
''' <param name="value">A DateTime structure. </param>
''' <returns>A DateTimeNull object whose Value is equal to the combined Date and TimeOfDay properties of the supplied System.DateTime structure.</returns>
Public Shared Widening Operator CType(ByVal value As System.DateTime) As DateTimeNull
Return New DateTimeNull(value)
End Operator
''' <summary>
''' Converts a DateTimeNull object to a System.DateTime structure.
''' </summary>
''' <param name="value">a DateTimeNull</param>
''' <returns>A System.DateTime structure whose Value is equal to the combined Date and TimeOfDay properties of the supplied DateTimeNull object.</returns>
Public Shared Widening Operator CType(ByVal value As DateTimeNull) As System.DateTime
If value.HasValue Then
Return value.InternalDate
Else
Throw New InvalidCastException("Cannot convert Null DateTimeNull to System.DatetTime.")
End If
End Operator
#End RegionThese two widening operators allow us to write the following code without compile errors:
Dim nullableDate As DateTimeNull = Nothing
Dim systemDate As System.DateTime
nullableDate = systemDate
systemDate = nullableDate
The first widening operator lets us cast from a System.DateTime to our DateTimeNull object, and the second one back again. Even with these two operators we cant yet do comparison checks between the two types. The code below will not compile.
If nullableDate = systemDate Then
End If
If systemDate = nullableDate Then
End If
For that to happen we need to add an equality operators. The code below will allow the first equality check to compile. Please note for every "equals" operator, you must provide a "not equals" operator too.
''' <summary>
''' Determines whether one specified DateTimeNull is equal to another specified DateTime.
''' </summary>
''' <param name="d1">A DateTimeNull.</param>
''' <param name="d2">A System.DateTime.</param>
''' <returns><c>true</c> if d1 is not null and d1 is equal to d2; otherwise, false.</returns>
Public Shared Operator =(ByVal d1 As DateTimeNull, ByVal d2 As System.DateTime) As Boolean
If d1.HasValue Then
Return (d1.InternalDate = d2)
Else
Return False
End If
End Operator
''' <summary>
''' Determines whether one specified DateTimeNull is not equal to another specified DateTime.
''' </summary>
''' <param name="d1">A DateTimeNull.</param>
''' <param name="d2">A System.DateTime.</param>
''' <returns><c>true</c> if d1 is not null and d1 is not equal to d2; otherwise, false.</returns>
Public Shared Operator <>(ByVal d1 As DateTimeNull, ByVal d2 As System.DateTime) As Boolean
If d1.HasValue Then
Return Not (d1.InternalDate = d2)
Else
Return False
End If
End OperatorWe now need another pair of operators for the second condition.
''' <summary>
''' Determines whether one specified System.DateTime is equal to another specified DateTimeNull.
''' </summary>
''' <param name="d1">A System.DateTime.</param>
''' <param name="d2">A DateTimeNull.</param>
''' <returns><c>true</c> if d1 is not null and d1 is equal to d2; otherwise, false.</returns>
Public Shared Operator =(ByVal d1 As System.DateTime, ByVal d2 As DateTimeNull) As Boolean
If d2.HasValue Then
Return (d1 = d2.InternalDate)
Else
Return False
End If
End Operator
''' <summary>
''' Determines whether one specified System.DateTime is not equal to another specified DateTimeNull.
''' </summary>
''' <param name="d1">A System.DateTime.</param>
''' <param name="d2">A DateTimeNull.</param>
''' <returns><c>true</c> if d1 is not null and d1 is not equal to d2; otherwise, false.</returns>
Public Shared Operator <>(ByVal d1 As System.DateTime, ByVal d2 As .DateTimeNull) As Boolean
If d2.HasValue Then
Return Not (d1 = d2.InternalDate)
Else
Return False
End If
End OperatorWe may now wish to take the time to add in some "greater-than-or-equal-to" and "less-than-or-equal-to" operators for these two data types.
''' <summary>
''' Determines whether one specified DateTimeNull is less than or equal to another specified System.DateTime.
''' </summary>
''' <param name="d1">A DateTimeNull.</param>
''' <param name="d2">A System.DateTime.</param>
''' <returns><c>true</c> if d1 is not null and d1 is less than or equal to d2; otherwise, false.</returns>
Public Shared Operator <=(ByVal d1 As DateTimeNull, ByVal d2 As System.DateTime) As Boolean
If d1.HasValue Then
Return (d1.InternalDate <= d2)
Else
Return False
End If
End Operator
''' <summary>
''' Determines whether one specified DateTimeNull is greater than or equal to another specified System.DateTime.
''' </summary>
''' <param name="d1">A DateTimeNull.</param>
''' <param name="d2">A System.DateTime.</param>
''' <returns><c>true</c> if d1 is not null and d1 is greater than or equal to d2; otherwise, false.</returns>
Public Shared Operator >=(ByVal d1 As DateTimeNull, ByVal d2 As System.DateTime) As Boolean
If d1.HasValue Then
Return (d1.InternalDate >= d2)
Else
Return False
End If
End Operator
Remember to provide operators for both left and right evaluation of the DateTimeNull object.
Casting to and from System.Data.SqlTypes.SqlDateTimeTo allow cross casting between our DateTimeNull object and the System.Data.SqlTypes.SqlDateTime we just follow the same process and add in the widening and comparison operators as we did for the System.DateTime, but we do need to keep in mind the upper and lower date limits of the System.Data.SqlTypes.SqlDateTime structure or an out of range error could happen at run-time. So evaluate the value and throw an appropriate exception as necessary in the operator.
In Part 5, we will look at some of the methods we may need to implement