Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi SecondsBetween fehlerhaft? (https://www.delphipraxis.net/151504-secondsbetween-fehlerhaft.html)

dominikkv 20. Mai 2010 13:03


SecondsBetween fehlerhaft?
 
Hi,

ich habe ein kleines Problem mit der Funktion SecondsBetween aus den DateUtils. Diese gibt in manchen Fällen ein fehlerhaftes Ergebnis aus. Beispiel:
Delphi-Quellcode:
program Test;

{$APPTYPE CONSOLE}

uses
  SysUtils, DateUtils;

var
  Date1, Date2: TDateTime;
  Dummy: Char;

begin
  Date1 := StrToDateTime('20.05.2010 13:57:40');
  Date2 := StrToDateTime('20.05.2010 14:02:40');

  WriteLN(DateTimeToStr(Date1), ' - ', DateTimeToStr(Date2), ' = ', SecondSpan(Date1, Date2), ' = ', SecondsBetween(Date1, Date2));

  Date1 := StrToDateTime('20.05.2010 14:57:40');
  Date2 := StrToDateTime('20.05.2010 15:02:40');

  WriteLN(DateTimeToStr(Date1), ' - ', DateTimeToStr(Date2), ' = ', SecondSpan(Date1, Date2), ' = ', SecondsBetween(Date1, Date2));

  Read(Dummy);
end.
Ergebnis:
Zitat:

20.05.2010 13:57:40 - 20.05.2010 14:02:40 = 2.99999999720603E+0002 = 299
20.05.2010 14:57:40 - 20.05.2010 15:02:40 = 3.00000000349246E+0002 = 300
Beides mal ist der Unterschied genau 5 Minuten (= 300 Sekunden), der erste Aufruf zeigt aber eine Differenz von 299 Sekunden!

Das wird wohl daran liegen, dass TDateTime ein Double ist und darum Ungenauigkeiten in den Nachkommabereichen auftreten. Allerdings erwarte ich von einer offiziellen Funktion dass diese auch funktioniert (Wortspiel! :cyclops: ).

Ich behelfe mir im Moment so:
Delphi-Quellcode:
function MySecondsBetween(const ANow, AThen: TDateTime): Int64;
begin
  Result := Round(SecondSpan(ANow, AThen));
end;
ich weiß aber nicht, ob sich diese Funktion immer richtig verhält.

Was haltet ihr davon?

Dominik

blackfin 20. Mai 2010 13:09

Re: SecondsBetween fehlerhaft?
 
Ja, die Funktion Secondsbetween hat einen Bug :(

Das Problem daran ist, dass die SecondBetween so implementiert ist:
Result := Trunc(SecondSpan(ANow, AThen));
...und das Trunc macht hier diesen Bug aus, da es rigoros die Nachkommastellen abschneidet und das stimmt ja so nicht ganz. Round ist hier besser / genauer.

Die von dir vorgeschlagene Lösung verwende ich auch, hat eigentlich noch nie versagt...
Irgendwo stand sogar im EDN, dass man dies am Besten statt Secondsbetween verwenden soll.

Wolfgang Mix 20. Mai 2010 13:11

Re: SecondsBetween fehlerhaft?
 
Hier wurde gezeigt, dass auch die Funktion YearsBetween falsch rechnet.

blackfin 20. Mai 2010 13:12

Re: SecondsBetween fehlerhaft?
 
Das betrifft alle xxxxBetween Funktionen :)

dominikkv 20. Mai 2010 13:21

Re: SecondsBetween fehlerhaft?
 
ok, danke euch :thumb:

Wolfgang Mix 20. Mai 2010 14:43

Re: SecondsBetween fehlerhaft?
 
Mathematisch sicherer ist wohl, beide Zeiten in Sekunden umzurechnen
und dann die Differenz zu bilden.

himitsu 21. Aug 2014 12:59

AW: Re: SecondsBetween fehlerhaft?
 
Zitat:

Zitat von Wolfgang Mix (Beitrag 1022459)
Mathematisch sicherer ist wohl, beide Zeiten in Sekunden umzurechnen
und dann die Differenz zu bilden.

Aber nur, wenn man beim Umrechnen nicht auch wieder mit Trunc arbeitet.

Beide Seiten abrundend in Sekunden umberechnet, ergibt dann auch wieder soein Rundungsproblem.
siehe http://www.delphipraxis.net/181510-w...aendert-2.html
Aktuell wird Beides in Millisekunden umgerechnet, subtrahiert und dann abgerundet in Sekunden umgewandelt.

Dejan Vu 21. Aug 2014 13:02

AW: SecondsBetween fehlerhaft?
 
Wird es korrekt in Millisekunden umgerechnet? Also z.B. 0.5 ms addiert und dann abgerundet?

himitsu 21. Aug 2014 14:49

AW: SecondsBetween fehlerhaft?
 
Nein, natürlich nicht. :stupid:

Es wird DateTimeToMilliseconds benutzt, welches intern DateTimeToTimeStamp verwendet und das rundet (glaub ich) brav ab.
Wie gesagt, es wird (scheinbar) überall nur mit abgeschlossenen Zeiteinheiten gerechnet, also immer ordentlich abrunden, inkl. eventueller Rundungsfehler.


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:22 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz