Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Convert 64bit hex string to date?

Status
Not open for further replies.

markdmac

MIS
Dec 20, 2003
12,340
US
Below is some simple code that I am using to grab some inventory information. This works perfectly on Windows XP, Windows 2003 and Windows 7. However on Windows Vista and WIndows 2008 the InstalledOn data is in a format I am totally unfamiliar with. It appears to be some form of a hex value.

Code:
On Error Resume Next
strComputer = "."
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_QuickFixEngineering",,48)
For Each objItem in colItems
    Wscript.Echo "HotFixID: " & objItem.HotFixID
    Wscript.Echo "InstallDate: " & objItem.InstallDate
    Wscript.Echo "InstalledOn: " & objItem.InstalledOn
Next

The output that I get for InstalledOn is:
Code:
01c9c5ce4b48e5fd
When I compare that to the data I see in the GUI via Add/Remove Programs the real date for that hotfix is:
Code:
4/25/2009

I've been researching and the best I can come up with is that this somehow equates to the number of ticks since the beginning of year 1601 UTC.

My desired end result is to have a function I can call and have it take the long string and return a recognizeable date.

Any assistance would be greatly appreciated.
 
I finally figured this out. Took me about 6 hours so I am sharing the solution so others will be able to use it.

Code:
hDate = "01c9c5ce4b48e5fd"
'The above should resolve to 4/25/2009

WScript.Echo HexDateToDate(hDate)

Function HexDateToDate(hDate)
	highPart = CDbl("&h" & Left(hDate,8))
	lowPart = CDbl("&h" & Right(hDate,8))
	intInstalledOn = highPart * (2^32) + lowPart 
	intInstalledOn = intInstalledOn / (60 * 10000000)
	intInstalledOn = intInstalledOn / 1440
	HexDateToDate = intInstalledOn + #1/1/1601#
End Function

Breaking down the code, the secret was to break apart the number into two parts and then convert those numbers from Hex to decimal.

We then use the properties of the IADsLargeInteger to work with this. I won't even pretend to comprehend the math behind this, but you need to raise the first half to 2 to the 32nd power. Then add that to the second part. This will yield a rather large decimal number that represents the number of nanoseconds since Jan 1, 1601 and the event that logged our time.

Once we have nonoseconds, the rest of the code is used to convert to years, months, days, hours, minutes & seconds.
We then add that time to Jan 1, 1601 to get the time we had recorded.

It is all so simple once you get that concept, however finding the solution was rather difficult since I wasn't familiar with the IADsLargeInteger.


I hope you find this post helpful.

Regards,

Mark

Check out my scripting solutions at
Work SMARTER not HARDER. The Spider's Parlor's Admin Script Pack is a collection of Administrative scripts designed to make IT Administration easier! Save time, get more work done, get the Admin Script Pack.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top