Browse Source

* Patch from Alex Rayne (bug ID 14622) to provide some overloaded versions of the strtodate/strtotime functions

git-svn-id: trunk@13864 -
michael 16 years ago
parent
commit
dadd6631ad
2 changed files with 289 additions and 60 deletions
  1. 250 52
      rtl/objpas/sysutils/dati.inc
  2. 39 8
      rtl/objpas/sysutils/datih.inc

+ 250 - 52
rtl/objpas/sysutils/dati.inc

@@ -326,7 +326,8 @@ end ;
     if S does not represent a valid date value
     an EConvertError will be raised   }
 
-function StrToDate(const S: string): TDateTime;
+function StrToDate(const S: PChar; Len : integer; const useformat : string; separator : char = #0): TDateTime;
+
 const SInvalidDateFormat = '"%s" is not a valid date format';
 var
    df:string;
@@ -343,7 +344,9 @@ begin
     Raise EConvertError.CreateFmt(SInvalidDateFormat,[s]);
 
   YearMoreThenTwoDigits := False;
-  df := UpperCase(ShortDateFormat);
+  if separator = #0 then
+        separator := DateSeparator;
+  df := UpperCase(useFormat);
   { Determine order of D,M,Y }
   yp:=0;
   mp:=0;
@@ -381,7 +384,8 @@ begin
     values[i] := 0;
   s1 := '';
   n := 0;
-  for i := 1 to length(s) do
+  dec(len);
+  for i := 0 to len do
    begin
      if s[i] in ['0'..'9'] then
       s1 := s1 + s[i];
@@ -389,10 +393,10 @@ begin
      { space can be part of the shortdateformat, and is defaultly in slovak
        windows, therefor it shouldn't be taken as separator (unless so specified)
        and ignored }
-     if (DateSeparator <> ' ') and (s[i] = ' ') then
+     if (Separator <> ' ') and (s[i] = ' ') then
        Continue;
 
-     if (s[i] = dateseparator) or ((i = length(s)) and (s[i] in ['0'..'9'])) then
+     if (s[i] = separator) or ((i = len) and (s[i] in ['0'..'9'])) then
       begin
         inc(n);
         if n>3 then
@@ -446,41 +450,82 @@ begin
   Result := EncodeDate(y, m, d);
 end ;
 
+function StrToDate(const S: ShortString; const useformat : string; separator : char = #0): TDateTime;
+begin
+    result := StrToDate(@S[1],Length(s),UseFormat,separator);
+end;
+
+function StrToDate(const S: AnsiString; const useformat : string; separator : char = #0): TDateTime;
+begin
+    result := StrToDate(@S[1],Length(s),UseFormat,separator);
+end;
+
+function StrToDate(const S: ShortString; separator : char): TDateTime;
+begin
+    result := StrToDate(@S[1],Length(s),ShortDateFormat,separator)
+end;
+
+function StrToDate(const S: ShortString): TDateTime;
+begin
+    result := StrToDate(@S[1],Length(s),ShortDateFormat,#0);
+end;
+
+function StrToDate(const S: AnsiString; separator : char): TDateTime;
+begin
+    result := StrToDate(@S[1],Length(s),ShortDateFormat,separator)
+end;
+
+function StrToDate(const S: AnsiString): TDateTime;
+begin
+    result := StrToDate(@S[1],Length(s),ShortDateFormat,#0);
+end;
 
 {   StrToTime converts the string S to a TDateTime value
     if S does not represent a valid time value an
     EConvertError will be raised   }
 
-function StrToTime(const s: string): TDateTime;
+function StrToTime(const S: PChar; Len : integer; separator : char = #0): TDateTime;
 var
-   Len, Current: integer; PM: integer;
+   Current: integer; PM: integer;
+
+    function StrPas(Src : PChar; len: integer = 0) : ShortString;
+    var
+       tmp : integer;
+    begin
+        {tmp := IndexChar(Src[0], len, #0);
+        len :=ifthen(tmp >= 0, tmp, len);
+        len :=ifthen(len > 255, 255, len);}
+        SetLength(Result, len);
+        move(src[0],result[1],len);
+    end;
 
    function GetElement: integer;
    var
      j, c: integer;
+     CurrentChar : Char;
    begin
    result := -1;
-   Inc(Current);
-   while (result = -1) and (Current <= Len) do
+   while (result = -1) and (Current < Len) do
      begin
-       if S[Current] in ['0'..'9'] then 
+       CurrentChar := S[Current];
+       if CurrentChar in ['0'..'9'] then
           begin
             j := Current;
-            while (Current < Len) and (s[Current + 1] in ['0'..'9']) do
+            while (Current+1 < Len) and (s[Current + 1] in ['0'..'9']) do
               Inc(Current);
-            val(copy(S, j, 1 + Current - j), result, c);
+            val(StrPas(S+j, 1 + current - j), result, c);
           end
-       else if ((TimeAMString<>'') and (S[Current] = TimeAMString[1])) or (S[Current] in ['a', 'A']) then 
+       else if ((TimeAMString<>'') and (CurrentChar = TimeAMString[1])) or (S[Current] in ['a', 'A']) then
           begin
             pm:=1;
             Current := 1 + Len;
           end
-       else if ((TimePMString<>'') and (S[Current] = TimePMString[1])) or (S[Current] in ['p', 'P']) then 
+       else if ((TimePMString<>'') and (CurrentChar = TimePMString[1])) or (S[Current] in ['p', 'P']) then
          begin
            Current := 1 + Len;
            PM := 2;
          end
-       else if (S[Current] = TimeSeparator) or (S[Current] = ' ') then
+      else if (CurrentChar = Separator) or (CurrentChar = ' ') then
          Inc(Current)
       else
         raise EConvertError.Create('Invalid Time format');
@@ -492,8 +537,9 @@ var
    TimeValues: array[0..4] of integer;
 
 begin
+  if separator = #0 then
+        separator := TimeSeparator;
   Current := 0;
-  Len := length(s);
   PM := 0;
   for i:=0 to 4 do
     timevalues[i]:=0;
@@ -502,6 +548,7 @@ begin
   while (i < 5) and (TimeValues[i] <> -1) do 
     begin
      i := i + 1;
+     Inc(Current);
      TimeValues[i] := GetElement;
    end ;
   If (i<5) and (TimeValues[I]=-1) then
@@ -519,40 +566,79 @@ begin
   result := EncodeTime(TimeValues[0], TimeValues[1], TimeValues[2], TimeValues[3]);
 end ;
 
+function StrToTime(const s: ShortString; separator : char): TDateTime;
+begin
+   result := StrToTime(@s[1], length(s), separator);
+end;
+
+function StrToTime(const s: AnsiString; separator : char): TDateTime;
+begin
+   result := StrToTime(@s[1], length(s), separator);
+end;
+
+function StrToTime(const s: ShortString): TDateTime;
+begin
+   result := StrToTime(@s[1], length(s), #0);
+end;
+
+function StrToTime(const s: AnsiString): TDateTime;
+begin
+   result := StrToTime(@s[1], length(s), #0);
+end;
+
 {   StrToDateTime converts the string S to a TDateTime value
     if S does not represent a valid date and/or time value
     an EConvertError will be raised   }
 
 function StrToDateTime(const s: string): TDateTime;
 var
-  i, j, k, l: integer;
-  sd, st: string;
-begin
-  l := Length(s);
-  i := 1;
-  while (i <= l) and (s[i] = ' ') do
-    Inc(i);
-  j := i;
-  while (j <= l) and (s[j] <> ' ') do
-    Inc(j);
-  k := j;
-  while (k <= l) and (s[k] = ' ') do
-    Inc(k);
-  sd := Copy(s, i, j - i);
-  st := Copy(s, k, l);
-  if (st = '') and (Pos(TimeSeparator, sd) > 0) then
-  begin
-    st := sd;
-    sd := '';
-  end;
-  if (sd <> '') and (st <> '') then
-    Result := ComposeDateTime(StrToDate(sd), StrToTime(st))
-  else if st = '' then
-    Result := StrToDate(sd)
-  else
-    Result := StrToTime(st);
+  i: integer;
+begin
+       i := Pos(' ',s);
+       if i > 0 then begin
+                result := ComposeDateTime(StrToDate(@S[1], i - 1, ShortDateFormat, DateSeparator)
+                                        , StrToTime(@S[i+1], Length(S)-i , TimeSeparator));
+       end
+       else if pos(TimeSeparator,s) > 0 then
+           result := StrToTime(s,TimeSeparator)
+       else
+           result := StrToDate(s,LongDateFormat, DateSeparator)
 end ;
 
+function StrToDateTime(const s: ShortString; const UseFormat : TFormatSettings): TDateTime;
+var
+  i : integer;
+begin
+   with useformat do begin
+       i := Pos(' ',s);
+       if i > 0 then begin
+                result := ComposeDateTime(StrToDate(@S[1], i - 1, ShortDateFormat, DateSeparator)
+                                        , StrToTime(@S[i+1], Length(S)-i , TimeSeparator));
+       end
+       else if pos(TimeSeparator,s) > 0 then
+           result := StrToTime(s,TimeSeparator)
+       else
+           result := StrToDate(s, ShortDateFormat, DateSeparator)
+   end;
+end;
+
+function StrToDateTime(const s: AnsiString; const UseFormat : TFormatSettings): TDateTime;
+var
+  i : integer;
+begin
+   with useformat do begin
+       i := Pos(' ',s);
+       if i > 0 then begin
+                result := ComposeDateTime(StrToDate(@S[1], i - 1, ShortDateFormat, DateSeparator)
+                                        , StrToTime(@S[i+1], Length(S)-i , TimeSeparator));
+       end
+       else if pos(TimeSeparator,s) > 0 then
+           result := StrToTime(s,TimeSeparator)
+       else
+           result := StrToDate(s,ShortDateFormat, DateSeparator)
+   end;
+end;
+
 {   FormatDateTime formats DateTime to the given format string FormatStr   }
 
 function FormatDateTime(FormatStr: string; DateTime: TDateTime): string;
@@ -819,11 +905,56 @@ end;
 {$endif unix}
 
 // ieuw. These should  be written to work without exceptions?
-function TryStrToDate(const S: string; out Value: TDateTime): Boolean;
+function TryStrToDate(const S: ShortString; out Value: TDateTime): Boolean;
+begin
+    result := TryStrToDate(S, Value, #0);
+end;
+
+function TryStrToDate(const S: ShortString; out Value: TDateTime; separator : char): Boolean;
+  begin
+    result:=true;
+    try
+      value:=StrToDate(s, separator);
+    except
+      on EConvertError do
+        result:=false
+    end;
+  end;
+
+function TryStrToDate(const S: ShortString; out Value: TDateTime;
+                    const useformat : string; separator : char = #0): Boolean;
   begin
     result:=true;
     try
-      value:=StrToDate(s);
+      value:=StrToDate(s, useformat, separator);
+    except
+      on EConvertError do
+        result:=false
+    end;
+  end;
+
+function TryStrToDate(const S: AnsiString; out Value: TDateTime): Boolean;
+begin
+    result := TryStrToDate(S, Value, #0);
+end;
+
+function TryStrToDate(const S: AnsiString; out Value: TDateTime; separator : char): Boolean;
+  begin
+    result:=true;
+    try
+      value:=StrToDate(s, separator);
+    except
+      on EConvertError do
+        result:=false
+    end;
+  end;
+
+function TryStrToDate(const S: AnsiString; out Value: TDateTime;
+                    const useformat : string; separator : char = #0): Boolean;
+  begin
+    result:=true;
+    try
+      value:=StrToDate(s, useformat, separator);
     except
       on EConvertError do
         result:=false
@@ -833,23 +964,42 @@ function TryStrToDate(const S: string; out Value: TDateTime): Boolean;
 
 // function TryStrToDate(const S: string; out Value: TDateTime; const FormatSettings: TFormatSettings): Boolean;
 
+function TryStrToTime(const S: ShortString; out Value: TDateTime; separator : char): Boolean;
+  begin
+    result:=true;
+    try
+      value:=StrToTime(s, separator);
+    except
+      on EConvertError do
+        result:=false
+    end;
+  end;
 
-function TryStrToTime(const S: string; out Value: TDateTime): Boolean;
+function TryStrToTime(const S: ShortString; out Value: TDateTime): Boolean;
+begin
+    result := TryStrToTime(S,Value,#0);
+end;
+
+function TryStrToTime(const S: AnsiString; out Value: TDateTime; separator : char): Boolean;
   begin
     result:=true;
     try
-      value:=StrToTime(s);
+      value:=StrToTime(s, separator);
     except
       on EConvertError do
         result:=false
     end;
   end;
 
+function TryStrToTime(const S: AnsiString; out Value: TDateTime): Boolean;
+begin
+    result := TryStrToTime(S,Value,#0);
+end;
 
 // function TryStrToTime(const S: string; out Value: TDateTime; const FormatSettings: TFormatSettings): Boolean;
 
 
-function TryStrToDateTime(const S: string; out Value: TDateTime): Boolean;
+function TryStrToDateTime(const S: ShortString; out Value: TDateTime): Boolean;
   begin
     result:=true;
     try
@@ -860,28 +1010,76 @@ function TryStrToDateTime(const S: string; out Value: TDateTime): Boolean;
     end;
   end;
 
+function TryStrToDateTime(const S: AnsiString; out Value: TDateTime): Boolean;
+  begin
+    result:=true;
+    try
+      value:=StrToDateTime(s);
+    except
+      on EConvertError do
+        result:=false
+    end;
+  end;
 
 // function TryStrToDateTime(const S: string; out Value: TDateTime; const FormatSettings: TFormatSettings): Boolean;
 
 
-function StrToDateDef(const S: string; const Defvalue : TDateTime): TDateTime;
+function StrToDateDef(const S: ShortString; const Defvalue : TDateTime): TDateTime;
+begin
+   result := StrToDateDef(S,DefValue,#0);
+end;
+
+function StrToTimeDef(const S: ShortString; const Defvalue : TDateTime): TDateTime;
+begin
+   result := StrToTimeDef(S,DefValue,#0);
+end;
+
+function StrToDateTimeDef(const S: ShortString; const Defvalue : TDateTime): TDateTime;
 begin
-  if not TryStrToDate(s,Result) Then
+  if not TryStrToDateTime(s,Result) Then
     result:=defvalue;
 end;
 
-function StrToTimeDef(const S: string; const Defvalue : TDateTime): TDateTime;
+function StrToDateDef(const S: ShortString; const Defvalue : TDateTime; separator : char): TDateTime;
 begin
-  if not TryStrToTime(s,Result) Then
+  if not TryStrToDate(s,Result, separator) Then
     result:=defvalue;
 end;
 
-function StrToDateTimeDef(const S: string; const Defvalue : TDateTime): TDateTime;
+function StrToTimeDef(const S: ShortString; const Defvalue : TDateTime; separator : char): TDateTime;
+begin
+  if not TryStrToTime(s,Result, separator) Then
+    result:=defvalue;
+end;
+
+function StrToDateDef(const S: AnsiString; const Defvalue : TDateTime): TDateTime;
+begin
+   result := StrToDateDef(S,DefValue,#0);
+end;
+
+function StrToTimeDef(const S: AnsiString; const Defvalue : TDateTime): TDateTime;
+begin
+   result := StrToTimeDef(S,DefValue,#0);
+end;
+
+function StrToDateTimeDef(const S: AnsiString; const Defvalue : TDateTime): TDateTime;
 begin
   if not TryStrToDateTime(s,Result) Then
     result:=defvalue;
 end;
 
+function StrToDateDef(const S: AnsiString; const Defvalue : TDateTime; separator : char): TDateTime;
+begin
+  if not TryStrToDate(s,Result, separator) Then
+    result:=defvalue;
+end;
+
+function StrToTimeDef(const S: AnsiString; const Defvalue : TDateTime; separator : char): TDateTime;
+begin
+  if not TryStrToTime(s,Result, separator) Then
+    result:=defvalue;
+end;
+
 procedure ReplaceTime(var dati:TDateTime; NewTime : TDateTime);inline;
 begin
   dati:= ComposeDateTime(dati, newtime);

+ 39 - 8
rtl/objpas/sysutils/datih.inc

@@ -124,24 +124,55 @@ function IsLeapYear(Year: Word): boolean;
 function DateToStr(Date: TDateTime): string;
 function TimeToStr(Time: TDateTime): string;
 function DateTimeToStr(DateTime: TDateTime): string;
-function StrToDate(const S: string): TDateTime;
-function StrToTime(const S: string): TDateTime;
+function StrToDate(const S: ShortString): TDateTime;                  {$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToDate(const S: Ansistring): TDateTime;                   {$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToDate(const S: ShortString; separator : char): TDateTime;{$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToDate(const S: AnsiString; separator : char): TDateTime; {$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToTime(const S: Shortstring): TDateTime;                  {$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToTime(const S: Ansistring): TDateTime;                   {$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToTime(const S: ShortString; separator : char): TDateTime;{$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToTime(const S: AnsiString; separator : char): TDateTime; {$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToDate(const S: ShortString; const useformat : string; separator : char): TDateTime;{$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToDate(const S: AnsiString; const useformat : string; separator : char): TDateTime;{$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToTime(const S: PChar; Len : integer; separator : char = #0): TDateTime;
+function StrToDate(const S: PChar; Len : integer; const useformat : string; separator : char = #0): TDateTime;
 function StrToDateTime(const S: string): TDateTime;
+function StrToDateTime(const s: ShortString; const UseFormat : TFormatSettings): TDateTime;
+function StrToDateTime(const s: AnsiString; const UseFormat : TFormatSettings): TDateTime;
 function FormatDateTime(FormatStr: string; DateTime: TDateTime):string;
 procedure DateTimeToString(out Result: string; const FormatStr: string; const DateTime: TDateTime);
 Function DateTimeToFileDate(DateTime : TDateTime) : Longint;
 Function FileDateToDateTime (Filedate : Longint) :TDateTime;
-function TryStrToDate(const S: string; out Value: TDateTime): Boolean;
-function TryStrToTime(const S: string; out Value: TDateTime): Boolean;
-function TryStrToDateTime(const S: string; out Value: TDateTime): Boolean;
+function TryStrToDate(const S: ShortString; out Value: TDateTime): Boolean;                         {$ifdef SYSUTILSINLINE}inline;{$endif}
+function TryStrToDate(const S: AnsiString; out Value: TDateTime): Boolean;                         {$ifdef SYSUTILSINLINE}inline;{$endif}
+function TryStrToDate(const S: ShortString; out Value: TDateTime; separator : char): Boolean;
+function TryStrToDate(const S: AnsiString; out Value: TDateTime; separator : char): Boolean;
+function TryStrToTime(const S: ShortString; out Value: TDateTime): Boolean;                         {$ifdef SYSUTILSINLINE}inline;{$endif}
+function TryStrToTime(const S: AnsiString; out Value: TDateTime): Boolean;                         {$ifdef SYSUTILSINLINE}inline;{$endif}
+function TryStrToTime(const S: ShortString; out Value: TDateTime; separator : char): Boolean;
+function TryStrToTime(const S: AnsiString; out Value: TDateTime; separator : char): Boolean;
+function TryStrToDate(const S: ShortString; out Value: TDateTime;
+                        const useformat : string; separator : char = #0): Boolean;
+function TryStrToDate(const S: AnsiString; out Value: TDateTime;
+                        const useformat : string; separator : char = #0): Boolean;
+function TryStrToDateTime(const S: ShortString; out Value: TDateTime): Boolean;
+function TryStrToDateTime(const S: AnsiString; out Value: TDateTime): Boolean;
 
 // function TryStrToDate(const S: string; out Value: TDateTime; const FormatSettings: TFormatSettings): Boolean;
 // function TryStrToTime(const S: string; out Value: TDateTime; const FormatSettings: TFormatSettings): Boolean;
 // function TryStrToDateTime(const S: string; out Value: TDateTime; const FormatSettings: TFormatSettings): Boolean;
 
-function StrToDateDef(const S: string; const Defvalue : TDateTime): TDateTime;
-function StrToTimeDef(const S: string; const Defvalue : TDateTime): TDateTime;
-function StrToDateTimeDef(const S: string; const Defvalue : TDateTime): TDateTime;
+function StrToDateDef(const S: ShortString; const Defvalue : TDateTime): TDateTime;                   {$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToDateDef(const S: ShortString; const Defvalue : TDateTime; separator : char): TDateTime; {$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToTimeDef(const S: ShortString; const Defvalue : TDateTime): TDateTime;                   {$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToTimeDef(const S: ShortString; const Defvalue : TDateTime; separator : char): TDateTime; {$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToDateTimeDef(const S: ShortString; const Defvalue : TDateTime): TDateTime;               {$ifdef SYSUTILSINLINE}inline;{$endif}
+
+function StrToDateDef(const S: AnsiString; const Defvalue : TDateTime): TDateTime;                   {$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToDateDef(const S: AnsiString; const Defvalue : TDateTime; separator : char): TDateTime; {$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToTimeDef(const S: AnsiString; const Defvalue : TDateTime): TDateTime;                   {$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToTimeDef(const S: AnsiString; const Defvalue : TDateTime; separator : char): TDateTime; {$ifdef SYSUTILSINLINE}inline;{$endif}
+function StrToDateTimeDef(const S: AnsiString; const Defvalue : TDateTime): TDateTime;               {$ifdef SYSUTILSINLINE}inline;{$endif}
 
 function CurrentYear:Word;
 { FPC Extra }