PDA

Ver la Versión Completa : Buscar archivos con horario de verano activado


ehdez82
16-05-2012, 22:42:01
Estoy realizando una aplicación con Delphi 2010 que entre sus funciones busca en una carpeta los archivos modificados después de una fecha y hora. Estoy utilizando para esto el componente JvSearchFiles del paquete Jedi.
El problema es que cuando el sistema aplica automáticamente el horario de verano la hora de modificación de los archivos se adelanta una hora afectando la comparación.

He separado un pequeño ejemplo para explicar el problema, aqui está el código:

procedure TForm1.Button1Click(Sender: TObject);
var
D: TDateTime;
begin
with JvSearchFiles do
begin
RootDirectory := ExtractFilePath(Application.ExeName) + '\Logs';
D := EncodeDateTime(2011, 12, 5, 21, 30, 0, 0);
MFiles.Lines.Add('Searching files modified after ' + DateTimeToStr(D));
FileParams.SearchTypes := FileParams.SearchTypes + [stLastChangeAfter];
FileParams.LastChangeAfter := D;
Search;
end;
end;

procedure TForm1.JvSearchFilesFindFile(Sender: TObject; const AName: string);
var
S: String;
begin
with JvSearchFiles do
begin
S := S + AName;
S := S + ' Modified Time: ' + DateTimeToStr
(FileTimeToDateTime(FindData.ftLastWriteTime));
S := S + ' Creation Time: ' + DateTimeToStr
(FileTimeToDateTime(FindData.ftCreationTime));
end;
MFiles.Lines.Add(S);
end;

Lo que me muestra en el memo es:

Searching files modified after 05/12/2011 02:00:00 PM
Log (1).log Modified Time: 05/12/2011 02:54:03 PM Creation Time: 12/05/2012 02:13:46 AM
Log (2).log Modified Time: 05/12/2011 08:57:16 PM Creation Time: 15/05/2012 01:32:04 PM
Log (3).log Modified Time: 05/12/2011 10:05:00 PM Creation Time: 15/05/2012 01:32:05 PM
Log (4).log Modified Time: 05/12/2011 10:59:27 PM Creation Time: 15/05/2012 01:32:05 PM

Lo que dice el explorador de windows 7 es:

Log (1).log Modified Time: 05/12/2011 01:54:03 PM Creation Time: 12/05/2012 02:13:46 AM
Log (2).log Modified Time: 05/12/2011 07:57:16 PM Creation Time: 15/05/2012 01:32:04 PM
Log (3).log Modified Time: 05/12/2011 09:05:00 PM Creation Time: 15/05/2012 01:32:05 PM
Log (4).log Modified Time: 05/12/2011 09:59:27 PM Creation Time: 15/05/2012 01:32:05 PM


El componente JvSearchFiles utiliza principalmente estos dos procedimientos:

procedure TJvSearchParams.SetLastChangeAfter(const Value: TDateTime);
var
DosFileTime: Longint;
LocalFileTime: TFileTime;
begin
{ Value must be >= 1-1-1980 }
DosFileTime := DateTimeToDosDateTime(Value);
if not Windows.DosDateTimeToFileTime(LongRec(DosFileTime).Hi,
LongRec(DosFileTime).Lo, LocalFileTime) or
not Windows.LocalFileTimeToFileTime(LocalFileTime, FLastChangeAfterFT) then
RaiseLastOSError;

FLastChangeAfter := Value;
end;

function TJvSearchParams.Check(const AFindData: TWin32FindData): Boolean;
begin
...

if stLastChangeAfter in FSearchTypes then
if CompareFileTime(ftLastWriteTime, FLastChangeAfterFT) < 0 then
Exit;
...
end;

En el procedimiento SetLastChangeAfter se utilizan las funciones DateTimeToDosDateTime, DosDateTimeToFileTime y LocalFileTimeToFileTime los cuales por lo visto no logran que se le aplique a la fecha el horario de verano.

Cuando desactivo aplicar automáticamente el horario de verano todo funciona perfectamente y coincide la hora de modificación que muestra la aplicación con la del explorador de windows 7. Sin embargo no creo que la aplicación deba forzar al usuario a cambiar su configuración personal. Entonces lo que necesito es alguna forma de convertir mi fecha a la configuración local incluyendo el horario de verano.

Gracias de antemano.
Saludos.

Casimiro Notevi
17-05-2012, 00:05:40
Con la hora UTC creo que solventas el problema:

procedure TMainForm.TimeZoneClick(Sender: TObject);
var
MyTime : TDateTime;
UTC: TSystemTime;
begin
MyTime := Time;
GetSystemTime(UTC);
with Memo1.Lines do
begin
Add('PC time: '+TimeToStr(MyTime));
Add('UTC: '+IntToStr(UTC.wHour)+':'+IntToStr(UTC.wMinute)+':'+IntToStr(UTC.wSecond));
Add('Date: '+IntToStr(UTC.wYear)+':'+IntToStr(UTC.wMonth)+':'+IntToStr(UTC.wDay));
end;
end;


Mira aquí. (http://www.tek-tips.com/viewthread.cfm?qid=1486209)

Casimiro Notevi
17-05-2012, 00:15:27
También puede ser GMT:
function GMTToLocalTime(GMTTime: TDateTime): TDateTime;
var
GMTST: Windows.TSystemTime;
LocalST: Windows.TSystemTime;
begin
SysUtils.DateTimeToSystemTime(GMTTime, GMTST);
SysUtils.Win32Check(Windows.SystemTimeToTzSpecificLocalTime(nil, GMTST, LocalST));
Result := SysUtils.SystemTimeToDateTime(LocalST);
end;


Aquí. (http://alldelphi.com/2008/04/03/gmt-time-to-local-time/)