AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

CompareDate gibt immer 1 aus...

Ein Thema von Codix32 · begonnen am 18. Mai 2015 · letzter Beitrag vom 26. Mai 2015
Antwort Antwort
Seite 1 von 2  1 2      
Codix32

Registriert seit: 23. Apr 2009
137 Beiträge
 
Delphi 2005 Personal
 
#1

CompareDate gibt immer 1 aus...

  Alt 18. Mai 2015, 00:47
Delphi-Version: 2005
Merkwürdiges Verhalten bei CompareDate

Egal ob der erste Datumwert kleiner, größer, oder gleich dem Zweiten ist:

Der Wert ist immer 1

Hat jemand sowas schon erlebt?

Delphi-Quellcode:
var
  a, b:TDate;
begin
 a:= now;
 if Key = VK_Return then
  begin
   b:= strtodate(Edit1.Text);
   Label1.Caption:= inttostr(compareDate(a,b));
  end;
end;
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#2

AW: CompareDate gibt immer 1 aus...

  Alt 18. Mai 2015, 01:07
Bedenke bitte, dass es im Grunde egal ist ob du TDateTime oder TDate oder TTime nimmst. Im Hintergrund ist alles TDateTime. Das ist irreführend, aber TDate speichert nicht Datum, sondern auch Uhrzeit ab.

Wenn du also eine TDate Variable definierst und ihr Now zuweist, dann hast du ihr Datum und Uhrzeit zugewiesen. Die Variable enthält also den TDateTime Wert. Und Now jetzt, selbst wenn es eine TDate Variable ist, und Now eine Millisekunde später, sind nicht gleich.

Lösung:

- Statt Now Funktion Date Funktion nehmen. Die gibt nur das Datum zurück.
- oder Trunc(Now) eingeben. Damit wird die Uhrzeit angeschnitten.
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.682 Beiträge
 
Delphi 5 Professional
 
#3

AW: CompareDate gibt immer 1 aus...

  Alt 18. Mai 2015, 01:44
@Popov: Ich nahm an, weil du Delphi 7 hast, kannst du nachschauen, was CompareDate macht. CompareDate vergleicht nur den Datumsteil, oder anders ausgedrückt: beide Parameter werden einem Trunc unterzogen (zumindest für den Vergleich auf Gleichheit).

Die Frage ist also: Was steht in den beiden Variablen a und b drin? Das bekommt man ja leicht raus mit DateToStr.

MfG Dalai
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#4

AW: CompareDate gibt immer 1 aus...

  Alt 18. Mai 2015, 01:57
Ich hab vorher den Code nicht ausprobiert, aber CompareDate gibt richtige Ergebnisse raus. Vorausgesetzt die Eingabe ist richtig, z. B. "15.05.2015".
  Mit Zitat antworten Zitat
Dejan Vu
(Gast)

n/a Beiträge
 
#5

AW: CompareDate gibt immer 1 aus...

  Alt 18. Mai 2015, 07:45
Nimm mal die 'If Key=' Abfrage raus. Wäre ja denkbar, das es sich nur um ein Wahrnehmungsproblem handelt. Ansonsten stelle das Problem mit einem kleinen Testprogramm dar.
Delphi-Quellcode:
Program Tester;
{$APPTYPE CONSOLE}

Procedure TestCompareDate (a : TDate; bStr : String);
var
  b : TDate;

Begin
  b := StrToDate(bStr);
  Writeln ('CompareDate('DateToStr(a),',',DateToStr(b),')=',CompareDate(a,b));
End;

begin
  TestCompareDate(Now,'1.1.2015');
  TestCompareDate(Now,'1.1.2016');
end.
Trage jeweils deine Testdaten ein, mit denen bei Dir angeblich '1' rauskommt.
  Mit Zitat antworten Zitat
Codix32

Registriert seit: 23. Apr 2009
137 Beiträge
 
Delphi 2005 Personal
 
#6

AW: CompareDate gibt immer 1 aus...

  Alt 25. Mai 2015, 23:20
Trage jeweils deine Testdaten ein, mit denen bei Dir angeblich '1' rauskommt.
Dein Beispiel funktioniert bei mir richtig.

Aber hier:
Delphi-Quellcode:
function TForm1.Tagedazwischen(vor, nach:TDate):Integer;
begin
 if compareDate(vor,nach) >= 0 then Result:= daysbetween(vor,nach)
 Else if compareDate(vor,nach) < 0 then Result := -1;
end;
Das Ergebnis bleibt immer 1.
Und eine Meldung lautet:
[Warnung] Unit1.pas(94): W1035 Rückgabewert der Funktion 'TForm1.Tagedazwischen' könnte undefiniert sein

Warum?

Aufgerufewn wird die Funktion hier:
Delphi-Quellcode:
procedure TForm1.Zeitraum(dt:TDate);
var
  vorTag:TDate;
begin
Gauge1.Progress:=0; Gauge2.Progress:=0;Gauge3.Progress:=0;
 vorTag:= strtoDate('17.04.2015');
  if wievieltePackung(Tagedazwischen(dt, vorTag)) >= 1 then
     Gauge1.Progress:= round(100 / 28 * Tagedazwischen(dt, vorTag));
Dabei spielt es keine Rolle ob ich Zeitraum(Now) oder Zeitraum(Date) schreibe.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu
Online

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.034 Beiträge
 
Delphi 12 Athens
 
#7

AW: CompareDate gibt immer 1 aus...

  Alt 25. Mai 2015, 23:50
Zitat:
Warum?
Formatiere mal den Quelltext ordentlich und dann sieht du es bestimmt.


[edit]
Delphi-Quellcode:
function TForm1.TageDazwischen(vor, nach: TDate): Integer;
begin
  if CompareDate(vor, nach) >= 0 then
    Result := DaysBetween(vor, nach)
  else
    if CompareDate(vor, nach) < 0 then
      Result := -1
    {else
      Result := ???}
;
end;


Delphi-Quellcode:
function TForm1.TageDazwischen(vor, nach: TDate): Integer;
begin
  if CompareDate(vor, nach) >= 0 then
    Result := DaysBetween(vor, nach)
  else
    //if CompareDate(vor, nach) < 0 then // Oder das weglassen, da eh sinnlos, aber das weiß der Compiler ja nicht.
      Result := -1;
end;
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests

Geändert von himitsu (25. Mai 2015 um 23:57 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Dalai
Dalai

Registriert seit: 9. Apr 2006
1.682 Beiträge
 
Delphi 5 Professional
 
#8

AW: CompareDate gibt immer 1 aus...

  Alt 26. Mai 2015, 00:00
Aber hier:
Delphi-Quellcode:
function TForm1.Tagedazwischen(vor, nach:TDate):Integer;
begin
 if compareDate(vor,nach) >= 0 then Result:= daysbetween(vor,nach)
 Else if compareDate(vor,nach) < 0 then Result := -1;
end;
Das Ergebnis bleibt immer 1.
Das Ergebnis wovon genau? CompareDate? DaysBetween? Und warum rufst du CompareDate doppelt auf?

Zitat:
Und eine Meldung lautet:
[Warnung] Unit1.pas(94): W1035 Rückgabewert der Funktion 'TForm1.Tagedazwischen' könnte undefiniert sein

Warum?
Weil du zwei if-Bedingungen stehen hast und Result jeweils von der Erfüllung selbiger abhängt. Die Warnung mag zwar für die menschliche Logik nicht zutreffen, aber das weiß der Compiler ja nicht.

Zitat:
Aufgerufewn wird die Funktion hier:
Delphi-Quellcode:
procedure TForm1.Zeitraum(dt:TDate);
var
  vorTag:TDate;
begin
Gauge1.Progress:=0; Gauge2.Progress:=0;Gauge3.Progress:=0;
 vorTag:= strtoDate('17.04.2015');
  if wievieltePackung(Tagedazwischen(dt, vorTag)) >= 1 then
     Gauge1.Progress:= round(100 / 28 * Tagedazwischen(dt, vorTag));
Mach mal eine Ersetzung der Variablen mit deinen Eingabedaten auf Papier (oder im Editor) und überlege, was jeweils bei den Funktionen rauskommt und vergleiche das mit deinen Erwartungen. Kann man auch im Debugger machen, wenn man will.

MfG Dalai
  Mit Zitat antworten Zitat
Popov
(Gast)

n/a Beiträge
 
#9

AW: CompareDate gibt immer 1 aus...

  Alt 26. Mai 2015, 00:04
Zitat:
Warum?
Formatiere mal den Quelltext ordentlich und dann sieht du es bestimmt.
Wollte ich gerade auch drauf hinweisen.

Aber vielleicht noch paar Hinweise und Fragen:
Delphi-Quellcode:
function TForm1.Tagedazwischen(vor, nach:TDate):Integer;
begin
 if compareDate(vor,nach) >= 0 then Result:= daysbetween(vor,nach)
 Else if compareDate(vor,nach) < 0 then Result := -1;
end;
Wenn compareDate(vor,nach) >= 0 größer, gleich Null sind, warum fragst du dann später nochmal mit compareDate(vor,nach) < 0 ob es kleiner Null ist?

Im Code compareDate(vor,nach) steht vor vor nach. In der Funktion Zeitraum ist in der Zeile wievieltePackung(Tagedazwischen(dt, vorTag)) der vorTag an zweiter Stelle. Ich weiß nicht welche Tage in dt stehen, aber ich gehe davon aus, dass es nachTage sind. Vielleicht solltest du für den Fall in der Funktion Tagedazwischen zuerst vor und nach sortieren, also prüfen ob vor auch wirklich das frühere Datum ist. Ansonsten prüfst du drauf ob das spätere Datum vor dem älteren Datum steht. Das Ergebnis wäre in dem Fall -1.
  Mit Zitat antworten Zitat
Codix32

Registriert seit: 23. Apr 2009
137 Beiträge
 
Delphi 2005 Personal
 
#10

AW: CompareDate gibt immer 1 aus...

  Alt 26. Mai 2015, 00:17
Zitat:
Warum?
Formatiere mal den Quelltext ordentlich und dann sieht du es bestimmt.


[edit]
Delphi-Quellcode:
function TForm1.TageDazwischen(vor, nach: TDate): Integer;
begin
  if CompareDate(vor, nach) >= 0 then
    Result := DaysBetween(vor, nach)
  else
    if CompareDate(vor, nach) < 0 then
      Result := -1
    {else
      Result := ???}
;
end;


Delphi-Quellcode:
function TForm1.TageDazwischen(vor, nach: TDate): Integer;
begin
  if CompareDate(vor, nach) >= 0 then
    Result := DaysBetween(vor, nach)
  else
    //if CompareDate(vor, nach) < 0 then // Oder das weglassen, da eh sinnlos, aber das weiß der Compiler ja nicht.
      Result := -1;
end;
Ich stehe auf dem Schlauch. Das geht auch nicht:
Delphi-Quellcode:
function TForm1.Tagedazwischen(vor, nach:TDate):Integer;
begin
 if compareDate(vor,nach) >= 0 then
    Result:= daysbetween(vor,nach)
 Else
 //if compareDate(vor,nach) < 0 then Result := -1;
    Result := -1;
end;
Es bleibt 1, auch wenn das erste Datum größer als das 2. ist.
Result := -1 wird nicht ausgegeben.
Die Fehlermeldung ist allerdings weg.

Normalerweise wird die Procedure Zeitraum(date), in der die Function liegt im OnCreate der Form aufgerufen:
Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
begin
  BorderIcons := [biSystemmenu];
  Statusbar1.panels[0].text:='Datum: '+ DatetoStr(Date);
  Statusbar1.panels[1].text:='Woche: '+ InttoStr(WeekOf(Date));
  Zeitraum(Date); //<- Enthält die Function Tagedazwischen
  fuelleLabels;
end;
Hier die Procedure:
Delphi-Quellcode:
procedure TForm1.Zeitraum(dt:TDate);
var
  vorTag:TDate; //<- 1 Tag vor der 1. Tablette
begin
 Gauge1.Progress:=0; Gauge2.Progress:=0;Gauge3.Progress:=0;
 vorTag:= strtoDate('17.04.2015');
  if wievieltePackung(Tagedazwischen(dt, vorTag)) >= 1 then
     Gauge1.Progress:= round(100 / 28 * Tagedazwischen(dt, vorTag));
  if wievieltePackung(daysbetween(dt, vorTag)) >= 2 then
     Gauge2.Progress:= round(100 / 28 * Tagedazwischen(dt, vorTag+incday(27)));
  if wievieltePackung(daysbetween(dt, vorTag)) > 2 then
     Gauge3.Progress:= round(100 / 28 * Tagedazwischen(dt, vorTag+incDay(55)));
     Gauge4.Progress:= round(100 / 84 * Tagedazwischen(dt, vorTag));
  if Tagedazwischen(dt, vortag) <= 84 then
     Label14.caption:= ' Tabletten genommen: ' + inttostr(Tagedazwischen(dt, vortag))+ '/84'
  else
    Label14.caption:= ' Tabletten genommen: 84/84';
    Label15.Caption:= inttostr(compareDate(dt, vortag));
end;
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:49 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