Variant ignorance is rampant

Now is not the time to point the finger of blame. However! It’s quite possible that your programmers just aren’t aware that they shouldn’t be storing dates as strings. With this in mind, let’s take a whirlwind tour of the correct data types to use.

In Visual Basic 3, the Variant data type can be used to store dates of all shapes and sizes. Once a Variant contains a valid date, its VarType (the type of data that it contains) has the value 7 (or constant V_DATE in Visual Basic 3, vbDate in versions 4 and 5).

Date variants exhibit a unique behavior in that they expose their value externally in the format of a short date, but internally they store the value as a double-precision number. For example, try the following snippet of code in Visual Basic 3, and check out the two values for one variable:

Dim vDate As Variant
Dim sDate As String
vDate = CVDate("2/2/1996")
sDate = "2/2/1996"
MsgBox "As a Date, I look like: " & vDate
MsgBox "But internally, I look like: " & CDbl(vDate)
MsgBox "Adding 1, I look like this: " & vDate + 1
' This line will error.
MsgBox "But the string...: " & sDate + 1

Notice that the CDbl function shows the internal representation of the Variant date variable. This internal representation is the reason you’re able to accomplish simple arithmetic on the variable without having to subject it to any special conversion. If you want the last line of code above to work, you’ll need to convert the string to a date using the CVDate function.

Visual Basic versions 4 and 5 move the whole date-handling process one stage ahead by using the Date data type. This is not a Variant of type 7 but an actual data type in its own right. The Date data type is similar to the Variant(7) data type in the way that it exposes its external value as a date but internally processes itself as a double-precision number.

A few points about both Variant dates and Date data types are noteworthy. When the value of a date is exposed externally, it takes on the formatting characteristics of the short date format used by your system. For example, the standard short date format is MM/dd/yy. If you assign the value 3/17/1964 to a date variable (my birthday—all cards, cash, and so on accepted!) and then examine the variable, it has the external value 03/17/64. In other words, the year part of the date is displayed as a two-digit date, even though I explicitly assigned a four-digit year to the variable. Because the short date format of my system uses only two-year digits, this is how the Date data type will look regardless of the format of the value assigned to it. This thinking that the Date data type won’t store dates correctly could be another reason why programmers have not used it. Remember that internally the value is stored as a double, so it always knows which century it’s in.

The internal double value is actually the number of days since December 31, 1899, with the value 1 representing December 31, 1899; 2 representing January 1, 1900; and so on. If you move backward in time, the value starts counting down to a negative number. So if you try the code

Dim vDate As Variant
vDate = CDbl(CVDate("1/1/1899"))
MsgBox vDate

in Visual Basic 3, the value displayed will be -363 (locale permitting).

In Visual Basic 3, you should use the CVDate function to convert an expression to a Variant of type V_DATE(7). In Visual Basic 4 and 5, however, you can use the CDate function, which will convert an expression to a Date data type and not a Variant of type Date. This difference is subtle but useful to know.

Similarly, the DateValue function will return the Variant date value of an expression, not the Date data type value.