Entwickler-Ecke

Sonstiges (Delphi) - Probleme mit der Funktion MonthsBetween von Delphi (Bug??)


[TP]Hawk274 - Sa 11.01.03 19:30
Titel: Probleme mit der Funktion MonthsBetween von Delphi (Bug??)
Hallo ...
ich benutzt die Funktion MonthsBetween um die Anzahl der Monate zwischen den beiden angegebenen TDateTime-Werten verstrichen sind.
Das mache ich vollgehendermaßen ...

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
procedure TdlgAnmeldung.cmbYearBisExit(Sender: TObject);
var
  dtVon, dtBis: TDateTime;
begin
  dtVon := StrToDate( '01.' + cmbMonthVon.Text + '.' + cmbYearVon.Text );
  dtBis := StrToDate( '01.' + cmbMonthBis.Text + '.' + cmbYearBis.Text );
  //Wenn Monat und Jahr jeweils gleich sind --> 0
  if NOT( (MonthOf(dtVon) = MonthOf(dtBis))
      AND (YearOf(dtVon) = YearOf(dtBis)) ) then
  begin
    if NOT( dfMonthCount.Text = '1' ) then
      dfMonthCount.Text := IntToStr( StrToInt(dfMonthCount.Text)+1 );
  end
  else
    dfMonthCount.Text := '0';
end;

Das merkwürdige aber ist wenn ich jetzt 01 und 2003 in den Von comboboxen auswähle und 01 und 2004 in den Bis Comboboxen auswähle steht bei Anzahl der Monate 12 drin -> richtig. Trage ich jetzt aber z.b 01 und 2003 bei Von ein und dann 02 und 2003 bei Bis dann steht dort 2 Monat, obwohl ... das versteh ich nicht ... finde mein Fehler nicht!

Richtig wäre z.B. folgendes:
Von Monat: 01
Von Jahr: 2003
Bis Monat: 02
Bis Jahr: 2003
----------------
Ergebnis: 1 Monat

Von Monat: 01
Von Jahr: 2003
Bis Monat: 03
Bis Jahr: 2003
----------------
Ergebnis: 2 Monat

Von Monat: 01
Von Jahr: 2003
Bis Monat: 04
Bis Jahr: 2003
----------------
Ergebnis: 3 Monat
u.s.w.

hmmm ... komisch, dachte ich mir probierst du mal vollgehendes aus:

Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
procedure TdlgAnmeldung.cmbYearVonExit(Sender: TObject);
var
  dtVon, dtBis: TDateTime;
begin
  dtVon := StrToDate( '01.01.2003' );
  dtBis := StrToDate( '01.02.2003' );

  //Wenn Monat und Jahr jeweils gleich sind --> 0
  if NOT( (MonthOf(dtVon) = MonthOf(dtBis))
      AND (YearOf(dtVon) = YearOf(dtBis)) ) then
  begin
    dfMonthCount.Text := IntToStr( MonthsBetween(dtVon, dtBis));
    Showmessage( dfMonthCount.Text );
  end
  else
    dfMonthCount.Text := '0';
end;

procedure TdlgAnmeldung.cmbYearBisExit(Sender: TObject);
var
  dtVon, dtBis: TDateTime;
begin
  dtVon := StrToDate( '01.01.2003' );
  dtBis := StrToDate( '01.03.2003' );

  //Wenn Monat und Jahr jeweils gleich sind --> 0
  if NOT( (MonthOf(dtVon) = MonthOf(dtBis))
      AND (YearOf(dtVon) = YearOf(dtBis)) ) then
  begin
    dfMonthCount.Text := IntToStr( MonthsBetween(dtVon, dtBis));
    Showmessage( dfMonthCount.Text );
  end
  else
    dfMonthCount.Text := '0';
end;


Als Ergebnis bekomme ich bei beiden 1 zurück geliefert! Das ist aber falsch! Bei dem ersten Ergebnis kommt 1 heraus, das ist richtig doch beim zweiten Ergebnis muss doch 2 heraus kommen. Versteh ich hier jetzt irgendetwas falsch oder mach Delphi was nicht richtig!?


Ex0rzist - So 12.01.03 04:40

Um Differenzen zwischen zwei Zeitpunkten zu ermitteln, empfehle ich dir diese [http://home.pages.at/dbr-software/delphi/tage.htm] Funktion von DBR.

Die funktioniert bei mir wunderbar. :D


[TP]Hawk274 - So 12.01.03 20:00

das sind zwar ganz nette Funktionen ... aber ich benötige die Anzahl der Monate zwischen zwei TDateTime-Werten verstrichen sind ... :?:


AndyB - So 12.01.03 20:40

Schon mal die Online Hilfe zu MonthsBetween gelesen?
Zitat:
Da die Monate keine identische Länge aufweisen, berechnet MonthsBetween eine Näherung, indem 30,4375 Tage pro Monat zugrundegelegt werden. Es werden nur vollständige Monate gezählt. Die Differenz zwischen dem 1. Februar und dem 28. Februar wird also von MonthsBetween ebenso wie die Differenz zwischen dem 1. Februar und dem 1. März als Null gemeldet.


[TP]Hawk274 - So 12.01.03 22:13

Jup, die Hilfe hatte ich bereits gelesen ... aber nicht den unteren Teil :oops:


Wolff68 - So 12.01.03 22:33

Also macht MonthsBetween nichs anderes als ein Simples (Ende-Start) DIV 30,4375 ??? :eyecrazy:
Was für ein Schwachsinn !!! :puke:

Also da würde ich dann doch lieber das ganze mit DecodeDate zerlegen und selber durchrechnen. (Und diese dummen DateUtils in Gulli kippen)