Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Die Delphi-IDE (https://www.delphipraxis.net/62-die-delphi-ide/)
-   -   Wann hat sich die Funktion SecondsBetween geändert (https://www.delphipraxis.net/181510-wann-hat-sich-die-funktion-secondsbetween-geaendert.html)

v2afrank 21. Aug 2014 10:42


Wann hat sich die Funktion SecondsBetween geändert
 
Hallo,
ich benutze in einem Delphi 6 Programm die Funktion SecondsBetween. Dabei ist mir ein Fehler aufgefallen, den mann so reproduzieren kann:
Delphi-Quellcode:
procedure TForm35.Button1Click(Sender: TObject);

var
   s1,s2:string;
   d1,d2:TDateTime;
   diff:Integer;
begin
  s1:='05:23:08';
  s2:='05:23:19';
  d1:=StrToDate('16.07.2014')+StrToTime(s1);
  d2:=StrToDate('16.07.2014')+StrToTime(s2);
  diff:=SecondsBetween(d1,d2);
  Caption:=IntToStr(diff);
end;
In meinem Delphi 6 bekomme ich hier 10 raus. Mit meinem XE2 kommt die erwartete 11 raus. Ich muss allerdings 6 benutzen, da ich eine CSV Datei mit dem CSV Reader von hier einlese die noch nicht Unicode fähig ist. Gibt es außer try and error noch eine Möglichkeit heruaszufinden wann sich die Funktion geändert hat ? Mit wann meine ich dabei welche Delphi Version

himitsu 21. Aug 2014 10:53

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Wieso ist es denn wichtig wann das passiert ist?

Jetzt geht es richtig und früher war es falsch.
Im Grunde brauchst du eh nur die Versionen selber prüfen, welche ihr einsetzt und dann interessiert nur "hier geht es, aber da nicht".

Sicher das sich SecondsBetween geändert hat und nicht StrToTime?

Eventuell ist die CPU auch auf einen anderen Rundungsmodus eingestellt, z.B. durch irgendwelche Fremdkomponenten, welche einfach so an programmglobalen Dingen rumfummeln, oder durch andere Grundeinstellungen der RTL/VCL.


6? ... Unicode ... Da geht doch alles bis D2007 (D7, D8, D2005, D2006, D2007)
Also einfach mal D2007 ausprobieren und wenn es da auch noch nicht richtig geht, dann habt ihr eh pech und solltet den Code nun doch langsam mal portieren. :angel:
(Beim Kauf von XE2 konntet ihr euch ja alles runter bis D7 freischalten lassen)

mkinzler 21. Aug 2014 10:55

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Dann wäre es doch einfacher diese unicodefähig zu machen.

v2afrank 21. Aug 2014 11:03

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Momentan habe ich aber nur XE2 und 7 installiert. Klar kann ich jetzt die verschiedenen Versonen bis 2007 installieren und testen. Einfacher wäre es aber doch gewesen wenn irgendwo ersichtbar gewesen wäre. Geändert ab x.y.

Es war natürlich praktisch die Datei einfach zu nehmen und das Einlesen der CSV Dateie war erledigt.

Dejan Vu 21. Aug 2014 11:20

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Zitat:

Zitat von himitsu (Beitrag 1269355)
Wieso ist es denn wichtig wann das passiert ist?

Um zu wissen, wann der Qualitätscheck bei Emba/nprise/Codegear/Borland ausgesetzt hat.
Zitat:

Eventuell ist die CPU auch auf einen anderen Rundungsmodus eingestellt, z.B. durch irgendwelche Fremdkomponenten, welche einfach so an programmglobalen Dingen rumfummeln, oder durch andere Grundeinstellungen der RTL/VCL.
Mal sehen: Ungenauigkeit = 1 Sekunde, oder 1/86400 oder die 10/11 Stelle (30000.123456 ist ja ein auf die Sekunde genaues Datum). Double hat aber 15 signifikante stellen. Wenn ich jetzt mal annehme, das 'StrToDateTime' keine 3-4 Schutzstellen verbrät, kann es daran nicht liegen.

Habe ich einen Fehler in meinen Überlegungen?

Aber ausprobieren wäre ja interessant:
Delphi-Quellcode:
var oneSecond double;

begin
  oneSecond := (strToDateTime('16.07.2014 13:04:05')-StrToDateTime('16.07.2014 13:04:04'))*86400;
  writeln(oneSecond);
end.
Was kommt denn da raus? Bzw. mit den Zeiten vom TE?

pertzschc 21. Aug 2014 11:45

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Zitat:

Zitat von Dejan Vu (Beitrag 1269366)
Was kommt denn da raus? Bzw. mit den Zeiten vom TE?

" 9.99999605119228E-0001" mit Delphi 2010.

Grüße, Christoph

himitsu 21. Aug 2014 12:07

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Zitat:

Zitat von Dejan Vu (Beitrag 1269366)
Wenn ich jetzt mal annehme, das 'StrToDateTime' keine 3-4 Schutzstellen verbrät, kann es daran nicht liegen.

Wenn Da SecondsBetween abrundet, dann reicht schon ein Rundungsfehler von 'ner Millisekunde, in die ungünstigste Richtung.

v2afrank 21. Aug 2014 12:10

AW: Wann hat sich die Funktion SecondsBetween geändert
 
9.99999605119228E-0001 mit Delphi 6 und XE2

himitsu 21. Aug 2014 12:16

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Alle Between-Time-Funktionen arbeiten mit Millisekunden.

Also erstmal auf Millisekunden umgerechnet, dann die Differenz gebildet und zum Schluß abgerundet (Integerdivision durch die entsprechende Zeiteinheit, hier MSecPerSec).
Es wird also 3 Mal (ab)gerundet.



Die Betweenfunktionen geben halt jede "abgeschlossene" Zeiteinheit raus und nicht die gerundeten.
In diesem Fall lieg die Lösung darin, daß an das Endedatum z.B. eine halbe Sekunde angehängt wird,
oder Emba hätte, wie z.B. bei den CompareValue-Funktionen, ein Epsilon zur Verfügung gestellt, bzw. würde runden statt abzurunden.



Zitat:

Zitat von Dejan Vu (Beitrag 1269366)
Um zu wissen, wann der Qualitätscheck bei Emba/nprise/Codegear/Borland ausgesetzt hat.

Wieso ausgesetzt?

Jetzt rechnet die Funktion doch richtig und früher war sie "kaputt". :zwinker:

Dejan Vu 21. Aug 2014 12:28

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Zitat:

Zitat von himitsu (Beitrag 1269383)
Zitat:

Zitat von Dejan Vu (Beitrag 1269366)
Um zu wissen, wann der Qualitätscheck bei Emba/nprise/Codegear/Borland ausgesetzt hat.

Wieso ausgesetzt?

Jetzt rechnet die Funktion doch richtig und früher war sie "kaputt". :zwinker:

Wurde das kommuniziert? :zwinker:
Ist Qualität = 'gut' oder eher und in erster Linie 'gleichbleibend', 'transparent' und vor allen Dingen 'nachvollziehbar'? :zwinker:

Etwas, was immer gleich ist, ist qualitativ besser, als etwas, von dem man nicht weiß, ob es noch gleich ist. Qualität ist in erster Linie ein Maß für die Wiederholbarkeit und erst dann ein Maß für Güte. McDonalds hat zum Beispiel eine sehr hohe Qualität. Schmeckt zwar beschissen, aber immer gleich, man kann sich drauf verlassen.

Aber es war polemisch. Kann nämlich sein, das das in irgend einer Release note drin stand.

@himitsu: Also werden doch die Stellen ausgereizt. Ich habe hier kein Delphi und kann das nicht nachprüfen. Danke für die Mühe.

himitsu 21. Aug 2014 12:34

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Nochmal nachgedacht:
Aufgrund der bekannten Rundungen, an jede Zeit 'ne 1/4 Millisekunde dranhängen und an die Endezeit nochmal 'ne 1/4 Sekunde ... dann sollten die Rundungsfehler weg sein.
Oder selber rechnen
Delphi-Quellcode:
Round(Abs(Zeit1 - Zeit2) * SecsPerDay)
.

Sir Rufo 21. Aug 2014 12:40

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Gibt es da nicht so eine tolle Erfindung wie Unittests?

Damit prüft man die eigenen Gebilde (und auch implizit das, was man mitverwendet).
Im Zweifelsfall läuft es auf einen Compilerschalter hinaus, der bestimmt Unterschiede bei den Compilern eben berücksichtigt. Aber dieser Fehler rutscht dann nicht mehr durch.

mirage228 21. Aug 2014 12:52

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Zur Referenz noch die Diskussion, wo das Problem vor einigen Jahren auch schon auffiel: http://www.delphipraxis.net/151504-s...ehlerhaft.html

Zumindest mit Delphi 2010 stieß ich hier ebenfalls auch Ungereimtheiten und habe mir eine eigene, modifizierte Variante schreiben müssen, die korrekt rechnet.

Dejan Vu 21. Aug 2014 13:09

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Zitat:

Zitat von Sir Rufo (Beitrag 1269393)
Gibt es da nicht so eine tolle Erfindung wie Unittests?

Wenn man nicht weiß, das es fehlerhaft ist und man die Routine nicht kennt, bringt das blöderweise nicht viel. Außer, man rechnet das für alle Zeiten aus, was dann wieder etwas länger dauert.

Ergo: Bei derart kritischen Routinen sollte man sich en Detail die Implementierung anschauen (was normalerweise bei Unittests eben nicht passiert, da man nach Spec testet) und die Einzelschritte testen (i.e. alle Codepfade). Oder besser: Eine Berechnung/Implementierung nach formal korrekter Spezifikation vornehmen. Und dann kann man wieder nach dieser Spec Tests schreiben und sich beruhigt zurücklehnen.

Sir Rufo 21. Aug 2014 14:52

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Zitat:

Zitat von Dejan Vu (Beitrag 1269401)
Zitat:

Zitat von Sir Rufo (Beitrag 1269393)
Gibt es da nicht so eine tolle Erfindung wie Unittests?

Wenn man nicht weiß, das es fehlerhaft ist und man die Routine nicht kennt, bringt das blöderweise nicht viel. Außer, man rechnet das für alle Zeiten aus, was dann wieder etwas länger dauert.

Aber ich weiß doch, was meine Funktionen herausbringen sollen und das überprüft man

himitsu 21. Aug 2014 15:20

AW: Wann hat sich die Funktion SecondsBetween geändert
 
siehe der andere Thread -> http://www.delphipraxis.net/151504-s...ehlerhaft.html

Es kommt jetzt darauf an, mit welchem der beiden Werte du zufällig deinen Unittest aufbaust.

Sir Rufo 21. Aug 2014 15:30

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Zitat:

Zitat von himitsu (Beitrag 1269436)
siehe der andere Thread -> http://www.delphipraxis.net/151504-s...ehlerhaft.html

Es kommt jetzt darauf an, mit welchem der beiden Werte du zufällig deinen Unittest aufbaust.

Nochmal zum Mitschreiben:

Ich für meinen Teil baue keine Unittests für die Standard-Delphi-Funktionen. Aber ich erstelle Funktionen, Klassen mit Methoden und diese benutzen auch die Delphi-Standard-Funktionen.

Für diese meinen Funktionen, Klassen und Methoden erstelle ich Unittests. Wenn dort dann nicht die erwarteten Werte herauskommen, dann schlägt der Unittest für meine Methoden/Funktionen an.

Warum das dann fehlerhaft ist, dass muss ich dann selber herausfinden. Das passe ich dann so an, dass es passt. Wenn eine neuere Delphi-Version dann andere Werte liefert, dann schlägt der Unittest wieder für meine Methoden/Funktionen an, weil die ja mit falschen Werten arbeiten.

himitsu 21. Aug 2014 15:33

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Ja, und nun kommt es darauf an, mit welchem Wert deine Funktion z.B. dieses SecondsBetween aufrufen würde.

Jenachdem kann der Test deiner Funktion erfolgreich sein, falls du zufällig einen der funktionierenden Fälle erwischts.

Sir Rufo 21. Aug 2014 15:39

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Zitat:

Zitat von himitsu (Beitrag 1269442)
Ja, und nun kommt es darauf an, mit welchem Wert deine Funktion z.B. dieses SecondsBetween aufrufen würde.

Jenachdem kann der Test deiner Funktion erfolgreich sein, falls du zufällig einen der funktionierenden Fälle erwischts.

Ja und das Gras ist grün ... wir wissen doch alle, dass bei einem Unittest mehrere Situationen geprüft werden müssen. Und wenn ein Bug zurückgemeldet wird, dann wird das als weitere Situation in den Unittest aufgenommen und dann der Bug beseitigt.

Ich sehe so einen Unittest immer als ein lebendiges Gebilde an.

himitsu 21. Aug 2014 15:43

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Und wenn du jetzt in allen geprüften Situationen zufällig auf funktionierende Fälle triffst? :tongue:


Frag mal den Murphy :angel:

Dejan Vu 21. Aug 2014 16:10

AW: Wann hat sich die Funktion SecondsBetween geändert
 
Für Unittests bildet man Kongruenzklassen für die Parameter, wählt Kandidaten aus den KK aus und testet mit allen Kombinationen von Parametern.
Beispiel:
"Bei positivem Kontostand werden Guthabenzinsen verwendet, bei negativem die Dispozinsen. Ist der Kontostand 0, wird kein Zinsatzverwendet. Auszudrucken ist der zu verwendete Zinssatz"

Wir haben drei Kongruenzklassen (laut Spec):
1. Alle Guthaben > 0
2. Guthaben = 0
3. Alle Guthaben < 0

Wir generieren Tests für Werte ...
* so in der Mitte einer KK
* so am Rand der KK
* direkt am Rand der KK

Manchmal alle drei, manchmal reichen zwei (Mitte und direkt am Rand) oder nur ein wert (der in der Mitte).

Wie sieht das bei 'SecondsBetween' aus? Wieviele Kongruenzklassen haben wir? Laut Spec 2: "gültiges Datum" und "ungültiges Datum". Bischen wenig.

Mist. Unser Test wird entweder imnmer fehlschlagen (weil wir Glück haben, und Datumse gewählt haben, die nicht passen) oder immer funktionieren. Davon haben wir dann aber nicht viel.

Also: Genau spezifizieren, wie SecsBetween (also 'Seconds between') implementiert werden muss.

Daher mit Tipp: Für Kernfunktionen exakt spezifizieren wie sich die Funktion verhalten soll und im Idealfall das Verfahren angeben. Dann kann man KK bilden und 100% Testabdeckung erzielen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:40 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