![]() |
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:
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
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; ![]() |
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) |
AW: Wann hat sich die Funktion SecondsBetween geändert
Dann wäre es doch einfacher diese unicodefähig zu machen.
|
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. |
AW: Wann hat sich die Funktion SecondsBetween geändert
Zitat:
Zitat:
Habe ich einen Fehler in meinen Überlegungen? Aber ausprobieren wäre ja interessant:
Delphi-Quellcode:
Was kommt denn da raus? Bzw. mit den Zeiten vom TE?
var oneSecond double;
begin oneSecond := (strToDateTime('16.07.2014 13:04:05')-StrToDateTime('16.07.2014 13:04:04'))*86400; writeln(oneSecond); end. |
AW: Wann hat sich die Funktion SecondsBetween geändert
Zitat:
Grüße, Christoph |
AW: Wann hat sich die Funktion SecondsBetween geändert
Zitat:
|
AW: Wann hat sich die Funktion SecondsBetween geändert
9.99999605119228E-0001 mit Delphi 6 und XE2
|
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:
Jetzt rechnet die Funktion doch richtig und früher war sie "kaputt". :zwinker: |
AW: Wann hat sich die Funktion SecondsBetween geändert
Zitat:
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. |
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)
|
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. |
AW: Wann hat sich die Funktion SecondsBetween geändert
Zur Referenz noch die Diskussion, wo das Problem vor einigen Jahren auch schon auffiel:
![]() Zumindest mit Delphi 2010 stieß ich hier ebenfalls auch Ungereimtheiten und habe mir eine eigene, modifizierte Variante schreiben müssen, die korrekt rechnet. |
AW: Wann hat sich die Funktion SecondsBetween geändert
Zitat:
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. |
AW: Wann hat sich die Funktion SecondsBetween geändert
Zitat:
|
AW: Wann hat sich die Funktion SecondsBetween geändert
siehe der andere Thread ->
![]() Es kommt jetzt darauf an, mit welchem der beiden Werte du zufällig deinen Unittest aufbaust. |
AW: Wann hat sich die Funktion SecondsBetween geändert
Zitat:
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. |
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. |
AW: Wann hat sich die Funktion SecondsBetween geändert
Zitat:
Ich sehe so einen Unittest immer als ein lebendiges Gebilde an. |
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: |
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 01:02 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz