Delphi - Restando horas

 
Vista:

Restando horas

Publicado por Rodolfo (12 intervenciones) el 02/06/2003 21:57:23
Tengo un problema.

Hace un tiempo publicaron en la lista una forma de poder hacer sumas y restas con las horas:

h1:=StrToDateTime(Table1.FieldByName('hora_i').AsString); { hora de inicio }
h2:=StrToDateTime(Table1.FieldByName('hora_f').AsString); { hora final }
h3:=h2-h1; { hora de Salida menos hora de Ingreso } { horas trabajadas }
horas:=Trunc(h3*24);
minutos:=Round(h3*1440)-horas*60;
tiempo:=Format('%.2d:%2.2d',[horas,minutos]);

En los 6 registros que uso como prueba, me sale bien en 5 de ellos, pero en uno siempre me da el siguiente error:
HORA_I: 08:30
HORA_F: 17:30
HORA_TRAB: 08:60

Lo que no entiendo es porque me sale 8 horas 60 minutos, en vez de salirme simplemente 09:00

Que puedo estar haciendo mal?

Los calculos son registrados en una tabla. La tabla es de DBase, asi que no tengo campo tipo fecha, lo estoy poniendo en un campo tipo string.

Muchas Gracias.

Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:Restando horas

Publicado por Ernesto De Spirito (706 intervenciones) el 03/06/2003 15:07:08
Se trata de un típico caso de errores de representación y aritmética de punto flotante. Verás, de por sí, las horas 8:30 y 17:30 no tienen una representación exacta en formato binario de punto flotante (ni siquiera lo tienen en decimal, ya que se necesitan infinitos dígitos), por lo que los valores de h1 y h2 estarían viciados por un error de representación, pero además podrían introducirse errores de conversión (redondeo de los resultados de las operaciones aritméticas necesarias para convertir de string a TDateTime, o Double, ya que son lo mismo). Ese pequeño error casi imperceptible hace que por ejemplo el resultado de la direfencia de ambas fechas no sea exactamente 9:00 (que dicho sea de paso tampoco tendría representación exacta). Para que me entiendas, h3 podría valer algo como 9:00:00.00000000001, que no te daría problemas con las fórmulas que empleas, pero en el caso que planteas, el valor de h3 es algo como 8:59:59.99999999999, y con tus fórmulas obtendrás 8 horas y 60 minutos.

El problema se podría resolver así:

minutos := Round(h3 * 1440);
horas := minutos div 60;
minutos := minutos mod 60;
tiempo := Format('%.2d:%2.2d', [horas, minutos]);

O así:

DecodeTime(h3, horas, minutos, segundos, milsegundos);
tiempo := Format('%.2d:%2.2d', [horas, minutos]);

O también podrías asignar la variable "tiempo" directamente, convirtiendo la hora de h3 en string:

tiempo := FormatDateTime('hh:mm', h3);

Espero que te sirva.

Ernesto De Spirito
http://www.latiumsoftware.com/es/index.php
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Restando horas

Publicado por BigLuis (463 intervenciones) el 04/06/2003 17:36:23
Yo en una ocasion tuve la necesidad de restar dias y horas para un programa de calculo de dietas y tiré por el camino del medio y me fue bien. Te explico.Los campos eran DateTime (a mi me gustan mas por compatibilidad) e hice lo siguiente:
Declaré estas variables:
Var
DiaSalida,DiaLlegada:TDate;
HoraSalida,HoraLlegada:TTime;
Horasalida2,Horallegada2:String;
Hora1,Hora2,Minuto1,Minuto2,HoraTotal1,Horatotal2:string;
A,B:Integer;
iHoraSalida,iHoraLlegada:Integer;
begin
Como la variable es TDate solo recoge la fecha
DiaSalida:=Contenido del Campo.AsDatetime;
Como la variabel es TTime solo recoge la hora
HoraSalida:=Contenido del Campo.AsDatetime;
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:Restando horas SIGUE

Publicado por BigLuis (463 intervenciones) el 04/06/2003 17:37:06
.......
HoraSalida2:=Timetostr(HoraSalida);
Horallegada2:=TimetoStr(HoraLlegada);

A:=pos(':',Horasalida2);
B:=pos(':',Horallegada2);

hora1:=copy(horasalida2,1,a-1);
hora2:=copy(horallegada2,1,b-1);

Minuto1:=copy(horasalida2,a+1,2);
Minuto2:=copy(horallegada2,b+1,2);

//Concatena el string de la hora de salida
Horatotal1:=Hora1+Minuto1;
//Conversion del String de la hora de salida concatenada a Integer
iHoraSalida:=strtoint(Horatotal1); //La definitiva con la que se trabaja
//Concatena el string de la hora de llegada
Horatotal2:=Hora2+Minuto2;
//Conversion del String de la hora de llegada concatenada a Integer
iHoraLlegada:=strtoint(Horatotal2);//La definitiva con la que se trabaja
Si restas HoraLlegada(Entero)-iHorasalida(Entero)= un Entrero.
Me has entendido?
Suerte
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar