Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VisualC++

How to Decode the CIM_DATETIME Format Employed in WMI Queries Using C++

4.78/5 (5 votes)
7 Apr 2014CPOL1 min read 15.3K   157  
A robust approach to decoding CIM_DATETIME for C++ programmers

Introduction

This will show how a C++ programmer may convert a time value returned from a WMI query into a format she/he will be more familiar with.

Background

WMI queries use a date and time format called CIM_DATETIME (Common Information Model). In the MSDN example Getting WMI Data from the local computer, the WIN32_OperatingSystem class contains this property:

C++
datetime LastBootUpTime;

This is a CIM_DATETIME format string. It is also known as DMTF (Distributed Management Task Force) datetime format. Date and time are encoded as a string containing UTC time with an appended offset in minutes for the current locale. This is the offset of local time from UTC time. Encoded time values have a one microsecond resolution.
Scripting services are provided with SWbemDateTime() to parse this format. C# programmers may employ ManagementDateTimeConverter.ToDateTime:

C#
// Convert DMTF datetime to System.DateTime
string dmtfDate = "20140408141835.999999+480";
DateTime dt = ManagementDateTimeConverter.ToDateTime(dmtfDate);

For C++ programmers in an unmanaged environment, they can if they wish parse the string directly. This is a perfectly acceptable approach. If in the future the encoded format is altered, then dependent code would be affected. Fortunately, SWbemDateTime() also exposes a COM interface which can be instantiated in this way:

C++
ISWbemDateTime *pSWbemDateTime = NULL;
HRESULT hr = CoCreateInstance(CLSID_SWbemDateTime, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pSWbemDateTime));

Using the Code

SWbemDateTime() can convert CIM_DATETIME values to and from FILETIME and VT_DATE values. VT_DATE is a lower precision format (500 millisecond) so this tip will concentrate on the FILETIME format which is probably of more interest to C++ programmers. The function CIMDateTimetoFiletime() below may be used to convert a CIM_DATETIME to a FILETIME in either local time or UTC time.

C++
// Convert CIM_DATETIME to FILETIME either as UTC or local time.
// Input:  CIM_DATETIME as LPCWSTR
// Input: bool blocaltime: true compute local time else compute UTC time
// Output: FILETIME pointer
// Return: true for success
bool CIMDateTimetoFiletime(__in LPCWSTR cimdatetime, __out LPFILETIME filetime,
 __in const bool blocaltime = true)
{
 bool bSuccess = false;
 // Get a SWbemDateTime object.
 ISWbemDateTime *pSWbemDateTime = NULL;
 HRESULT hr = CoCreateInstance(CLSID_SWbemDateTime, NULL, CLSCTX_INPROC_SERVER,
  IID_PPV_ARGS(&pSWbemDateTime));
 if (SUCCEEDED(hr))
 {
  BSTR timebstr = SysAllocString(cimdatetime);
  if (timebstr)
  {
   // Set time value.
   hr = pSWbemDateTime->put_Value(timebstr);
   if (SUCCEEDED(hr))
   {
    BSTR bstrFileTime;
    // Get a FILETIME.
    hr = pSWbemDateTime->GetFileTime(blocaltime?VARIANT_TRUE:VARIANT_FALSE,
     &bstrFileTime);
    if (SUCCEEDED(hr))
    {
     ULARGE_INTEGER tempFT;
     // 64-bit value representing the number of 100-nanosecond intervals 
     // since January 1, 1601 (UTC).
     tempFT.QuadPart = _wtoi64(bstrFileTime); 
     // FILETIME is a structure of two 32-bit integers.
     filetime->dwLowDateTime = tempFT.LowPart;
     filetime->dwHighDateTime = tempFT.HighPart;
     bSuccess = true;
     SysFreeString(bstrFileTime);
    }
   }
   SysFreeString(timebstr);
  }
  pSWbemDateTime->Release();
 }
 return bSuccess;
}

The project supplied uses the example from MSDN to extract the LastBootTime and convert to FILETIME as both UTC and local times.

History

  • v1.00 07-04-2014

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)