TDateEdit: redefine NullDate, since it was actually impossible to select tha actual date 1899-12-30 in the control. Also check dates agains MinDateTime and MaxDateTime.

This commit is contained in:
Bart 2022-08-02 23:32:41 +02:00
parent 37fa159874
commit d0843ab78b

View File

@ -36,7 +36,11 @@ uses
Menus, StrUtils, DateUtils, TimePopup, CalcForm, ImgList, Math;
const
NullDate: TDateTime = 0;
NullDate: TDateTime = 29584650.5 {appr 10 x MaxDateTime};
//Note: if you change this value to be in the range of allowed dates
//you will be unable to select that date from the calendar, so better not do that
//In hindside this vale should have been declared as a non-writeable constant
NullTime: TDateTime = 0;
type
@ -602,6 +606,7 @@ type
procedure CalendarPopupShowHide(Sender: TObject);
procedure SetDateOrder(const AValue: TDateOrder);
function DateToText(Value: TDateTime): String;
function IsNullDate(ADate: TDateTime): Boolean;
protected
class procedure WSRegisterClass; override;
function GetDefaultGlyphName: string; override;
@ -1611,11 +1616,12 @@ begin
PopupOrigin := ControlToScreen(Point(0, Height));
ADate := GetDate;
if ADate = NullDate then
if IsNullDate(ADate) then
ADate := SysUtils.Date;
if IsLimited then
CheckRange(ADate, FMinDate, FMaxDate);
CheckRange(ADate, FMinDate, FMaxDate)
else
CheckRange(ADate, MinDateTime, MaxDateTime);
ShowCalendarPopup(PopupOrigin, ADate, CalendarDisplaySettings,
FMinDate, FMaxDate,
@CalendarPopupReturnDate, @CalendarPopupShowHide, self);
@ -1652,7 +1658,7 @@ begin
//Synchronize FDate
FDate := TextToDate(Text, NullDate);
//Force a valid date in the control, but not if Text was empty in designmode
if not ((csDesigning in ComponentState) and FDefaultToday and (FDate = NullDate)) then
if not ((csDesigning in ComponentState) and FDefaultToday and (IsNullDate(FDate))) then
SetDate(FDate);
end;
@ -1961,7 +1967,7 @@ begin
if not TryStrToDate(AText, Result, FS) then
begin
Result := ParseDateNoPredefinedOrder(AText, FS);
if (Result = NullDate) then Result := ADefault;
if IsNullDate(Result) then Result := ADefault;
end;
end
else
@ -1976,7 +1982,6 @@ begin
raise EInvalidDate.CreateFmt(rsDateTooSmall, [DateToStr(SysUtils.MinDateTime)]);
if (ADate > SysUtils.MaxDateTime) then
raise EInvalidDate.CreateFmt(rsDateTooLarge, [DateToStr(SysUtils.MaxDateTime)]);
if (ADate < AMinDate) or (ADate > AMaxDate) then
raise EInvalidDate.CreateFmt(rsInvalidDateRangeHint, [DateToStr(ADate),
DateToStr(AMinDate), DateToStr(AMaxDate)]);
@ -2032,7 +2037,7 @@ var
Def: TDateTime;
begin
//debugln(['TDateEdit.GetDate: FDate = ',DateToStr(FDate)]);
if (FDate = NullDate) and FDefaultToday then
if IsNullDate(FDate) and FDefaultToday then
Def := SysUtils.Date
else
Def := FDate;
@ -2061,15 +2066,20 @@ procedure TDateEdit.SetDate(Value: TDateTime);
begin
FUpdatingDate := True;
try
if {not IsValidDate(Value) or }(Value = NullDate) then
if IsNullDate(Value) then
begin
if DefaultToday then
Value := SysUtils.Date
else
Value := NullDate;
//else
// Value := NullDate;
end;
if not IsNullDate(Value) then
begin
if IsLimited then
CheckRange(Value, FMinDate, FMaxDate)
else
CheckRange(Value, MinDateTime, MaxDateTime);
end;
if IsLimited then
CheckRange(Value, FMinDate, FMaxDate);
FDate := Value;
Text := DateToText(FDate);
finally
@ -2112,7 +2122,7 @@ function TDateEdit.DateToText(Value: TDateTime): String;
var
FS: TFormatSettings;
begin
if Value = NullDate then
if IsNullDate(Value) then
Result := ''
else
begin
@ -2128,6 +2138,11 @@ begin
end;
end;
function TDateEdit.IsNullDate(ADate: TDateTime): Boolean;
begin
Result := (Trunc(ADate) = Trunc(NullDate));
end;
class procedure TDateEdit.WSRegisterClass;
begin
inherited WSRegisterClass;
@ -2176,7 +2191,7 @@ end;
procedure TTimeEdit.SetEmptyTime;
begin
Text := EmptyStr;
FTime := NullDate;
FTime := NullTime;
IsEmptyTime := True;
end;
@ -2211,7 +2226,7 @@ begin
ParseInput;
PopupOrigin := ControlToScreen(Point(0, Height));
ATime := GetTime;
if ATime = NullDate then
if ATime = NullTime then
ATime := SysUtils.Time;
ShowTimePopup(PopupOrigin, ATime, Self.DoubleBuffered,
@TimePopupReturnTime, @TimePopupShowHide, FSimpleLayout, self);