Classic VB Corner

The Next Y2K

There's another one coming, and this one's still flying pretty far below the radar. Classic VB apps are only vulnerable to the extent they interact with others.

Ever heard the phrase "Unix time"? That's the most often-used description of the method of marking time by the number of seconds that have passed since January 1, 1970. A question arose the other day about this, and how negative values were starting to creep into VB calculations, ostensibly because of the way VB uses the high-bit to indicate sign.

Simple fix, thinks I! Just ignore the high-bit, treating the Long as unsigned. I started with some long archived routines I wrote back in the days before the Date variable type was introduced (everyone knows that ClassicVB Date variables are just Doubles in drag, right?):

Public Function NetTimeToVbTime(ByVal NetDate As Long) As Double
Const BaseDate# = 25569 'DateSerial(1970, 1, 1)
Const SecsPerDay# = 86400
NetTimeToVbTime = BaseDate + (CDbl(NetDate) / SecsPerDay)
End Function

Public Function VbTimeToNetTime(ByVal VbDate As Double) As Long
Const BaseDate# = 25569 'DateSerial(1970, 1, 1)
Const SecsPerDay# = 86400
VbTimeToNetTime = (VbDate - BaseDate) * SecsPerDay
End Function

The functions got their names because I was working with the various Net API functions at the time. Functions, such as NetUserGetInfo, provide dates for things such as last logon or password change using this "Unix time" method. That was okay when they were designed, because Windows as we know it didn't exist before 1970 and a DWORD holds a pretty big number of seconds.

Back to ignoring the high-bit. It turns out that if you can use only the first 31-bits, rather than all 32, the clock ticks down to KABOOM early in the morning on January 19, 2038. The 32nd bit effectively doubles that date with destiny, pushing it all the way out to February 7, 2106. Simple math:

' Clock rolls over on 1/19/2038 at 3:14:07 AM, if the
' basedate is the commonly used midnight on 1/1/1970.

Private Const BaseDate As Date = #1/1/1970#
Private Const Bit31 As Double = 2147483648# ' 0x80000000
Private Const Bit32 As Double = 4294967296# ' 0x100000000

Public Function NetTimeToVbTime(ByVal NetDate As Long) As Date
Dim Seconds As Double
Const SecsPerDay As Double = 86400
' Be aware that many "Unix" times are expressed in GMT, so
' you may also need to adjust for local offset as needed.
' See: http://vb.mvps.org/samples/TimeZone
If NetDate >= 0 Then
Seconds = CDbl(NetDate)
Else
Seconds = CDbl(NetDate) + Bit32
End If
NetTimeToVbTime = CDbl(BaseDate) + (Seconds / SecsPerDay)
End Function

Public Function VbTimeToNetTime(ByVal VbDate As Date) As Long
Dim Seconds As Double
' Supports VB Dates through: 2/7/2106 6:28:15 AM
Seconds = DateDiff("s", BaseDate, VbDate)
If Seconds >= Bit32 Then
' Houston, we have a problem!
ElseIf Seconds >= Bit31 Then
Seconds = Seconds - Bit32
End If
VbTimeToNetTime = Seconds
End Function

Problem solved! For now, anyway, right? Well, not so fast. It turns out that, even though Windows wasn't around back then, Unix was indeed around before 1970 and the negative numbers are by design. D'oh! Of course there's a need to express dates in the past, too. The explanation offered by Dennis Ritchie, the R of K&R fame, is that he thought it'd "be nice" to be able to represent his entire lifetime. Okay, he's perhaps earned that.

So then, this is just a heads-up, for those of you unaware as I was, of this impending global hand-wringing event we'll all be witnessing at some point down the road. The C/C++ runtimes are full of the same sort of date logic, of course. Just search MSDN for January 1, 1970 for some examples. Yes, there are some provisions for 64-bit logic, but those seem to be creeping in rather slowly. Meanwhile, there's oodles of code in the wild ticking down to Y2K38, and not all of it is even patchable, much less accessible. Just consider all the embedded devices that have long-term projected life spans.

This will be a "disaster" ClassicVB folks can pretty much rubber-neck, thankfully, due to the very long range built into our Date variables. To the extent that you're interacting with alien code bearing these limitations, however, you do need to be aware. You may start seeing negative values at any point, or you may be seeing them already. If your application could be working with date values just three decades from now, and you're swapping data with outside sources, it makes sense to start testing for these potential problems now.

About the Author

Karl E. Peterson wrote Q&A, Programming Techniques, and various other columns for VBPJ and VSM from 1995 onward, until Classic VB columns were dropped entirely in favor of other languages. Similarly, Karl was a Microsoft BASIC MVP from 1994 through 2005, until such community contributions were no longer deemed valuable. He is the author of VisualStudioMagazine.com's new Classic VB Corner column. You can contact him through his Web site if you'd like to suggest future topics for this column.

comments powered by Disqus

Featured

  • Creating Reactive Applications in .NET

    In modern applications, data is being retrieved in asynchronous, real-time streams, as traditional pull requests where the clients asks for data from the server are becoming a thing of the past.

  • AI for GitHub Collaboration? Maybe Not So Much

    No doubt GitHub Copilot has been a boon for developers, but AI might not be the best tool for collaboration, according to developers weighing in on a recent social media post from the GitHub team.

  • Visual Studio 2022 Getting VS Code 'Command Palette' Equivalent

    As any Visual Studio Code user knows, the editor's command palette is a powerful tool for getting things done quickly, without having to navigate through menus and dialogs. Now, we learn how an equivalent is coming for Microsoft's flagship Visual Studio IDE, invoked by the same familiar Ctrl+Shift+P keyboard shortcut.

  • .NET 9 Preview 3: 'I've Been Waiting 9 Years for This API!'

    Microsoft's third preview of .NET 9 sees a lot of minor tweaks and fixes with no earth-shaking new functionality, but little things can be important to individual developers.

  • Data Anomaly Detection Using a Neural Autoencoder with C#

    Dr. James McCaffrey of Microsoft Research tackles the process of examining a set of source data to find data items that are different in some way from the majority of the source items.

Subscribe on YouTube