88

In VB.NET, is there a way to set a DateTime variable to "not set"? And why is it possible to set a DateTime to Nothing, but not possible to check if it is Nothing? For example:

Dim d As DateTime = Nothing
Dim boolNotSet As Boolean = d Is Nothing 

The second statement throws this error:

'Is' operator does not accept operands of type 'Date'. Operands must be reference or
nullable types.
DavidRR
  • 18,291
  • 25
  • 109
  • 191
Muleskinner
  • 14,150
  • 19
  • 58
  • 79
  • 1
    In addition to John Gant's answer below, you can also check if the datetime variable = Nothing (Note the = instead of "is"). – DCNYAM May 03 '11 at 12:51
  • Thanks, using Dim boolNotSet As Boolean = d = Nothing seems like the most simple solution right now. Interesting with the Nullable casting never seen that before – Muleskinner May 03 '11 at 13:02
  • @Chris - I think He is using VB – Karthik Ratnam May 03 '11 at 13:22
  • @Karthik Ratnam, yes he is but it amounts to the same thing and @Marc Gravell's answer gets all of the points across. – Chris Haas May 03 '11 at 13:24
  • @Chris Haas: Not really, because of the Nothing keyword which has no equivalent in C#. This is not a duplicate. – Meta-Knight May 03 '11 at 13:53
  • 1
    @NYSystemsAnalyst: according to [Nothing (Visual Basic)](http://msdn.microsoft.com/en-us/library/0x9tb07z%28v=vs.110%29), using `= Nothing` or `<> Nothing` is not good practice: "When checking whether a reference (or nullable value type) variable is **null**, do not use `= Nothing` or `<> Nothing`. Always use `Is Nothing` or `IsNot Nothing`." – DavidRR Sep 12 '12 at 14:54
  • @DavidRR I believe you mean `Not Is Nothing` – Muleskinner Sep 12 '12 at 19:43
  • @Muleskinner: I believe that `IsNot Nothing` and `Not Is Nothing` are equivalent. From [IsNot Operator (Visual Basic)](http://msdn.microsoft.com/en-us/library/t3bat82c%28v=vs.110%29): "**IsNot** is the opposite of the **Is** operator. The advantage of **IsNot** is that you can avoid awkward syntax with **Not** and **Is**, which can be difficult to read." – DavidRR Sep 12 '12 at 20:08
  • @Muleskinner: Here is the list of the [keywords](http://msdn.microsoft.com/en-us/library/dd409611%28v=vs.110%29) in the Visual Studio 2012 edition of Visual Basic. Not sure how long the `IsNot` keyword has been around. – DavidRR Sep 12 '12 at 20:16
  • @DavidRR Sorry my mistake, I see it was introduced in Visual Basic 2005 – Muleskinner Sep 12 '12 at 21:44
  • Be careful with using variable = nothing, this can lead to NullReferenceException – Maddin Jul 03 '17 at 12:12

8 Answers8

150

This is one of the biggest sources of confusion with VB.Net, IMO.

Nothing in VB.Net is the equivalent of default in C#: the default value for the given type.

  • For value types, this is essentially the equivalent of 'zero': 0 for Integer, False for Boolean, DateTime.MinValue for DateTime, ...
  • For reference types, it is the null value (a reference that refers to, well, nothing).

The statement d Is Nothing is therefore equivalent to d Is DateTime.MinValue, which obviously does not compile.

Solutions: as others have said

  • Either use DateTime? (i.e. Nullable(Of DateTime)). This is my preferred solution.
  • Or use d = DateTime.MinValue or equivalently d = Nothing

In the context of the original code, you could use:

Dim d As DateTime? = Nothing
Dim boolNotSet As Boolean = Not d.HasValue

A more comprehensive explanation can be found on Anthony D. Green's blog

jeroenh
  • 26,362
  • 10
  • 73
  • 104
  • 1
    Thanks for explaining. It is interesting to note that isNothing(d) does not work but d = Nothing does! – phn Nov 09 '18 at 10:53
16

DateTime is a value type, which is why it can't be null. You can check for it to be equal to DateTime.MinValue, or you can use Nullable(Of DateTime) instead.

VB sometimes "helpfully" makes you think it's doing something it's not. When it lets you set a Date to Nothing, it's really setting it to some other value, maybe MinValue.

See this question for an extensive discussion of value types vs. reference types.

Community
  • 1
  • 1
John M Gant
  • 18,970
  • 18
  • 64
  • 82
5

DateTime is a value type, which means it always has some value.

It's like an integer - it can be 0, or 1, or less than zero, but it can never be "nothing".

If you want a DateTime that can take the value Nothing, use a Nullable DateTime.

Cheeso
  • 189,189
  • 101
  • 473
  • 713
4

Some examples on working with nullable DateTime values.

(See Nullable Value Types (Visual Basic) for more.)

'
' An ordinary DateTime declaration. It is *not* nullable. Setting it to
' 'Nothing' actually results in a non-null value.
'
Dim d1 As DateTime = Nothing
Console.WriteLine(String.Format("d1 = [{0}]\n", d1))
' Output:  d1 = [1/1/0001 12:00:00 AM]

' Console.WriteLine(String.Format("d1 is Nothing? [{0}]\n", (d1 Is Nothing)))
'
'   Compilation error on above expression '(d1 Is Nothing)':
'
'      'Is' operator does not accept operands of type 'Date'.
'       Operands must be reference or nullable types.

'
' Three different but equivalent ways to declare a DateTime
' nullable:
'
Dim d2? As DateTime = Nothing
Console.WriteLine(String.Format("d2 = [{0}][{1}]\n", d2, (d2 Is Nothing)))
' Output:  d2 = [][True]

Dim d3 As DateTime? = Nothing
Console.WriteLine(String.Format("d3 = [{0}][{1}]\n", d3, (d3 Is Nothing)))
' Output:  d3 = [][True]

Dim d4 As Nullable(Of DateTime) = Nothing
Console.WriteLine(String.Format("d4 = [{0}][{1}]\n", d4, (d4 Is Nothing)))
' Output:  d4 = [][True]

Also, on how to check whether a variable is null (from Nothing (Visual Basic)):

When checking whether a reference (or nullable value type) variable is null, do not use = Nothing or <> Nothing. Always use Is Nothing or IsNot Nothing.
DavidRR
  • 18,291
  • 25
  • 109
  • 191
1

In any programming language, be careful when using Nulls. The example above shows another issue. If you use a type of Nullable, that means that the variables instantiated from that type can hold the value System.DBNull.Value; not that it has changed the interpretation of setting the value to default using "= Nothing" or that the Object of the value can now support a null reference. Just a warning... happy coding!

You could create a separate class containing a value type. An object created from such a class would be a reference type, which could be assigned Nothing. An example:

Public Class DateTimeNullable
Private _value As DateTime

'properties
Public Property Value() As DateTime
    Get
        Return _value
    End Get
    Set(ByVal value As DateTime)
        _value = value
    End Set
End Property

'constructors
Public Sub New()
    Value = DateTime.MinValue
End Sub

Public Sub New(ByVal dt As DateTime)
    Value = dt
End Sub

'overridables
Public Overrides Function ToString() As String
    Return Value.ToString()
End Function

End Class

'in Main():

        Dim dtn As DateTimeNullable = Nothing
    Dim strTest1 As String = "Falied"
    Dim strTest2 As String = "Failed"
    If dtn Is Nothing Then strTest1 = "Succeeded"

    dtn = New DateTimeNullable(DateTime.Now)
    If dtn Is Nothing Then strTest2 = "Succeeded"

    Console.WriteLine("test1: " & strTest1)
    Console.WriteLine("test2: " & strTest2)
    Console.WriteLine(".ToString() = " & dtn.ToString())
    Console.WriteLine(".Value.ToString() = " & dtn.Value.ToString())

    Console.ReadKey()

    ' Output:
    'test1:  Succeeded()
    'test2:  Failed()
    '.ToString() = 4/10/2012 11:28:10 AM
    '.Value.ToString() = 4/10/2012 11:28:10 AM

Then you could pick and choose overridables to make it do what you need. Lot of work - but if you really need it, you can do it.

sscheider
  • 522
  • 5
  • 14
1

You can also use below just simple to check:

If startDate <> Nothing Then
your logic
End If

It will check that the startDate variable of DateTime datatype is null or not.

Mahavirsinh Padhiyar
  • 1,299
  • 11
  • 33
1

You can check this like below :

if varDate = "#01/01/0001#" then
       '  blank date. do something.
else
       ' Date is not blank. Do some other thing
end if
Sukhi
  • 13,261
  • 7
  • 36
  • 53
0

A way around this would be to use Object datatype instead:

Private _myDate As Object
Private Property MyDate As Date
    Get
        If IsNothing(_myDate) Then Return Nothing
        Return CDate(_myDate)
    End Get
    Set(value As Date)
        If date = Nothing Then
            _myDate = Nothing
            Return
        End If
        _myDate = value
     End Set
End Property

Then you can set the date to nothing like so:

MyDate = Nothing
Dim theDate As Date = MyDate
If theDate = Nothing Then
    'date is nothing
End If
George Filippakos
  • 16,359
  • 15
  • 81
  • 92