Bladeren bron

fcl-db: mysql: fix handling milliseconds in date time values with precision < 3. f.e. datetime(1) value '07:13:45.1' has 100 msec not 1 msec (value after decimal point does not always means milliseconds)

git-svn-id: trunk@30154 -
lacak 10 jaren geleden
bovenliggende
commit
94a2fbb20d
1 gewijzigde bestanden met toevoegingen van 30 en 21 verwijderingen
  1. 30 21
      packages/fcl-db/src/sqldb/mysql/mysqlconn.inc

+ 30 - 21
packages/fcl-db/src/sqldb/mysql/mysqlconn.inc

@@ -838,7 +838,7 @@ begin
     Result := StrToInt(S);
 end;
 
-function InternalStrToFloat(S: string): Extended;
+function InternalStrToFloat(const S: string): Extended;
 
 var
   I: Integer;
@@ -856,7 +856,7 @@ begin
   Result := StrToFloat(Tmp);
 end;
 
-function InternalStrToCurrency(S: string): Extended;
+function InternalStrToCurrency(const S: string): Extended;
 
 var
   I: Integer;
@@ -874,7 +874,7 @@ begin
   Result := StrToCurr(Tmp);
 end;
 
-function InternalStrToDate(S: string): TDateTime;
+function InternalStrToDate(const S: string): TDateTime;
 
 var
   EY, EM, ED: Word;
@@ -889,7 +889,26 @@ begin
     Result:=EncodeDate(EY, EM, ED);
 end;
 
-function InternalStrToDateTime(S: string): TDateTime;
+function StrToMSecs(const S: string): Word;
+var C: char;
+    d, MSecs: double;
+begin
+{$IFDEF MYSQL56_UP}
+  // datetime(n), where n is fractional seconds precision (between 0 and 6)
+  MSecs := 0;
+  d := 100;
+  for C in S do
+    begin
+    MSecs := MSecs + (ord(C)-ord('0'))*d;
+    d := d / 10;
+    end;
+  Result := Round(MSecs);
+{$ELSE}
+  Result := 0;
+{$ENDIF}
+end;
+
+function InternalStrToDateTime(const S: string): TDateTime;
 
 var
   EY, EM, ED: Word;
@@ -902,19 +921,15 @@ begin
   EH := StrToInt(Copy(S, 12, 2));
   EN := StrToInt(Copy(S, 15, 2));
   ES := StrToInt(Copy(S, 18, 2));
-  EMS:=0;
-{$IFDEF mysql56}
-  if (Copy(S, 21, 3)<>'') then
-    EMS := StrToIntDef(Copy(S, 21, 3),0);
-{$ENDIF} 
+  EMS:= StrToMSecs(Copy(S, 21, 6));
   if (EY = 0) or (EM = 0) or (ED = 0) then
     Result := 0
   else
     Result := EncodeDate(EY, EM, ED);
-  Result := ComposeDateTime(Result,EncodeTime(EH, EN, ES, EMS));
+  Result := ComposeDateTime(Result, EncodeTime(EH, EN, ES, EMS));
 end;
 
-function InternalStrToTime(S: string): TDateTime;
+function InternalStrToTime(const S: string): TDateTime;
 
 var
   EH, EM, ES, EMS: Word;
@@ -922,24 +937,20 @@ var
 
 begin
   p := 1;
-  EMS:=0;
   EH := StrToInt(ExtractSubstr(S, p, [':'])); //hours can be 2 or 3 digits
   EM := StrToInt(ExtractSubstr(S, p, [':']));
   ES := StrToInt(ExtractSubstr(S, p, ['.']));
-{$IFDEF mysql56}
-   EMS:= StrToIntDef(ExtractSubstr(S, p, ['.']),0);
-{$ENDIF}   
+  EMS:= StrToMSecs(Copy(S, p, 6));
   Result := EncodeTimeInterval(EH, EM, ES, EMS);
 end;
 
-function InternalStrToTimeStamp(S: string): TDateTime;
+function InternalStrToTimeStamp(const S: string): TDateTime;
 
 var
   EY, EM, ED: Word;
   EH, EN, ES, EMS: Word;
 
 begin
-  EMS:=0;
 {$IFNDEF mysql40}
   EY := StrToInt(Copy(S, 1, 4));
   EM := StrToInt(Copy(S, 6, 2));
@@ -947,10 +958,7 @@ begin
   EH := StrToInt(Copy(S, 12, 2));
   EN := StrToInt(Copy(S, 15, 2));
   ES := StrToInt(Copy(S, 18, 2));
-{$IFDEF mysql56}
-  if (Copy(S, 21, 3)<>'') then
-    EMS := StrToIntDef(Copy(S, 21, 3),0);
-{$ENDIF} 
+  EMS:= StrToMSecs(Copy(S, 21, 6));
 {$ELSE}
   EY := StrToInt(Copy(S, 1, 4));
   EM := StrToInt(Copy(S, 5, 2));
@@ -958,6 +966,7 @@ begin
   EH := StrToInt(Copy(S, 9, 2));
   EN := StrToInt(Copy(S, 11, 2));
   ES := StrToInt(Copy(S, 13, 2));
+  EMS:= 0;
 {$ENDIF}
   if (EY = 0) or (EM = 0) or (ED = 0) then
     Result := 0