My sample to "COUNTDOWN" between 2 TDateTime values:
the "countdown" to hh:mm:ss it's ok!
I not certain about the values is correct to: years, months and days
needs more Math for this...
source code
implementation
{$R *.dfm}
uses
System.DateUtils;
var
lDTFuture: TDateTime;
lDTnow : TDateTime;
//
lMyFS: TFormatSettings;
procedure TForm2.Button1Click(Sender: TObject);
begin
lMyFS := TFormatSettings.Create; // dont needs "Free it"
lMyFS.LongTimeFormat := 'hh:mm:ss.zzz'; // defining new format for "LongTimeFormat" values when showing it! pass it as "last" param for funtions!
//
lDTFuture := StrToDateTimeDef('31/12/2020 00:00:00.000', now, lMyFS); // avoid "AV"
lDTnow := StrToDateTimeDef('30/12/2019 23:59:50.000', now, lMyFS); // avoid "AV"
//
Timer1.Enabled := true;
end;
procedure TForm2.Timer1Timer(Sender: TObject);
var
lYears : word;
lMonths : word;
lDays : word;
lHours : word;
lMinutes: word;
lSeconds: word;
begin
if (lDTFuture <= lDTnow) then
begin
Timer1.Enabled := false;
//
ShowMessage('The time-is-out...');
//
exit;
end;
//
Edit2.Text := DateTimeToStr(lDTnow, lMyFS);
Edit3.Text := DateTimeToStr(lDTFuture, lMyFS);
//
// the big problem here with many calculate necessary to verify the values valids: 31days-1 ... = month-1 ... 12month-1 = years-1 etc... verify 28,29,30,31 days
// then my minimalisct code was not enought
lYears := System.DateUtils.YearsBetween(lDTFuture, lDTnow) mod 1000;
lMonths := System.DateUtils.MonthsBetween(lDTFuture, lDTnow) mod 12;
lDays := System.DateUtils.DaysBetween(lDTFuture, lDTnow) mod DaysPerYear[System.DateUtils.IsInLeapYear(lDTnow)];
//
// here the "countdown" works as expected!
lHours := System.DateUtils.HoursBetween(lDTFuture, lDTnow) mod 24;
lMinutes := System.DateUtils.MinutesBetween(lDTFuture, lDTnow) mod 60;
lSeconds := System.DateUtils.SecondsBetween(lDTFuture, lDTnow) mod 60;
//
Edit1.Text := Format('%d years, %d months, %d days, %d hours, %d minutes, %d seconds', [lYears, lMonths, lDays, lHours, lMinutes, lSeconds]);
//
lDTnow := lDTnow + 0.00001; // would be better use "NOW" as current value! // IncSeconds() or MilliSeconds
end;
hug