Browse Source

--- Merging r13864 into '.':
U rtl/objpas/sysutils/dati.inc
U rtl/objpas/sysutils/datih.inc
--- Merging r13865 into '.':
G rtl/objpas/sysutils/dati.inc
--- Merging r13871 into '.':
U rtl/objpas/sysconst.pp
--- Merging r13888 into '.':
G rtl/objpas/sysutils/dati.inc
--- Merging r13920 into '.':
U rtl/objpas/dateutil.inc
--- Merging r13928 into '.':
G rtl/objpas/sysutils/dati.inc
--- Merging r13949 into '.':
G rtl/objpas/dateutil.inc
--- Merging r13954 into '.':
G rtl/objpas/dateutil.inc
--- Merging r13959 into '.':
G rtl/objpas/sysutils/dati.inc
--- Merging r14018 into '.':
G rtl/objpas/sysutils/dati.inc
G rtl/objpas/sysutils/datih.inc

# revisions: 13864,13865,13871,13888,13920,13928,13949,13954,13959,14018
------------------------------------------------------------------------
r13864 | michael | 2009-10-16 10:16:55 +0200 (Fri, 16 Oct 2009) | 1 line
Changed paths:
M /trunk/rtl/objpas/sysutils/dati.inc
M /trunk/rtl/objpas/sysutils/datih.inc

* Patch from Alex Rayne (bug ID 14622) to provide some overloaded versions of the strtodate/strtotime functions
------------------------------------------------------------------------
------------------------------------------------------------------------
r13865 | michael | 2009-10-16 11:31:09 +0200 (Fri, 16 Oct 2009) | 1 line
Changed paths:
M /trunk/rtl/objpas/sysutils/dati.inc

* TryStrToTime/TryStrToDate no longer need to catch exceptions
------------------------------------------------------------------------
------------------------------------------------------------------------
r13871 | michael | 2009-10-16 17:31:25 +0200 (Fri, 16 Oct 2009) | 1 line
Changed paths:
M /trunk/rtl/objpas/sysconst.pp

* Forgot to commit
------------------------------------------------------------------------
------------------------------------------------------------------------
r13888 | michael | 2009-10-17 13:18:16 +0200 (Sat, 17 Oct 2009) | 1 line
Changed paths:
M /trunk/rtl/objpas/sysutils/dati.inc

* Correctly split date/time parts when dateseparator is a space
------------------------------------------------------------------------
------------------------------------------------------------------------
r13920 | ivost | 2009-10-22 23:26:24 +0200 (Thu, 22 Oct 2009) | 2 lines
Changed paths:
M /trunk/rtl/objpas/dateutil.inc

* changed output parameters from var to out. This suppress some unnecessary hints and it's also done in datih.inc

------------------------------------------------------------------------
------------------------------------------------------------------------
r13928 | michael | 2009-10-23 12:24:24 +0200 (Fri, 23 Oct 2009) | 1 line
Changed paths:
M /trunk/rtl/objpas/sysutils/dati.inc

* Forgot raise statement in strtodate (thanks to Denis Golovan)
------------------------------------------------------------------------
------------------------------------------------------------------------
r13949 | ivost | 2009-10-24 22:53:00 +0200 (Sat, 24 Oct 2009) | 2 lines
Changed paths:
M /trunk/rtl/objpas/dateutil.inc

* fixed CompareDate function. Only dates are compared now, ignoring time of day.

------------------------------------------------------------------------
------------------------------------------------------------------------
r13954 | ivost | 2009-10-25 12:06:38 +0100 (Sun, 25 Oct 2009) | 2 lines
Changed paths:
M /trunk/rtl/objpas/dateutil.inc

* reverted r13949 because it's unnecessary test

------------------------------------------------------------------------
------------------------------------------------------------------------
r13959 | ivost | 2009-10-26 18:34:07 +0100 (Mon, 26 Oct 2009) | 2 lines
Changed paths:
M /trunk/rtl/objpas/sysutils/dati.inc

* parameter "Separator" of function TryStrToDate was not passed to IntStrToDate

------------------------------------------------------------------------
------------------------------------------------------------------------
r14018 | marco | 2009-11-03 22:20:10 +0100 (Tue, 03 Nov 2009) | 2 lines
Changed paths:
M /trunk/rtl/objpas/sysutils/dati.inc
M /trunk/rtl/objpas/sysutils/datih.inc

* trystrto* variants with formatsettings.

------------------------------------------------------------------------

git-svn-id: branches/fixes_2_4@14685 -

marco 15 years ago
parent
commit
19c13567ab
4 changed files with 440 additions and 123 deletions
  1. 33 33
      rtl/objpas/dateutil.inc
  2. 2 0
      rtl/objpas/sysconst.pp
  3. 361 77
      rtl/objpas/sysutils/dati.inc
  4. 44 13
      rtl/objpas/sysutils/datih.inc

+ 33 - 33
rtl/objpas/dateutil.inc

@@ -174,7 +174,7 @@ Function EndOfADay(const AYear, ADayOfYear: Word): TDateTime; overload;
 
 Function MonthOfTheYear(const AValue: TDateTime): Word;
 Function WeekOfTheYear(const AValue: TDateTime): Word; overload;
-Function WeekOfTheYear(const AValue: TDateTime; var AYear: Word): Word; overload;
+Function WeekOfTheYear(const AValue: TDateTime; out AYear: Word): Word; overload;
 Function DayOfTheYear(const AValue: TDateTime): Word;
 Function HourOfTheYear(const AValue: TDateTime): Word;
 Function MinuteOfTheYear(const AValue: TDateTime): LongWord;
@@ -186,7 +186,7 @@ Function MilliSecondOfTheYear(const AValue: TDateTime): Int64;
   ---------------------------------------------------------------------}
 
 Function WeekOfTheMonth(const AValue: TDateTime): Word; overload;
-Function WeekOfTheMonth(const AValue: TDateTime; var AYear, AMonth: Word): Word; overload;
+Function WeekOfTheMonth(const AValue: TDateTime; out AYear, AMonth: Word): Word; overload;
 Function DayOfTheMonth(const AValue: TDateTime): Word;
 Function HourOfTheMonth(const AValue: TDateTime): Word;
 Function MinuteOfTheMonth(const AValue: TDateTime): Word;
@@ -300,8 +300,8 @@ Function IncMilliSecond(const AValue: TDateTime): TDateTime; // ; const ANumberO
   ---------------------------------------------------------------------}
 
 Function EncodeDateTime(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word): TDateTime;
-Procedure DecodeDateTime(const AValue: TDateTime; var AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word);
-Function TryEncodeDateTime(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word; var AValue: TDateTime): Boolean;
+Procedure DecodeDateTime(const AValue: TDateTime; out AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word);
+Function TryEncodeDateTime(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word; out AValue: TDateTime): Boolean;
 
 { ---------------------------------------------------------------------
     Encode/decode date, specifying week of year and day of week
@@ -309,25 +309,25 @@ Function TryEncodeDateTime(const AYear, AMonth, ADay, AHour, AMinute, ASecond, A
 
 Function EncodeDateWeek(const AYear, AWeekOfYear: Word; const ADayOfWeek: Word): TDateTime;
 Function EncodeDateWeek(const AYear, AWeekOfYear: Word): TDateTime; //; const ADayOfWeek: Word = 1
-Procedure DecodeDateWeek(const AValue: TDateTime; var AYear, AWeekOfYear, ADayOfWeek: Word);
-Function TryEncodeDateWeek(const AYear, AWeekOfYear: Word; var AValue: TDateTime; const ADayOfWeek: Word): Boolean;
-Function TryEncodeDateWeek(const AYear, AWeekOfYear: Word; var AValue: TDateTime): Boolean; //; const ADayOfWeek: Word = 1
+Procedure DecodeDateWeek(const AValue: TDateTime; out AYear, AWeekOfYear, ADayOfWeek: Word);
+Function TryEncodeDateWeek(const AYear, AWeekOfYear: Word; out AValue: TDateTime; const ADayOfWeek: Word): Boolean;
+Function TryEncodeDateWeek(const AYear, AWeekOfYear: Word; out AValue: TDateTime): Boolean; //; const ADayOfWeek: Word = 1
 
 { ---------------------------------------------------------------------
     Encode/decode date, specifying day of year
   ---------------------------------------------------------------------}
 
 Function EncodeDateDay(const AYear, ADayOfYear: Word): TDateTime;
-Procedure DecodeDateDay(const AValue: TDateTime; var AYear, ADayOfYear: Word);
-Function TryEncodeDateDay(const AYear, ADayOfYear: Word; var AValue: TDateTime): Boolean;
+Procedure DecodeDateDay(const AValue: TDateTime; out AYear, ADayOfYear: Word);
+Function TryEncodeDateDay(const AYear, ADayOfYear: Word; out AValue: TDateTime): Boolean;
 
 { ---------------------------------------------------------------------
     Encode/decode date, specifying week of month
   ---------------------------------------------------------------------}
 
 Function EncodeDateMonthWeek(const AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word): TDateTime;
-Procedure DecodeDateMonthWeek(const AValue: TDateTime; var AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word);
-Function TryEncodeDateMonthWeek(const AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word; var AValue: TDateTime): Boolean;
+Procedure DecodeDateMonthWeek(const AValue: TDateTime; out AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word);
+Function TryEncodeDateMonthWeek(const AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word; out AValue: TDateTime): Boolean;
 
 { ---------------------------------------------------------------------
     Replace given element with supplied value.
@@ -343,7 +343,7 @@ Function RecodeMilliSecond(const AValue: TDateTime; const AMilliSecond: Word): T
 Function RecodeDate(const AValue: TDateTime; const AYear, AMonth, ADay: Word): TDateTime;
 Function RecodeTime(const AValue: TDateTime; const AHour, AMinute, ASecond, AMilliSecond: Word): TDateTime;
 Function RecodeDateTime(const AValue: TDateTime; const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word): TDateTime;
-Function TryRecodeDateTime(const AValue: TDateTime; const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word; var AResult: TDateTime): Boolean;
+Function TryRecodeDateTime(const AValue: TDateTime; const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word; out AResult: TDateTime): Boolean;
 
 { ---------------------------------------------------------------------
     Comparision of date/time
@@ -364,10 +364,10 @@ Function SameTime(const A, B: TDateTime): Boolean;
 
 Function NthDayOfWeek(const AValue: TDateTime): Word;
 
-Procedure DecodeDayOfWeekInMonth(const AValue: TDateTime; var AYear, AMonth, ANthDayOfWeek, ADayOfWeek: Word);
+Procedure DecodeDayOfWeekInMonth(const AValue: TDateTime; out AYear, AMonth, ANthDayOfWeek, ADayOfWeek: Word);
 
 Function EncodeDayOfWeekInMonth(const AYear, AMonth, ANthDayOfWeek,  ADayOfWeek: Word): TDateTime;
-Function TryEncodeDayOfWeekInMonth(const AYear, AMonth, ANthDayOfWeek,  ADayOfWeek: Word; var AValue: TDateTime): Boolean;
+Function TryEncodeDayOfWeekInMonth(const AYear, AMonth, ANthDayOfWeek,  ADayOfWeek: Word; out AValue: TDateTime): Boolean;
 
 { ---------------------------------------------------------------------
     Exception throwing routines
@@ -386,11 +386,11 @@ Procedure InvalidDayOfWeekInMonthError(const AYear, AMonth, ANthDayOfWeek,  ADay
 
 Function DateTimeToJulianDate(const AValue: TDateTime): Double;
 Function JulianDateToDateTime(const AValue: Double): TDateTime;
-Function TryJulianDateToDateTime(const AValue: Double; var ADateTime: TDateTime): Boolean;
+Function TryJulianDateToDateTime(const AValue: Double; out ADateTime: TDateTime): Boolean;
 
 Function DateTimeToModifiedJulianDate(const AValue: TDateTime): Double;
 Function ModifiedJulianDateToDateTime(const AValue: Double): TDateTime;
-Function TryModifiedJulianDateToDateTime(const AValue: Double; var ADateTime: TDateTime): Boolean;
+Function TryModifiedJulianDateToDateTime(const AValue: Double; out ADateTime: TDateTime): Boolean;
 
 { ---------------------------------------------------------------------
     Unix timestamp support.
@@ -917,7 +917,7 @@ begin
 end;
 
 
-Function WeekOfTheYear(const AValue: TDateTime; var AYear: Word): Word;
+Function WeekOfTheYear(const AValue: TDateTime; out AYear: Word): Word;
 
 Var
   DOW : Word;
@@ -992,7 +992,7 @@ begin
 end;
 
 
-Function WeekOfTheMonth(const AValue: TDateTime; var AYear, AMonth: Word): Word;
+Function WeekOfTheMonth(const AValue: TDateTime; out AYear, AMonth: Word): Word;
 
 Var
   DOW : Word;
@@ -1410,7 +1410,7 @@ end;
     Increment/decrement functions.
   ---------------------------------------------------------------------}
 
-Procedure MaybeSkipTimeWarp(OldDate: TDateTime; var NewDate: TDateTime);
+Procedure MaybeSkipTimeWarp(OldDate: TDateTime; out NewDate: TDateTime);
 begin
   if (OldDate>0) and (NewDate<0) then
     NewDate:=NewDate-0.5
@@ -1528,14 +1528,14 @@ begin
 end;
 
 
-Procedure DecodeDateTime(const AValue: TDateTime; var AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word);
+Procedure DecodeDateTime(const AValue: TDateTime; out AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word);
 begin
   DecodeDate(AValue,AYear,AMonth,ADay);
   DecodeTime(AValue,AHour,AMinute,ASecond,AMilliSecond);
 end;
 
 
-Function TryEncodeDateTime(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word; var AValue: TDateTime): Boolean;
+Function TryEncodeDateTime(const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word; out AValue: TDateTime): Boolean;
 
 Var
  tmp : TDateTime;
@@ -1564,7 +1564,7 @@ begin
 end;
 
 
-Procedure DecodeDateWeek(const AValue: TDateTime; var AYear, AWeekOfYear, ADayOfWeek: Word);
+Procedure DecodeDateWeek(const AValue: TDateTime; out AYear, AWeekOfYear, ADayOfWeek: Word);
 
 var
   DOY : Integer;
@@ -1614,7 +1614,7 @@ end;
 
 
 
-Function TryEncodeDateWeek(const AYear, AWeekOfYear: Word; var AValue: TDateTime; const ADayOfWeek: Word): Boolean;
+Function TryEncodeDateWeek(const AYear, AWeekOfYear: Word; out AValue: TDateTime; const ADayOfWeek: Word): Boolean;
 
 Var
   DOW : Word;
@@ -1634,7 +1634,7 @@ begin
 end;
 
 
-Function TryEncodeDateWeek(const AYear, AWeekOfYear: Word; var AValue: TDateTime): Boolean; //; const ADayOfWeek: Word = 1
+Function TryEncodeDateWeek(const AYear, AWeekOfYear: Word; out AValue: TDateTime): Boolean; //; const ADayOfWeek: Word = 1
 begin
   Result:=TryEncodeDateWeek(AYear,AWeekOfYear,AValue,1);
 end;
@@ -1650,7 +1650,7 @@ begin
 end;
 
 
-Procedure DecodeDateDay(const AValue: TDateTime; var AYear, ADayOfYear: Word);
+Procedure DecodeDateDay(const AValue: TDateTime; out AYear, ADayOfYear: Word);
 
 Var
   M,D : Word;
@@ -1661,7 +1661,7 @@ begin
 end;
 
 
-Function TryEncodeDateDay(const AYear, ADayOfYear: Word; var AValue: TDateTime): Boolean;
+Function TryEncodeDateDay(const AYear, ADayOfYear: Word; out AValue: TDateTime): Boolean;
 begin
   Result:=(ADayOfYear<>0) and (ADayOfYear<=DaysPerYear [IsleapYear(AYear)]);
   If Result then
@@ -1680,7 +1680,7 @@ begin
     InvalidDateMonthWeekError(AYear,AMonth,AWeekOfMonth,ADayOfWeek);
 end;
 
-Procedure DecodeDateMonthWeek(const AValue: TDateTime; var AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word);
+Procedure DecodeDateMonthWeek(const AValue: TDateTime; out AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word);
 
 Var
   D,SDOM,EDOM : Word;
@@ -1715,7 +1715,7 @@ begin
     end;
 end;
 
-Function TryEncodeDateMonthWeek(const AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word; var AValue: TDateTime): Boolean;
+Function TryEncodeDateMonthWeek(const AYear, AMonth, AWeekOfMonth, ADayOfWeek: Word; out AValue: TDateTime): Boolean;
 
 var
   S : Word;
@@ -1813,7 +1813,7 @@ begin
 end;
 
 
-Function TryRecodeDateTime(const AValue: TDateTime; const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word; var AResult: TDateTime): Boolean;
+Function TryRecodeDateTime(const AValue: TDateTime; const AYear, AMonth, ADay, AHour, AMinute, ASecond, AMilliSecond: Word; out AResult: TDateTime): Boolean;
 
   Procedure FV (Var AV : Word; Arg : Word);
 
@@ -1908,7 +1908,7 @@ begin
 end;
 
 
-Procedure DecodeDayOfWeekInMonth(const AValue: TDateTime; var AYear, AMonth, ANthDayOfWeek, ADayOfWeek: Word);
+Procedure DecodeDayOfWeekInMonth(const AValue: TDateTime; out AYear, AMonth, ANthDayOfWeek, ADayOfWeek: Word);
 
 var
   D: Word;
@@ -1927,7 +1927,7 @@ begin
 end;
 
 
-Function TryEncodeDayOfWeekInMonth(const AYear, AMonth, ANthDayOfWeek,  ADayOfWeek: Word; var AValue: TDateTime): Boolean;
+Function TryEncodeDayOfWeekInMonth(const AYear, AMonth, ANthDayOfWeek,  ADayOfWeek: Word; out AValue: TDateTime): Boolean;
 
 Var
   SOM,D : Word;
@@ -2035,7 +2035,7 @@ begin
 end;
 
 
-Function TryJulianDateToDateTime(const AValue: Double; var ADateTime: TDateTime): Boolean;
+Function TryJulianDateToDateTime(const AValue: Double; out ADateTime: TDateTime): Boolean;
 begin
   ADateTime := JulianDateToDateTime(AValue);
   TryJulianDateToDateTime := ADateTime <> NaN;
@@ -2055,7 +2055,7 @@ begin
 end;
 
 
-Function TryModifiedJulianDateToDateTime(const AValue: Double; var ADateTime: TDateTime): Boolean;
+Function TryModifiedJulianDateToDateTime(const AValue: Double; out ADateTime: TDateTime): Boolean;
 begin
   Result:=False;
   NotYetImplemented('TryModifiedJulianDateToDateTime');

+ 2 - 0
rtl/objpas/sysconst.pp

@@ -41,6 +41,8 @@ resourcestring
   SErrInvalidDayOfWeekInMonth = 'Year %d Month %d NDow %d DOW %d is not a valid date';
   SErrInvalidDayOfYear   = 'Year %d does not have a day number %d';
   SErrInvalidTimeStamp   = 'Invalid date/timestamp : "%s"';
+  SErrIllegalDateFormatString   = '"%s" is not a valid date format string';
+  SErrInvalidTimeFormat  = '"%s" is not a valid time';
   SExceptionErrorMessage = 'exception at %p';
   SExceptionStack        = 'Exception stack error';
   SExecuteProcessFailed  = 'Failed to execute "%s", error code: %d';

+ 361 - 77
rtl/objpas/sysutils/dati.inc

@@ -326,8 +326,16 @@ end ;
     if S does not represent a valid date value
     an EConvertError will be raised   }
 
-function StrToDate(const S: string): TDateTime;
+function IntStrToDate(Out ErrorMsg : AnsiString; const S: PChar; Len : integer; const useformat : string; const defs:TFormatSettings; separator : char = #0): TDateTime;
+
 const SInvalidDateFormat = '"%s" is not a valid date format';
+
+procedure FixErrorMsg(const errm :ansistring;const errmarg : ansistring);
+
+begin
+  errormsg:=format(errm,[errmarg]);
+end;
+
 var
    df:string;
    d,m,y,ly:word;
@@ -339,11 +347,16 @@ var
    LocalTime:tsystemtime;
    YearMoreThenTwoDigits : boolean;
 begin
-  if s = '' then
-    Raise EConvertError.CreateFmt(SInvalidDateFormat,[s]);
-
+  ErrorMsg:='';   Result:=0;
+  if (Len=0) then
+    begin
+      FixErrorMsg(SInvalidDateFormat,'');
+      exit;
+    end;
   YearMoreThenTwoDigits := False;
-  df := UpperCase(ShortDateFormat);
+  if separator = #0 then
+    separator := defs.DateSeparator;
+  df := UpperCase(useFormat);
   { Determine order of D,M,Y }
   yp:=0;
   mp:=0;
@@ -375,13 +388,17 @@ begin
      end;
    end;
   if Which<>3 then
-   Raise EConvertError.Create('Illegal format string');
+    begin
+      FixErrorMsg(SErrIllegalDateFormatString,useformat);
+      Exit;
+    end;
 { Get actual values }
   for i := 1 to 3 do
     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,23 +406,32 @@ 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
-         Raise EConvertError.CreateFmt(SInvalidDateFormat,[s]);
+          begin 
+            FixErrorMsg(SInvalidDateFormat,s);
+            exit;
+          end;
          // Check if the year has more then two digits (if n=yp, then we are evaluating the year.)
         if (n=yp) and (length(s1)>2) then YearMoreThenTwoDigits := True;
         val(s1, values[n], c);
         if c<>0 then
-         Raise EConvertError.CreateFmt(SInvalidDateFormat,[s]);
+          begin
+            FixErrorMsg(SInvalidDateFormat,s);
+            Exit;
+          end;
         s1 := '';
       end
      else if not (s[i] in ['0'..'9']) then
-      Raise EConvertError.CreateFmt(SInvalidDateFormat,[s]);
+       begin
+         FixErrorMsg(SInvalidDateFormat,s);
+         Exit;
+       end;
    end ;
   // Fill in values.
   getLocalTime(LocalTime);
@@ -438,52 +464,104 @@ begin
   end;
   if (y >= 0) and (y < 100) and not YearMoreThenTwoDigits then
     begin
-    ly := ly - TwoDigitYearCenturyWindow;
+    ly := ly - defs.TwoDigitYearCenturyWindow;
     Inc(Y, ly div 100 * 100);
-    if (TwoDigitYearCenturyWindow > 0) and (Y < ly) then
+    if (defs.TwoDigitYearCenturyWindow > 0) and (Y < ly) then
       Inc(Y, 100);
     end;
   Result := EncodeDate(y, m, d);
-end ;
+end;
+
+function StrToDate(const S: PChar; Len : integer; const useformat : string; separator : char = #0): TDateTime;
+
+Var
+  MSg : AnsiString;
+
+begin
+  Result:=IntStrToDate(Msg,S,Len,useFormat,DefaultFormatSettings,Separator);
+  If (Msg<>'') then
+    Raise EConvertError.Create(Msg);
+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 IntStrToTime(Out ErrorMsg : AnsiString; const S: PChar; Len : integer;const defs:TFormatSettings; 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 ((defs.TimeAMString<>'') and (CurrentChar = defs.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 ((defs.TimePMString<>'') and (CurrentChar = defs.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');
+        ErrorMsg:=Format(SErrInvalidTimeFormat,[StrPas(S)]);
       end ;
    end ;
 
@@ -492,17 +570,23 @@ var
    TimeValues: array[0..4] of integer;
 
 begin
+  if separator = #0 then
+        separator := defs.TimeSeparator;
   Current := 0;
-  Len := length(s);
   PM := 0;
   for i:=0 to 4 do
     timevalues[i]:=0;
   i := 0;
   TimeValues[i] := GetElement;
+  If ErrorMsg<>'' then 
+    Exit;
   while (i < 5) and (TimeValues[i] <> -1) do 
     begin
      i := i + 1;
+     Inc(Current);
      TimeValues[i] := GetElement;
+     If ErrorMsg<>'' then
+        Exit;
    end ;
   If (i<5) and (TimeValues[I]=-1) then
     TimeValues[I]:=0;
@@ -519,39 +603,96 @@ begin
   result := EncodeTime(TimeValues[0], TimeValues[1], TimeValues[2], TimeValues[3]);
 end ;
 
+function StrToTime(const S: PChar; Len : integer; separator : char = #0): TDateTime;
+
+Var
+  Msg : AnsiString;
+
+begin
+  Result:=IntStrToTime(Msg,S,Len,DefaultFormatSettings,Separator);
+  If (Msg<>'') then 
+    Raise EConvertError.Create(Msg);
+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)
+  I: integer;
+begin
+  I:=Pos(TimeSeparator,S);
+  If (I>0) then
+    begin
+    While (I>0) and (S[I]<>' ') do
+      Dec(I);
+    If I>0 then
+      result:=ComposeDateTime(StrToDate(Copy(S,1,I-1)),StrToTime(Copy(S,i+1, Length(S)-i)))
+    else
+      result:=StrToTime(S)
+    end
   else
-    Result := StrToTime(st);
-end ;
+    Result:=StrToDate(S);
+end;
+
+function StrToDateTime(const s: AnsiString; const UseFormat : TFormatSettings): TDateTime;
+var
+  I: integer;
+begin
+  I:=Pos(TimeSeparator,S);
+  If (I>0) then
+    begin
+    While (I>0) and (S[I]<>' ') do
+      Dec(I);
+    If I>0 then
+      result:=ComposeDateTime(StrToDate(Copy(S,1,I-1),UseFormat.ShortDateFormat,UseFormat.DateSeparator),
+                              StrToTime(Copy(S,i+1, Length(S)-i),UseFormat.TimeSeparator))
+    else
+      result:=StrToTime(S,UseFormat.TimeSeparator)
+    end
+  else
+    Result:=StrToDate(S,UseFormat.ShortDateFormat,UseFormat.DateSeparator);
+end;
+
+function StrToDateTime(const s: ShortString; const UseFormat : TFormatSettings): TDateTime;
+var
+  I: integer;
+begin
+  I:=Pos(TimeSeparator,S);
+  If (I>0) then
+    begin
+    While (I>0) and (S[I]<>' ') do
+      Dec(I);
+    If I>0 then
+      result:=ComposeDateTime(StrToDate(Copy(S,1,I-1),UseFormat.ShortDateFormat,UseFormat.DateSeparator),
+                              StrToTime(Copy(S,i+1, Length(S)-i),UseFormat.TimeSeparator))
+    else
+      result:=StrToTime(S,UseFormat.TimeSeparator)
+    end
+  else
+    Result:=StrToDate(S,UseFormat.ShortDateFormat,UseFormat.DateSeparator);
+end;
 
 {   FormatDateTime formats DateTime to the given format string FormatStr   }
 
@@ -818,38 +959,121 @@ begin
 end;
 {$endif unix}
 
-// ieuw. These should  be written to work without exceptions?
-function TryStrToDate(const S: string; out Value: TDateTime): Boolean;
-  begin
-    result:=true;
-    try
-      value:=StrToDate(s);
-    except
-      on EConvertError do
-        result:=false
+function TryStrToDate(const S: ShortString; out Value: TDateTime): Boolean;
+begin
+    result := TryStrToDate(S, Value, #0);
+end;
+
+function TryStrToDate(const S: ShortString; out Value: TDateTime;
+                    const useformat : string; separator : char = #0): Boolean;
+                    
+Var
+  Msg : Ansistring;
+                      
+begin
+  Value:=IntStrToDate(Msg,@S[1],Length(S),useformat,defaultformatsettings,separator);
+  Result:=(Msg='');
+end;
+
+function TryStrToDate(const S: AnsiString; out Value: TDateTime;
+                    const useformat : string; separator : char = #0): Boolean;
+                    
+Var
+  Msg : Ansistring;                    
+                    
+begin
+  Result:=Length(S)<>0;
+  If Result then
+    begin
+    Value:=IntStrToDate(Msg,@S[1],Length(S),useformat,DefaultFormatSettings,Separator);
+    Result:=(Msg='');
     end;
-  end;
+end;
+
+function TryStrToDate(const S: ShortString; out Value: TDateTime; separator : char): Boolean;
+begin
+  Result:=TryStrToDate(S,Value,ShortDateFormat,Separator);
+end;
+
+
+function TryStrToDate(const S: AnsiString; out Value: TDateTime): Boolean;
+begin
+  Result:=TryStrToDate(S,Value,ShortDateFormat,#0);
+end;
 
+function TryStrToDate(const S: AnsiString; out Value: TDateTime; separator : char): Boolean;
+
+begin
+  Result:=TryStrToDate(S,Value,ShortDateFormat,Separator);  
+end;
+
+function TryStrToDate(const S: string; out Value: TDateTime; const FormatSettings: TFormatSettings): Boolean;
+Var
+  Msg : Ansistring;                    
+                    
+begin
+  Result:=Length(S)<>0;
+  If Result then
+    begin
+      Value:=IntStrToDate(Msg,@S[1],Length(S),FormatSettings.ShortDateFormat,FormatSettings,#0);
+      Result:=(Msg='');
+    end;
+end;
+
+function TryStrToTime(const S: ShortString; out Value: TDateTime; separator : char): Boolean;
+
+Var
+  Msg : AnsiString;
+begin
+  Value:=IntStrToTime(Msg,@S[1],Length(S),DefaultFormatSettings,Separator);
+  result:=(Msg='');
+end;
+
+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;
+Var
+  Msg : AnsiString;
+begin
+  Result:=Length(S)<>0;
+  If Result then
+    begin
+      Value:=IntStrToTime(Msg,@S[1],Length(S),DefaultFormatSettings,Separator);
+      Result:=(Msg='');
+    end;
+end;
 
-// function TryStrToDate(const S: string; out Value: TDateTime; const FormatSettings: TFormatSettings): Boolean;
+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;
+Var msg : AnsiString;
+begin
+  Result:=Length(S)<>0;
+  If Result then
+    begin
+      Value:=IntStrToTime(Msg,@S[1],Length(S),FormatSettings,#0);
+      Result:=(Msg='');
+    end;
+end;
 
-function TryStrToTime(const S: string; out Value: TDateTime): Boolean;
+function TryStrToDateTime(const S: ShortString; out Value: TDateTime): Boolean;
   begin
     result:=true;
     try
-      value:=StrToTime(s);
+      value:=StrToDateTime(s);
     except
       on EConvertError do
         result:=false
     end;
   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: AnsiString; out Value: TDateTime): Boolean;
   begin
     result:=true;
     try
@@ -860,28 +1084,88 @@ function TryStrToDateTime(const S: string; out Value: TDateTime): Boolean;
     end;
   end;
 
+function TryStrToDateTime(const S: string; out Value: TDateTime; const FormatSettings: TFormatSettings): Boolean;
+var
+  I: integer;
+  dtdate, dttime :TDateTime;
+begin
+  result:=true;
+  I:=Pos(FormatSettings.TimeSeparator,S);
+  If (I>0) then
+    begin
+      While (I>0) and (S[I]<>' ') do
+        Dec(I);
+      If I>0 then
+        begin
+          if not TryStrToDate(Copy(S,1,I-1),dtdate,Formatsettings) then
+            exit;
+          if not TryStrToTime(Copy(S,i+1, Length(S)-i),dttime,Formatsettings) then
+            exit;
+          Value:=ComposeDateTime(dtdate,dttime);
+        end
+      else
+         result:=TryStrToTime(s,Value,Formatsettings);
+    end
+  else
+    result:=TryStrToDate(s,Value,Formatsettings);
+end;
+
+function StrToDateDef(const S: ShortString; const Defvalue : TDateTime): TDateTime;
+begin
+   result := StrToDateDef(S,DefValue,#0);
+end;
 
-// function TryStrToDateTime(const S: string; out Value: TDateTime; const FormatSettings: TFormatSettings): Boolean;
+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 TryStrToDateTime(s,Result) Then
+    result:=defvalue;
+end;
 
-function StrToDateDef(const S: string; const Defvalue : TDateTime): TDateTime;
+function StrToDateDef(const S: ShortString; const Defvalue : TDateTime; separator : char): TDateTime;
 begin
-  if not TryStrToDate(s,Result) Then
+  if not TryStrToDate(s,Result, separator) Then
     result:=defvalue;
 end;
 
-function StrToTimeDef(const S: string; const Defvalue : TDateTime): TDateTime;
+function StrToTimeDef(const S: ShortString; const Defvalue : TDateTime; separator : char): TDateTime;
 begin
-  if not TryStrToTime(s,Result) Then
+  if not TryStrToTime(s,Result, separator) Then
     result:=defvalue;
 end;
 
-function StrToDateTimeDef(const S: string; const Defvalue : TDateTime): TDateTime;
+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);

+ 44 - 13
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: 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 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: 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 }