Components like TDateTimePicker and similar that are designed specifically for entering dates or times are useful when we want some visual representation of a date. However, why bother with visual components that are 'not-so-input-friendly when everything we want is just one Edit box to type the date into.
In this article you will find one great function designed to make date processing a bit faster.
Date Manipulation
The following DateComplete function is used to auto complete the given string value to a date representation.The whole idea is to allow our users to only start typing the date and to finish it from code when appropriate (in most cases in the OnExit event of some edit-enabled control.)
For example, if the default Windows short date format is 'dd.mm.yyyy' then assigning '29' to the StrLikeDate variable will, after calling the DateComplete procedure, result in '29.01.2006'. Of course, this is all true if the current month and year are January, 2006.
procedure DateComplete(var StrLikeDate : string; const NowIfError:boolean = True) ;
var
DateStr : string;
Year, Month, Day : Word;
cnt, SepCount : Integer;
begin
DateStr:=StrLikeDate;
if DateStr = '' then Exit;
SepCount := 0;
for cnt := 1 to Length(DateStr) do
begin
if not (DateStr[cnt] in ['0'..'9']) then
begin
DateStr[cnt] := DateSeparator;
inc(SepCount) ;
end;
end;
while (DateStr <> '') and (DateStr[Length(DateStr)]=DateSeparator) do
begin
Delete(DateStr, Length(DateStr), 1) ;
Dec(SepCount) ;
end;
DecodeDate(Now, Year, Month, Day) ;
if SepCount = 0 then
begin
case Length(DateStr) of
0 : DateStr := DateToStr(Now) ;
1, 2 : DateStr := DateStr+DateSeparator+IntToStr(Month) ;
4 : Insert(DateSeparator, DateStr, 3) ;
6, 8 : begin
Insert(DateSeparator, DateStr, 5) ;
Insert(DateSeparator, DateStr, 3) ;
end;
end; {case}
end; {if SepCount}
try
StrLikeDate := DateToStr(StrToDate(DateStr)) ;
except
if NowIfError = true then
StrLikeDate := DateToStr(Date)
else
StrLikeDate := '';
end;
end;
The DateComplete Procedure
As we can see from the procedure header:procedure DateComplete(var StrLikeDate : string; const NowIfError:boolean = True) ;The DateComplete takes the StrLikeDate string parameter by reference using the var keyword, meaning that DateComplete function is able to alter the value in StrLikeDate. The second parameter (optional, defaults to True) NowIfError is used in the exception handler part to check for bad date (for example: letters in StrLikeDate). If NowIfError is True (default if omitted) and there is an error while trying to convert the StrLikeDate value to date representation, the value of StrLikeDate will become the current date (Now), otherwise (NowIfError = False) the StrLikeDate will be returned as an empty string ('').
With the previous discussion in our mind, the DateComplete function can be called as:
procedure TForm1.edDateExit(Sender: TObject) ;Note: The DateComplete procedure will alter the StrLikeDate value to a date format 'dd.mm.yyyy', where date separator '.' is stored in the global variable DateSeparator (Delphi reads this value from the Regional Settings in the Control Panel).
var
s : string;
begin
s := edDate.Text;
DateComplete(s, True) ; {or DateComplete(s)}
edDate.Text := s;
end;
mm/dd/yyyy ?
If you (your users) are not using the 'dd.mm.yyyy' but 'mm/dd/yyyy' date format then DateComplete needs some modification to work properly. Take a look at the next line:
case Length(DateStr) ofThis piece of code handles the situation when only one or two digits are entered - only day (remember: 'dd.mm.yyyy'). DateStr becomes DateStr + Month (current).
...
1, 2 : DateStr:=DateStr + DateSeparator + IntToStr(Month) ;
...
If you are working with 'mm/dd/yyyy' short date format, simply change the previous code to:
case Length(DateStr) ofThat's it.
...
1, 2 : DateStr:=DateStr + DateSeparator + IntToStr(Day) ;
...


