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:
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
:
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:
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.
bool CIMDateTimetoFiletime(__in LPCWSTR cimdatetime, __out LPFILETIME filetime,
__in const bool blocaltime = true)
{
bool bSuccess = false;
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)
{
hr = pSWbemDateTime->put_Value(timebstr);
if (SUCCEEDED(hr))
{
BSTR bstrFileTime;
hr = pSWbemDateTime->GetFileTime(blocaltime?VARIANT_TRUE:VARIANT_FALSE,
&bstrFileTime);
if (SUCCEEDED(hr))
{
ULARGE_INTEGER tempFT;
tempFT.QuadPart = _wtoi64(bstrFileTime);
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