that new old thing: a date2num implementation in vb.net
Hell must be freezing over because I'm doing a lot more VB.NET development these days. Visual Studio 2013 and the .NET 4.5 framework are, in my opinion, the first usable versions of these products. As part of a project to port some of our legacy code from VB6 to VB.NET I've been converting all of the common functions and shared utility libraries we've built up over the years. Some libraries date back to the migration from QuickBasic/PDS 7 on DOS to Visual Basic on Windows.
Back in those days we used very simple yet powerful functions to do things like date math accurately. For example, in the old days, programmers had to account for leap year manually, if they didn't have a good toolset on hand. One of those toolsets was called QuickPak, a library of handy functions written in Assembler that could be linked to your BASIC program to do these things accurately and easily.
The function that sold systems -- our systems -- as being the most accurate product on the market at the time, was a function called Date2num. In short, its the number of days elapsed since 01/01/1979 and it was the basis of all calendar and date manipulation in the system. Take the date2num of a date, and apply a mod 7 and you could determine what day of the week it was for any date. By today's standards that seems kind of "big whoop" but in the days of CGA monitors and 360k floppy drives, being able to do this calculation accurately was a big deal.
So, flash forward to 2014. Some of that code from 1988 is now staring into the abyss of VB.NET. First, I needed to eliminate the dependency on a legacy 32-bit dll, namely qpro32.dll. That part was easy. In VB6 I already had figured out an all-code version of date2num, I can just use that! Right? Well... Not exactly.
Public Function Date2Num(ByVal strDate As String) As Integer
If IsDate(strDate) Then
Date2Num = Cint(CDate(strDate)) - 29220
Else
Date2Num = -32768
End If
End Function
Pretty simple right? Convert a date to its raw visual basic internal format (elapsed days since 01/01/1900) and adjust it with a predetermined constant to make it based on 1979. Nope. VB.Net is strongly typed so my little trick of converting a date to its "raw" form fails miserably. To make a long story short, and probably nobody really cares all that much, here's VB.NET version of the same function.
Public Shared Function Date2Num(ByVal strDate As String) As Integer
If IsDate(strDate) Then
Dim epoch As New DateTime(1979, 12, 31)
Dim dt As DateTime = CDate(strDate)
Dim ts As TimeSpan = dt.Subtract(epoch)
Date2Num = ts.Days
Else
Date2Num = -32768
End If
End Function
So there you have it. date2num ported to VB.NET. Tomorrow, maybe, I'll do the inverse function num2date.
' Num2date, tested to be 100% compatible with the original QuickPak function
ReplyDeletePublic Shared Function Num2Date(ByVal nDate As Integer) As String
If nDate <= -29220 Then
Num2Date = "%%%%%%%%%%"
ElseIf nDate > 31368 Then
Num2Date = "%%%%%%%%%%"
Else
Num2Date = Format(nDate + 29220, "MM/DD/YYYY")
End If
End Function