I have this code that only runs twice with the variables DateStart := 27-01-2013 DateStop := 31-03-2013
I think it should run with the results of 31-01-2013, 28-02-2013 and 31-3-2013 But I only get 2 results
I am quite sure I have been gazing to much and can't see the problem
begin
DateStart := EndOfTheMonth(DateStart);
while DateStart <= DateStop do
begin
FsFutureCreate(DateStart, cxDebit.Value, cxKredit.Value, aAccount, aType, aStore, aCity, txtText.Text, lRecord);
DateStart := EndOfTheMonth(IncMonth(DateStart));
end;
end;
Either FsFutureCreate (which you never told us what it is) has some side-effects, or you have some issue with floating-point fuzz. As you know, date and time values are doubles, and so comparisons like <= are dangerous. (Especially if you disregard the time part, as my analysis below shows.)
The second one is the more likely one. I just tried
procedure TForm1.FormCreate(Sender: TObject);
var d: TDate; d2: TDate;
begin
d := EncodeDate(2013, 01, 31);
d := IncMonth(d); // 2013-02-28
d := EndOfTheMonth(d); // 2013-02-28
d := IncMonth(d); // 2013-03-28
d := EndOfTheMonth(d); // 2013-03-31
d2 := EncodeDate(2013, 03, 31);
// d is now 2013-03-31 23:59:59
// d2 is now 2013-03-31 00:00:00
ShowMessage(BoolToStr(d <= d2, true));
end;
and got false, as one would expect. Hence, the problem, in this case, is that the EndOfTheMonth function also sets the time to the last second (or millisec) of the day. But even if this wasn't the case, doing comparisons using = is dangerous when it comes to floating-point values.
To fix your comparison, do
CompareDate(d, d2) <= 0
instead of
d <= d2.
I leave it as an exercise to find out, using the documentation, why this works and is robust.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With