Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Vergleich von 2 TDateTime's (https://www.delphipraxis.net/129194-vergleich-von-2-tdatetimes.html)

BackOrifice 14. Feb 2009 03:29


Vergleich von 2 TDateTime's
 
Nabend.

Ich habe hier ein Datum, welches größergleich einem StartDatum und kleinergleich einem Enddatum sein muss. Dazu benutze ich eine Funktion IsValidDate.
Delphi-Quellcode:
function TSemesters.IsValidDateToSemester(SemesterId: TSemesterID;
  Date: TDateTime): Boolean;
var SemesterInfo : TSemesterValue;
begin
  ... // SemesterInfo ist ein Record. SemesterBegin und SemesterEnd vom Typ TDate
  Result := (Date - SemesterInfo.SemesterBegin >= 0.0) and
    (SemesterInfo.SemesterEnd - Date >= 0.0)
end;

Nun weiß ich ja, dass ein direkter >=, <=, == Vergleich mit Gleitkommazahlen kritisch ist. Aber TDates belegen doch eh nur die Vorkommastelle und daher müsste ein Vergleich >= funktionieren - oder?
Vllt denke ich auch falsch. Ich bräuchte nur ein kurzes Feedback.

Thanks.

omata 14. Feb 2009 03:45

Re: Vergleich von 2 TDateTime's
 
Schau dir doch mal CompareDateTime in der Unit DateUtils an.

HaJo 14. Feb 2009 04:08

Re: Vergleich von 2 TDateTime's
 
Du kannst einen beliebigen Datums/Zeit Wert in eine signifikante Zahl umwandeln. Somit ist ein Vergleich zweier Datumswerte unzweifelhat möglich

BoolString 14. Feb 2009 09:09

Re: Vergleich von 2 TDateTime's
 
Die Überlegung ist zwar grundlegend richtig, aber aus den von dir bereits genannten Gründen sollte der Vergleich auf Datumswerte kein Problem darstellen.

Erstmal handelt es sich beim TDATE Wert um den Vorkommaanteil; und der wird präzise genug abgebildet. Außerdem hast du ja keine Prüfung auf Gleichheit, sondern auf auf 'Größer Gleich'. Nichts anderes tut man ja auch beim Vergleich zweier Floats; schauen, ob die Differenz zweier Werte Größer/Kleiner als eine gewisse Toleranz ist. Spannender wäre es, wenn du versuchen würdest Daten unterhalb von Millisekunden zu vergleichen.

Also meiner Meinung nach ist dies durchaus legitim und dürfte auch keine Probleme geben (mache es selbst so ;-)

Jan

hoika 14. Feb 2009 09:46

Re: Vergleich von 2 TDateTime's
 
Hallo,

das Problem tritt dann auf,
wenn du einen Tag z.B. über eine Addition von Stunden erzeugst.
In Abhängigkeit der jeweiligen Stunden gibt es Rundungsprobleme.

StrToTime('08:00')+StrToTime('08:00')+StrToTime('0 8:00')

ergibt z.B. nicht genau 1.0 (24h = 1 Tag)

Da hilft dann DateOf von Jedi.


Heiko

mkinzler 14. Feb 2009 09:48

Re: Vergleich von 2 TDateTime's
 
Oder einfach Trunc( <DateTime>)

Chemiker 14. Feb 2009 09:51

Re: Vergleich von 2 TDateTime's
 
Hallo BackOrifice,

TDate = TDateTime= Double

TDate belegt nicht nur die Vorkommastellen, sondern ist ein Type der Double entspricht und nur der bessern Lesbarkeit des Quellcodes dient.

Zitat:

Zitat von omata
Schau dir doch mal CompareDateTime in der Unit DateUtils an.

omata hat die Lösung schon angegeben.

Bis bald Chemiker

alzaimar 14. Feb 2009 09:52

Re: Vergleich von 2 TDateTime's
 
Zitat:

Zitat von HaJo
Du kannst einen beliebigen Datums/Zeit Wert in eine signifikante Zahl umwandeln. Somit ist ein Vergleich zweier Datumswerte unzweifelhat möglich

Ein TDateTime ist bereits eine Zahl, nämlich Double, also muss man nichts umwandeln. :zwinker:.

Chemiker 14. Feb 2009 10:09

Re: Vergleich von 2 TDateTime's
 
Hallo hoika,

vielleicht habe ich das ja nicht richtig verstanden, aber bei mir kommt 1 raus.

Delphi-Quellcode:
cStd:= StrToTime('08:00')+StrToTime('08:00')+StrToTime('08:00');
edDatumAus.Text:= FloatToStr(cStd);
Bis bald Chemiker

mkinzler 14. Feb 2009 10:16

Re: Vergleich von 2 TDateTime's
 
Zitat:

Zitat von Chemiker
Hallo hoika,

vielleicht habe ich das ja nicht richtig verstanden, aber bei mir kommt 1 raus.

Delphi-Quellcode:
cStd:= StrToTime('08:00')+StrToTime('08:00')+StrToTime('08:00');
edDatumAus.Text:= FloatToStr(cStd);
Bis bald Chemiker

Durch das StrToTime() erzeugst du auch einen geanuen Wert. Bei TDateTime-Werten in der Praxis ist das oft nicht so.

Satty67 14. Feb 2009 10:31

Re: Vergleich von 2 TDateTime's
 
genau.
Delphi-Quellcode:
StrToTime('08:00') = 0.3333...
Dann gibt die o.g. Rechnung nur 0.9999... statt der gewünschten 1.0

BoolString 14. Feb 2009 11:08

Re: Vergleich von 2 TDateTime's
 
Wenn ich das richtig verstanden habe, dann ging es doch aber nur um Datumswerte. Und dafür müsste die gewählte Variante doch durchaus ausreichend sein. Bei einer Addition von Stunden sieht das Ganze dann tatsächlich anders aus, weil natürlich Bruchteile durch Darstellungsungenauigkeiten unterschlagen werden können. Oder habe ich da jetzt was übersehen?

Jan

Chemiker 14. Feb 2009 11:13

Re: Vergleich von 2 TDateTime's
 
Hallo,

@Satty67: Das ist mir schon klar, dass es bei Gleitkommazahlen zu Rundungsprobleme kommen kann.

@ mkinzler: Ich habe nur das Beispiel von hoika nachgestellt und bei mir wird eine 1 ausgegeben und nicht „ergibt z.B. nicht genau 1.0 (24h = 1 Tag)“ .

Bis bald Chemiker

Hawkeye219 14. Feb 2009 12:05

Re: Vergleich von 2 TDateTime's
 
Hallo,

die Abfrage könnte auch so aussehen:

Delphi-Quellcode:
function TSemesters.IsValidDateToSemester(SemesterId: TSemesterID;
  Date: TDateTime): Boolean;
var SemesterInfo : TSemesterValue;
begin
  ... // SemesterInfo ist ein Record. SemesterBegin und SemesterEnd vom Typ TDate
  Result := {Math.}InRange(Date, StartOfTheDay(SemesterInfo.SemesterBegin),
                                 EndOfTheDay(SemesterInfo.SemesterEnd));
end;
Gruß Hawkeye

BackOrifice 14. Feb 2009 15:15

Re: Vergleich von 2 TDateTime's
 
Erstmal; Danke euch :-D

Es geht tatsächlich nur um Tage, also die Vorkommastellen eines Doubles. Und dafür sollte ja, nach den Aussagen hier, die Genauigkeit reichen. Ich denke, ich nehm die Methode mit dem Math.InRange =)


Vielen Dank.

hoika 16. Feb 2009 08:26

Re: Vergleich von 2 TDateTime's
 
Hallo,

du hast Recht.
Ich wollte mit dem Beispiel nur auf die Gefährlichkeit
des TDateTime hinweisen, wenn man damit rechnet.

Um noch mal auf das Addieren zu kommen.
Delphi-Quellcode:
var
  tdtDateTime: TDateTime;
begin
  tdtDateTime:= StrToTime('08:00')+StrToTime('08:00')+StrToTime('08:00');
  if tdtDateTime=1.0 then
  begin
    // jippi
  end
  else
  begin
    // oops
  end
end;
Bei mir (und bei einem Kunden ... ;( ) landet er in oops .


Heiko


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