PDA

Ver la Versión Completa : Calcular tiempo transcurrido


dtomeysoto
04-09-2013, 20:21:24
Hola a todos, he desarrollando una aplicación en Delphi XE que me registra la hora en que se encienden y se apagan los PC y Servidores en la red. También se registran la hora y la fecha en que los usuarios inician sesión y la hora en la que se finaliza. Los datos los guardo en una tabla de una base de datos MS SQL 2005.

Hasta aquí todo bien, pero a la hora de mostrar los resultados almacenados desde otra aplicación me gustaría mostrar además de la hora de inicio de sesión y la de cierre (en el caso de la información registrada para los usuarios) y la de encendido y apagado (en el caso de los PC y Servidores) mostrar además la duración de la sesión, es decir cuanto tiempo estuvo abierta la sesión (horas, minutos, segundos y milisegundos). Teniendo en cuenta que una sesión puede estar abierta más de 24 horas lo que equivaldría a mostrar también los días.

Me gustaría si alguno de ustedes ya tiene hecho algo similar que me mostrara como hacerlo, porque he intentado restar los dos campos que son de tipo TDateTime y luego con DecodeDateTime pero no consigo lo que quiero.

Gracias.

ecfisa
04-09-2013, 21:07:57
Hola dtomeysoto.

Para mostrar los datos de inicio y fin de sesión y el tiempo transcurrido entre ellos, podrías hacer:

(*
Para el ejemplo uso variables, y los eventos OnClick de dos Buttons,
en tu caso los tiempos de incio y cierre se obtendrían de los campos
de la tabla donde almacenas esos datos.
*)
uses DateUtils;

war
InicioSesion,
FinSesion : TDateTime;

procedure TForm1.btnInicioClick(Sender: TObject);
begin
InicioSesion := Now;
end;

procedure TForm1.btnFinClick(Sender: TObject);
begin
FinSesion := Now;

Memo1.Font.Name := 'Courier';
with Memo1.Lines do
begin
Clear;
Add('Inicio sesión: ' + DateTimeToStr(InicioSesion));
Add('Fin sesión : ' + DateTimeToStr(FinSesion));
Add('');
Add('Tiempo transcurrido');
Add('-------------------');
Add('Dias : ' + IntToStr(DaysBetween(FinSesion, InicioSesion)));
Add('Horas : ' + IntToStr(HoursBetween(FinSesion, InicioSesion)));
Add('Minutos : ' + IntToStr(MinutesBetween(FinSesion, InicioSesion)));
Add('Segundos : ' + IntToStr(SecondsBetween(FinSesion, InicioSesion)));
Add('Miliseg. : ' + IntToStr(MilliSecondsBetween(FinSesion, InicioSesion)));
end;
end;


Saludos :)

dtomeysoto
04-09-2013, 22:09:28
Ya había probado algo como lo que me recomiendas pero no estoy conforme con el resultado que obtengo, por ejemplo para los siguientes valores:

sesion_ini = 04/09/2013 07:04:11 am
sesion_fin = 04/09/2013 11:01:06 am

Obtengo:

Duración = D:0, H:3, M:236, S:14215

No quiero que los minutos se pasen de 60 al igual que los segundos.

Casimiro Notevi
04-09-2013, 23:11:34
¿Has probado en hacer una búsqueda (http://www.clubdelphi.com/foros/search.php)? es un tema muy repetido y seguro que encuentras la solución.

nlsgarcia
05-09-2013, 01:55:40
dtomeysoto,


...me gustaría mostrar...la duración de la sesión, es decir cuanto tiempo estuvo abierta la sesión (horas, minutos, segundos y milisegundos)...


Revisa este código basado en la solución sugerida en el Msg #2:

unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, DateUtils;

type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Memo1: TMemo;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
InicioSesion, FinSesion : TDateTime;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
InicioSesion := Now;
end;

procedure TForm1.Button2Click(Sender: TObject);
var
YYI, MMI, DDI, HHI, NNI, SSI, MSI : Word;
YYF, MMF, DDF, HHF, NNF, SSF, MSF : Word;
YYT, MMT, DDT, HHT, NNT, SST, MST : Word;
FinalSesion : String;

begin

FinSesion := Now;

ShortDateFormat := 'dd/mm/yyyy';
ShortTimeFormat := 'hh:nn:ss:zzz';
DateSeparator := '/';
TimeSeparator := ':';

DecodeDateTime(InicioSesion,YYI,MMI,DDI,HHI,NNI,SSI,MSI);
DecodeDateTime(FinSesion,YYF,MMF,DDF,HHF,NNF,SSF,MSF);

YYT := YYF - YYI;

if MMF >= MMI then
begin
MMT := MMF - MMI
end
else
begin
YYF := YYF - 1;
MMF := MMF + 12 - MMI;
end;

if DDF >= DDI then
begin
DDT := DDF - DDI
end
else
begin
MMT := MMT - 1;
DDT := DDF + MonthDays - DDI;
end;

if MMT < 0 then
begin
YYT := YYT - 1;
MMT := 12 + MMT;
end;

if HHF >= HHI then
begin
HHT := HHF - HHI;
end
else
begin
DDT := DDT - 1;
HHT := HHF + 24 - HHI;
end;

if NNF >= NNI then
begin
NNT := NNF - NNI;
end
else
begin
HHT := HHT - 1;
NNT := NNF + 60 - NNI;
end;

if HHT < 0 then
begin
DDT := DDT - 1;
HHT := HHT + 24
end;

if SSF >= SSI then
begin
SST := SSF - SSI;
end
else
begin
NNT := NNT - 1;
SST := SSF + 60 - SSI;
end;

if MSF >= MSI then
begin
MST := MSF - MSI;
end
else
begin
SST := SST - 1;
MST := MSF + 1000 - MSI;
end;

if SST < 0 then
begin
NNT := NNT - 1;
SST := SST + 60;
end;

Memo1.Font.Name := 'Courier';
with Memo1.Lines do
begin
Clear;
Add('Inicio sesión : ' + DateTimeToStr(InicioSesion));
Add('Fin sesión : ' + DateTimeToStr(FinSesion));
Add('');
Add('Tiempo transcurrido');
Add('-------------------');
Add('Años : ' + IntToStr(YYT));
Add('Meses : ' + IntToStr(MMT));
Add('Dias : ' + IntToStr(DDT));
Add('Horas : ' + IntToStr(HHT));
Add('Minutos : ' + IntToStr(NNT));
Add('Segundos : ' + IntToStr(SST));
Add('Miliseg. : ' + IntToStr(MST));
end;

end;

end.

El código anterior [I]permite mostrar en un componente TMemo el lapso de tiempo transcurridos entre dos variables TDateTime.

Nota: Variable TDateTime Inicial deber ser menor o igual a Variable TDateTime Final.

Espero sea útil :)

Nelson.

dtomeysoto
05-09-2013, 20:55:02
Hola Nelson, gracias por la colaboración. Lo ajusté a lo que necesito y parece trabajar bien.
Solo una cosa, cuando compilo me da 4 advertencias,

En estas líneas me dice: Comparison always evaluates to False

if MMT < 0 then
if HHT < 0 then
if SST < 0 then

Y esta línea: Variable 'MMT' might not have been initialized

if MMT < 0 then

Todo sobre Delphi XE.

nlsgarcia
05-09-2013, 23:10:46
dtomeysoto,


...ajusté a lo que necesito y parece trabajar bien...cuando compilo me da 4 advertencias...sobre Delphi XE...


El código del Msg #5 fue desarrollado en Delphi 7 y en dicho ambiente se generan las mismas advertencias del compilador que en Delphi XE, sin afectar el funcionamiento del código.

Espero sea útil :)

Nelson.

dtomeysoto
06-09-2013, 18:24:47
dtomeysoto,



El código del Msg #5 fue desarrollado en Delphi 7 y en dicho ambiente se generan las mismas advertencias del compilador que en Delphi XE, sin afectar el funcionamiento del código.

Espero sea útil :)

Nelson.

Mas que útil, me ha venido como una joya.

josydasalone
15-09-2016, 22:36:00
Ya había probado algo como lo que me recomiendas pero no estoy conforme con el resultado que obtengo, por ejemplo para los siguientes valores:

sesion_ini = 04/09/2013 07:04:11 am
sesion_fin = 04/09/2013 11:01:06 am

Obtengo:

Duración = D:0, H:3, M:236, S:14215

No quiero que los minutos se pasen de 60 al igual que los segundos.

Creo q lo mejor seria sacar el mod en los minutos y segundos.
Osea M := M mod 60;
S := S mod 60;

Casimiro Notevi
15-09-2016, 22:56:57
Bienvenido a clubdelphi, como siempre aconsejamos a los nuevos, no olvides leer nuestra guía de estilo (http://www.clubdelphi.com/foros/guiaestilo.php), gracias por tu colaboración :)


Y recuerda poner los tags al código fuente, ejemplo:

http://www.clubdelphi.com/images/UtilizarTAGs.png

Gracias :)

josydasalone
16-09-2016, 00:19:19
Ya había probado algo como lo que me recomiendas pero no estoy conforme con el resultado que obtengo, por ejemplo para los siguientes valores:

sesion_ini = 04/09/2013 07:04:11 am
sesion_fin = 04/09/2013 11:01:06 am

Obtengo:

Duración = D:0, H:3, M:236, S:14215

No quiero que los minutos se pasen de 60 al igual que los segundos.

Creo q lo mejor seria sacar el mod en los minutos y segundos.
Osea
M := M mod 60;
S := S mod 60;
Asi solo te daran resultados debajo de 60.