codetools: DateToCfgStr extended for time

git-svn-id: trunk@47623 -
This commit is contained in:
mattias 2015-02-07 11:59:48 +00:00
parent 64a4059bf0
commit 0d19bf6dd6
2 changed files with 115 additions and 19 deletions

View File

@ -236,9 +236,11 @@ function FindNextDelimitedItem(const List: string; Delimiter: char;
var Position: integer; FindItem: string): string; inline;
function AVLTreeHasDoubles(Tree: TAVLTree): TAVLTreeNode;
// store date locale independent, thread safe
const DateAsCfgStrFormat='YYYYMMDD';
function DateToCfgStr(const Date: TDateTime): string;
function CfgStrToDate(const s: string; out Date: TDateTime): boolean;
const DateTimeAsCfgStrFormat='YYYY/MM/DD HH:NN:SS';
function DateToCfgStr(const Date: TDateTime; const aFormat: string = DateAsCfgStrFormat): string;
function CfgStrToDate(const s: string; out Date: TDateTime; const aFormat: string = DateAsCfgStrFormat): boolean;
function SimpleFormat(const Fmt: String; const Args: Array of const): String;
@ -1855,39 +1857,103 @@ begin
end;
end;
function DateToCfgStr(const Date: TDateTime): string;
function DateToCfgStr(const Date: TDateTime; const aFormat: string): string;
var
NeedDate: Boolean;
NeedTime: Boolean;
Year: word;
Month: word;
Day: word;
Hour: word;
Minute: word;
Second: word;
MilliSecond: word;
p: Integer;
w: Word;
StartP: Integer;
s: String;
l: Integer;
begin
try
Result:=FormatDateTime(DateAsCfgStrFormat,Date);
except
Result:='';
Result:=aFormat;
NeedDate:=false;
NeedTime:=false;
for p:=1 to length(aFormat) do
case aFormat[p] of
'Y','M','D': NeedDate:=true;
'H','N','S','Z': NeedTime:=true;
end;
if NeedDate then
DecodeDate(Trunc(Date),Year,Month,Day);
if NeedTime then
DecodeTime(Frac(Date),Hour,Minute,Second,MilliSecond);
p:=1;
while p<=length(aFormat) do begin
case aFormat[p] of
'Y': w:=Year;
'M': w:=Month;
'D': w:=Day;
'H': w:=Hour;
'N': w:=Minute;
'S': w:=Second;
'Z': w:=MilliSecond;
else
inc(p);
continue;
end;
StartP:=p;
repeat
inc(p);
until (p>length(aFormat)) or (aFormat[p]<>aFormat[p-1]);
l:=p-StartP;
s:=IntToStr(w);
if length(s)<l then
s:=StringOfChar('0',l-length(s))+s
else if length(s)>l then
raise Exception.Create('date format does not fit');
ReplaceSubstring(Result,StartP,l,s);
p:=StartP+length(s);
end;
//debugln('DateToCfgStr "',Result,'"');
end;
function CfgStrToDate(const s: string; out Date: TDateTime): boolean;
function CfgStrToDate(const s: string; out Date: TDateTime;
const aFormat: string): boolean;
procedure AddDecimal(var d: word; c: char); inline;
begin
d:=d*10+ord(c)-ord('0');
end;
var
i: Integer;
Year, Month, Day: word;
Year, Month, Day, Hour, Minute, Second, MilliSecond: word;
begin
//debugln('CfgStrToDate "',s,'"');
Result:=true;
if length(s)<>length(DateAsCfgStrFormat) then begin
Result:=false;
exit;
if length(s)<>length(aFormat) then begin
Date:=0.0;
exit(false);
end;
try
Year:=0;
Month:=0;
Day:=0;
for i:=1 to length(DateAsCfgStrFormat) do begin
case DateAsCfgStrFormat[i] of
'Y': Year:=Year*10+ord(s[i])-ord('0');
'M': Month:=Month*10+ord(s[i])-ord('0');
'D': Day:=Day*10+ord(s[i])-ord('0');
Hour:=0;
Minute:=0;
Second:=0;
MilliSecond:=0;
for i:=1 to length(aFormat) do begin
case aFormat[i] of
'Y': AddDecimal(Year,s[i]);
'M': AddDecimal(Month,s[i]);
'D': AddDecimal(Day,s[i]);
'H': AddDecimal(Hour,s[i]);
'N': AddDecimal(Minute,s[i]);
'S': AddDecimal(Second,s[i]);
'Z': AddDecimal(MilliSecond,s[i]);
end;
end;
Date:=EncodeDate(Year,Month,Day);
Date:=ComposeDateTime(EncodeDate(Year,Month,Day),EncodeTime(Hour,Minute,Second,MilliSecond));
Result:=true;
except
Result:=false;
end;

View File

@ -9,6 +9,7 @@
./runtests --format=plain --suite=TestGuessIndentSize
./runtests --format=plain --suite=TestReindent
./runtests --format=plain --suite=TestSimpleFormat
./runtests --format=plain --suite=TestDateToCfgStr
}
unit TestBasicCodetools;
@ -33,6 +34,7 @@ type
procedure TestGuessIndentSize;
procedure TestReIndent;
procedure TestSimpleFormat;
procedure TestDateToCfgStr;
end;
implementation
@ -240,6 +242,34 @@ begin
t('A%1:s%0:sB',['Foo','Bar'],'ABarFooB');
end;
procedure TTestBasicCodeTools.TestDateToCfgStr;
procedure t(const Date: TDateTime; const aFormat, Expected: string);
var
Actual: String;
ActualDate: TDateTime;
begin
Actual:=DateToCfgStr(Date,aFormat);
if Actual<>Expected then begin
writeln(dbgsDiff(Expected,Actual));
AssertEquals('DateToCfgStr failed: Format="'+aFormat+'"',Expected,Actual);
exit;
end;
if (not CfgStrToDate(Actual,ActualDate,aFormat)) then begin
AssertEquals('CfgStrToDate failed: Format="'+aFormat+'" Cfg="'+Actual+'"',false,true);
exit;
end;
if ActualDate<>Date then begin
AssertEquals('CfgStrToDate failed: Format="'+aFormat+'"',DateTimeToStr(ActualDate),DateTimeToStr(Date));
end;
end;
begin
t(EncodeDate(1234,12,17),DateAsCfgStrFormat,'12341217');
t(EncodeDate(1234,1,2),DateAsCfgStrFormat,'12340102');
t(ComposeDateTime(EncodeDate(1234,1,2),EncodeTime(3,4,5,6)),DateTimeAsCfgStrFormat,'1234/01/02 03:04:05');
end;
initialization
AddToCodetoolsTestSuite(TTestBasicCodeTools);