Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Extraño resultado de la función "DateUtils.MinutesBetween" (https://www.clubdelphi.com/foros/showthread.php?t=95697)

dec 22-05-2022 18:37:05

Extraño resultado de la función "DateUtils.MinutesBetween"
 
Hola a todos,

A ver si alguien sabría decirme a qué se debe el siguiente extraño resultado utilizando la función de la unidad DateUtils "MinutesBetween":

Código Delphi [-]
var
  DateTimeA, DateTimeB: TDateTime;
begin
  DateTimeA := EncodeDateTime(2022, 1, 1, 10, 0, 0, 0);
  DateTimeB := EncodeDateTime(2022, 1, 1, 11, 0, 0, 0);

  // Muestra 60, lo que en principio parece el resultado esperado
  ShowMessage(IntToStr(MinutesBetween(DateTimeA, DateTimeB)));
end;
...
Código Delphi [-]
var
  DateTimeA, DateTimeB: TDateTime;
begin
  DateTimeA := EncodeDateTime(2022, 1, 1, 9, 0, 0, 0);
  DateTimeB := EncodeDateTime(2022, 1, 1, 10, 0, 0, 0);

  // Muestra 59, lo que en principio NO PARECE el resultado esperado
  ShowMessage(IntToStr(MinutesBetween(DateTimeA, DateTimeB)));
end;

P.D. El problema parece estar en Delphi 2007... puesto que en Delphi 10.4 en ambos casos el resultado es el esperado: 60 minutos... lo que me lleva a pensar en algún problema en la unidad "DateUtils" de Delphi 2007... porque además el problema ocurre también, por ejemplo, con la función "SecondsBetween"... y además con varias "horas"... es decir, no sólo de las 9 a las 10, pero, también de las 0 a la 1, por ejemplo.

Casimiro Notevi 23-05-2022 10:03:22

Puede que en alguno de los cálculos use un double y haga un "trunc" para quitar decimales y ahí pierda el valor correcto.

dec 23-05-2022 10:12:52

Hola a todos,

Cita:

Empezado por Casimiro Notevi (Mensaje 546963)
Puede que en alguno de los cálculos use un double y haga un "trunc" para quitar decimales y ahí pierda el valor correcto.

Sí que se hace algún "trunc", sí... Lo raro sería porqué el resultado es el esperado con algunas horas y con otras no lo es. Por lo demás, parece que se trata de algo que, al menos en Delphi 10.4, parece "solucionado". Y entrecomillo "solucionado" porque no estoy seguro de que se trate de un error, puesto que desde luego es totalmente consistente: el resultado es siempre el mismo, aunque, no es el esperado. En fin... acaso se pueda lidiar con dicho problema si no queda más remedio. ¡Gracias por tu respuesta Casimiro! :)

Casimiro Notevi 23-05-2022 10:20:45

¿Y al revés también sucede?
Cita:

ShowMessage(IntToStr(MinutesBetween(DateTimeB, DateTimeA)));
¿Y usar "otra cosa" que no sea IntToStr? ¿o ya viene con el valor incorrecto antes de eso?

dec 23-05-2022 10:55:06

Hola a todos,

Cambiando los argumentos el resultado es el mismo, y, por otro lado, usar "otra cosa" que no sea "IntToStr"... no sé muy bien qué posible alternativa habría... acabo de probar con "FloatToStr" y el resultado sigue siendo el mismo también...

P.D. Yo diría que el resultado viene ya directamente así de "MinutesBetween"... y curiosamente también ocurre lo mismo con "SecondsBetween", por ejemplo.

Casimiro Notevi 23-05-2022 17:05:02

Copiado de la delphi comunity:
mDateTimeToMillisecons es DateTimeToMillisecons
mMinutesBetween es MinutesBetween

Código Delphi [-]
function mDateTimeToMilliseconds(const ADateTime: TDateTime): Int64;
var
  LTimeStamp: TTimeStamp;
begin
  LTimeStamp := DateTimeToTimeStamp(ADateTime);
  Result := LTimeStamp.Date;
  Result := (Result * MSecsPerDay) + LTimeStamp.Time;
end;

function mMinutesBetween(const ANow, AThen: TDateTime): Int64;
begin
  Result := Abs(mDateTimeToMilliseconds(ANow) - mDateTimeToMilliseconds(AThen))
    div (MSecsPerSec * SecsPerMin);
end;

procedure TForm24.Button1Click(Sender: TObject);
var
  dtA, dtB :TDateTime;
  ano, mes, dia, hor1,hor2, min, seg, mil :int64;
begin
  ano:=2022;
  mes:=1;
  dia:=1;
  hor1:=10;
  hor2:=11;
  min:=0;
  seg:=0;
  mil:=0;

  dtA := EncodeDateTime(ano, mes, dia, hor1, min, seg, mil);
  dtB := EncodeDateTime(ano, mes, dia, hor2, min, seg, mil);
  ShowMessage(IntToStr(mMinutesBetween(dtB, dtA)));

  hor1:=9;
  hor2:=10;

  dtA := EncodeDateTime(ano, mes, dia, hor1, min, seg, mil);
  dtB := EncodeDateTime(ano, mes, dia, hor2, min, seg, mil);;
  ShowMessage(IntToStr(MminutesBetween(dtB, dtA)));
end;

dec 23-05-2022 19:00:26

Hola a todos,

Gracias Casimiro. En efecto, es exactamente la misma implementación que en la unidad DateUtils de Delphi 10.4... creo que al final algo así habrá que usarse, puesto que la implementación de la unidad DateUtils en Delphi 2007 parece contener "algo" que causa el "problema".


La franja horaria es GMT +2. Ahora son las 14:56:13.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi