Accurately Storing a Visual Basic 6 Date in an XML DOM Document

This document describes one possible way of how you can safely store a Visual Basic 6 Date datatype in an XML Document. Recently, I spent a significant amount of time trying to solve a very simple problem. In a Visual Basic 6 application, I had a variable of a Date datatype that I had to store in an XML DOM document. This seems easy enough; however, the problem is doing it without losing any of the accuracy of the Date datatype. Storing a Date in an XML file with a dateTime.tz datatype won't save all the milliseconds of this date. The method presented in this article works as long as you handle the XML document completely in VB6.

It appears that the if statement in the following code sometimes (depending on the accuracy of myDate1) returns dates are different:

' Creating an XML document with a root element
Set xmlDoc = New MSXML2.DOMDocument
Set xmlRoot = xmlDoc.createElement("root")
Set xmlDoc.documentElement = xmlRoot
' Assigning our date to the root element
xmlRoot.dataType = "dateTime.tz"
xmlRoot.nodeTypedValue = myDate1
' Serializing our document to XML, loading it again and
' retrieving our saved date
xmlDoc.loadXML (xmlDoc.xml)
myDate2 = xmlDoc.documentElement.nodeTypedValue
' Comparing the two dates...
If myDate1 <> myDate2 Then
   Call MsgBox("Dates are different")
Else
   Call MsgBox("Dates are the same")
End If

The source of this problem is Visual Basic 6's inability to handle milliseconds stored in dates. These other options also don't work or are too big of a headache to implement in VB6:

  • Converting it to a string removes all milliseconds.
  • Converting it to a Double and storing it as a string-typed XML element makes you worry about regional settings in VB6.
  • Converting it to a Double and storing it as a float-typed XML element also loses some accuracy.

This behavior appears to be independent of the version of the Microsoft XML Parser used. I've tried using Microsoft XML v2.6, v3.0, v4.0 and v5.0, and in each case this behavior appears.

The code with this article is a small VB6 project that you can use to reproduce this behavior. It uses Microsoft XML v4.0, but because this is installed by default on a Windows XP (if I remember correctly), you should be able to run it perfectly if you have VB6 installed. If you look at the source of this project, you'll see that you have to do some effort to reproduce this problem. I have encountered this problem because I was handling dates that were originally calculated by the GETDATE() function of SQL Server 2000, which is accurate to about three milliseconds. You will never see the problem, however, if you only use the Now function of Visual Basic because this function never returns a date that is sufficiently accurate.

The solution that I've used simply reads the memory used by the date, converts each byte to its hexadecimal representation, and saves this in a string. This string then can safely be used in an XML element without losing accuracy and without worrying about regional settings. For example, the date 2005-09-30 17:07:59.623 is converted to 3F5C24D836DCE240.

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
   (pDst As Any, pSrc As Any, ByVal ByteLen As Long)
Private Type DateTimeStructure
   Value(7) As Byte
End Type
Public Function AccurateDateToString(ByVal lcDate As Date) As String
   Dim strDate As String
   Dim objDate As DateTimeStructure
   Dim i As Byte

   Call CopyMemory(ByVal VarPtr(objDate), ByVal VarPtr(lcDate), 8)
   For i = 1 To 8
      strDate = strDate & Right("0" & Hex(objDate.Value(i - 1)), 2)
   Next
   AccurateDateToString = strDate
End Function
Public Function AccurateStringToDate(ByVal lcDate As String) As Date
   Dim dtmDate As Date
   Dim objDate As DateTimeStructure
   Dim i As Byte
   For i = 1 To 8
      objDate.Value(i - 1) = Val("&h" & mID(lcDate, (i * 2) - 1, 2))
   Next
   Call CopyMemory(ByVal VarPtr(dtmDate), ByVal VarPtr(objDate), 8)
   AccurateStringToDate = dtmDate
End Function

As you can see, the code contains two functions—one called AccurateDateToString that can be used to convert a Date to its string representation, and one called AccurateStringToDate that does the reverse. Because the date stored in the XML file is nothing more than a memory dump of a VB6 date, it'll be difficult to use it in other environments. For me, this wasn't an issue because the XML file that I created is only used internally in my project and, because of this, there never is any need to access it using another application.



About the Author

Michael Vanhoutte

I am a developer spending most of my time in C#, .NET 2.0 and Sql Server 2005. I am working for a Belgium company called Alfaprint developing Asset Management Software. More information about my company and our software can be found at http://www.adam.be.

Downloads

Comments

  • No need for that

    Posted by fclage on 10/20/2005 09:48am

    No need for so many lines of code, or even api declarations.
    
    Just convert the date to a double.
    ex:
    
    dim a as date, b as double
    
    a = now
    
    b = a
    ' VB6 automatically converts it to double (no need to add CDBL)
    
    debug.print "Date value : " & b
    
    ' Get the date back again from double value to date
    debug.print "The date from double: " & cdate(b)
    
    If you wish to save just the 8 bytes you can convert the double to a byte array (like your example does), but you can have problems with special ascii chars by doing so (even using MSXML components those parse errors may occur).
    
    Anyway, you can avoid the for next by using the StrConv function from VB.
    
    
    Just my 2c anyway ;)
    
    // FCLage

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Java developers know that testing code changes can be a huge pain, and waiting for an application to redeploy after a code fix can take an eternity. Wouldn't it be great if you could see your code changes immediately, fine-tune, debug, explore and deploy code without waiting for ages? In this white paper, find out how that's possible with a Java plugin that drastically changes the way you develop, test and run Java applications. Discover the advantages of this plugin, and the changes you can expect to see …

  • As a result of corporate expansions, mergers, and acquisitions, the teams and technologies that support an organization's IT service management (ITSM) practices can over time become somewhat dispersed. Supporting an organization's strategic objectives, and providing consistent and quality IT support is essential, but this can be challenging where disconnected support environments exist. While physically centralizing support is not always possible, nor is it always desirable, delivering a consistent and …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds