0

I am having a problem converting a string to a date and time. I know I need to truncate the string down, but I can't seem to find any information on how to do so. I figured someone else will have this question as well, so I thought I would put it here for research purposes. Here is the code:

uses
  SysUtils,
  ActiveX,
  ComObj,
  Variants;


procedure  GetLogEvents;
const
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
  EventDate     : TDateTime;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
  FWbemObjectSet:= FWMIService.ExecQuery(
                   'SELECT SourceName,TimeGenerated,ComputerName,EventCode,Message,RecordNumber ' +
                   ' FROM Win32_NTLogEvent ' +
                   'WHERE Logfile="Application"','WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  while oEnum.Next(1, FWbemObject, iValue) = 0 do
  begin
  if not VarIsNull(FWbemObject.SourceName)
             then Writeln(Format('SourceName          %s',[String(FWbemObject.SourceName)]));

    if not VarIsNull(FWbemObject.TimeGenerated)
             then Writeln(StrToDateTime(FWbemObject.TimeGenerated));

And I get the error:

EConvertError:'20140307135950.000000-000' is not a valid date and time.

Can anyone advise me on how to remedy this, please?

1 Answers1

1

The proper way to handle the WMI Datetime (Common Information Model datetime values) is using the WbemScripting.SWbemDateTime object.

Try this sample

uses
  SysUtils,
  ActiveX,
  ComObj,
  Variants;

function  WmiDateToTDatetime(vDate : OleVariant) : TDateTime;
var
  FWbemDateObj  : OleVariant;
begin;
  FWbemDateObj  := CreateOleObject('WbemScripting.SWbemDateTime');
  FWbemDateObj.Value:=vDate;
  Result:=FWbemDateObj.GetVarDate;
end;

procedure  GetLogEvents;
const
  wbemFlagForwardOnly = $00000020;
var
  FSWbemLocator : OLEVariant;
  FWMIService   : OLEVariant;
  FWbemObjectSet: OLEVariant;
  FWbemObject   : OLEVariant;
  oEnum         : IEnumvariant;
  iValue        : LongWord;
  EventDate     : TDateTime;
begin;
  FSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator');
  FWMIService   := FSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', '');
  FWbemObjectSet:= FWMIService.ExecQuery(
                   'SELECT SourceName,TimeGenerated,ComputerName,EventCode,Message,RecordNumber ' +
                   ' FROM Win32_NTLogEvent ' +
                   'WHERE Logfile="Application"','WQL',wbemFlagForwardOnly);
  oEnum         := IUnknown(FWbemObjectSet._NewEnum) as IEnumVariant;
  while oEnum.Next(1, FWbemObject, iValue) = 0 do
  begin
  if not VarIsNull(FWbemObject.SourceName)
             then Writeln(Format('SourceName          %s',[String(FWbemObject.SourceName)]));

    if not VarIsNull(FWbemObject.TimeGenerated)
             then Writeln(DateTimeToStr(WmiDateToTDatetime(FWbemObject.TimeGenerated)));
    FWbemObject:=Unassigned;
  end;
end;


begin
 try
    CoInitialize(nil);
    try
      GetLogEvents;
    finally
      CoUninitialize;
    end;
 except
    on E:EOleException do
        Writeln(Format('EOleException %s %x', [E.Message,E.ErrorCode]));
    on E:Exception do
        Writeln(E.Classname, ':', E.Message);
 end;
 Writeln('Press Enter to exit');
 Readln;
end.
RRUZ
  • 134,889
  • 20
  • 356
  • 483