WMI Time Bewilderment

Unless you're a seasoned programmer, managing time in Windows Management Instrumentation (WMI) is a complicated task. Besides minor problems that general time variations and Daylight Savings Time cause, dissimilar file systems store and present time in different formats. For example, NTFS stores time in Greenwich Mean Time (GMT) format, whereas FAT stores times in a local time format. The Distributed Management Task Force's (DMTF's) Common Information Model (CIM) standard—which WMI uses for its dates and times—further complicates matters by using yet another time format—Universal Time Coordinate (UTC). Chances are, you're bewildered by all these time-format variances. To get past the confusion, you need to understand how WMI handles and represents time.

Datetime Format
All time representation in WMI is based on the CIM datetime format. The CIM datetime data type is a fixed-length VT_BSTR string that represents either a specific date and time or an interval and uses either the yyyymmddHHMMSS.mmmmmmsUUU or yyyy-mm-dd HH:MM:SS:mmm format. Table 1 describes each format's variables.

Following the International Organization for Standardization (ISO) date notation (i.e., YYYYMMDD) and military time (i.e., a 24-hour clock in which, for example, 1600 hours represents 4:00 p.m.), WMI requires all fields in the time format to be of indicated length. To complete the required character length (i.e., 25 or 23 characters), you must pad the fields with leading zeros (e.g., use 04 to represent April).

You can use asterisks, in addition to zeros, to indicate unspecified fields. You can also use asterisks as wildcards. For example, using asterisks in the mm field would indicate that the event date can be a particular day in any month of a specific year. While generating reports, to specify the 16th day of any month in 2002, you would use 2002**16130100.000000-000. You can use asterisks to fill any unused fields. However, remember that you must always populate the entire field with asterisks. A legal use of asterisks is, for example, ******1613**00.000000-000, and an illegal use of asterisks is, for example, ******1613*100.000000-000. (The asterisk between the 3 and 1 is illegal because it doesn't populate the entire Seconds field.) Use of asterisks in the Where clause is also illegal. For example, the statement

Time Interval Format
In addition to a date and time, datetime values can contain an interval, which can help you calculate elapsed time. Like the datetime format, the interval format is of a fixed character length: ddddddddHHMMSS.mmmmm:000. (Table 2 describes this format's variables.) For example, 00000010101010.000000:000 shows a time interval of 10 days, 10 hours, 10 minutes, and 10 seconds. Unlike the datetime format, the final four characters of an interval are always a colon and three zeros, and you can't use asterisks in unspecified fields.

Also, you must set the value of the standard WMI qualifier SubType to interval for all properties (e.g., the StartTime property of Win32_ScheduledJob) that store values of the CIM datetime type. To learn more about qualifiers, refer to the WMI software development kit (SDK) at http://msdn.microsoft.com/downloads/default.asp?url=/code/sample.asp?url=/msdn-files/027/001/566/msdncompositedoc.xml.

Converting UTC to Local Time
WMI stores and presents time in the UTC format, which is essentially equivalent to the GMT format. Measured on the Prime Meridian (i.e., 0 degrees longitude) in Greenwich, England, UTC is also referred to as Zulu (Z) Time. In the real world, obviously, we use the local time and would prefer that WMI use the same. To convert UTC time to local time, you can use the positive or the negative offset—indicated by a plus (+) or minus (-) sign—in the s field and add it to the UTC time. For example, UTC - 300 in WMI represents Eastern time, which is 5 hours earlier than UTC time.

To simplify your life, you can wrap the conversion code into a function such as that which Listing 1 shows. (At callout A in Listing 1, the VBScript dateAdd function adds the offset minutes to the UTC time.) You can then reuse the function in your other scripts. For example, the script in Listing 2 uses the cUTC2Lt function that appears in Listing 1 to display the system's most recent boot time.

The difference between the local time and UTC time is dependent on the time zone and Daylight Savings Time. To obtain local time-zone settings and to determine whether Daylight Savings Time is in effect, you can use WMI's CurrentTimeZone and DayLightinEffect properties in the Win32_Computersystem class, as Listing 3 shows. WMI also provides a Win32_TimeZone class, which you can use to obtain time-zone properties (e.g., the time-zone name).

Wild Times
Differing time systems, varied time zones, Daylight Savings Time, incompatible datetime types, and diverse file systems representing time in different formats can all complicate the calculation of time in WMI. Fortunately, time management is simplified with the introduction of a new WMI object, SwbemDateTime, available with Windows XP. With the SwbemDateTime object, you'll no longer need to write lengthy and complicated code to keep track of the time. To learn more about the SwbemDateTime object, refer to http://msdn.microsoft.com or download the WMI SDK.

To see the list of all US states, their respective time differences, and the Daylight Savings Time chart, visit http://greenwichmeantime.com/local/usa/index.htm. For a list of military and civil time zones, visit http://greenwichmeantime.com/info/timezone.htm.