소스 검색

* comparing tdatetime variant values has to happen without an epsilon,
as all bits of the double value encode date/time information
(mantis #13110)

git-svn-id: trunk@12962 -

Jonas Maebe 16 년 전
부모
커밋
757abc620a
3개의 변경된 파일63개의 추가작업 그리고 1개의 파일을 삭제
  1. 1 0
      .gitattributes
  2. 13 1
      rtl/inc/variants.pp
  3. 49 0
      tests/webtbs/tw13110.pp

+ 1 - 0
.gitattributes

@@ -8797,6 +8797,7 @@ tests/webtbs/tw13015.pp svneol=native#text/plain
 tests/webtbs/tw13019.pp svneol=native#text/plain
 tests/webtbs/tw13075.pp svneol=native#text/plain
 tests/webtbs/tw1310.pp svneol=native#text/plain
+tests/webtbs/tw13110.pp svneol=native#text/plain
 tests/webtbs/tw13133.pp svneol=native#text/plain
 tests/webtbs/tw1318.pp svneol=native#text/plain
 tests/webtbs/tw13186.pp svneol=native#text/plain

+ 13 - 1
rtl/inc/variants.pp

@@ -1132,6 +1132,18 @@ begin
   else
     Result := 1;
 end;
+
+
+function DoVarCmpDate(const Left, Right: TDateTime; const OpCode: TVarOp): ShortInt;
+begin
+  { dates have to match exactly, all bits encode time information }
+  if(Left = Right) then
+    Result := 0
+  else if (OpCode in [opCmpEq, opCmpNe]) or (Left < Right) then
+    Result := -1
+  else
+    Result := 1;
+end;
 {$endif}
 
 function DoVarCmpInt64(const Left, Right: Int64): ShortInt;
@@ -1261,7 +1273,7 @@ begin
       else
         Result := DoVarCmpWStr(vl, vr, OpCode);
 {$ifndef FPUNONE}
-    ctDate:     Result := DoVarCmpFloat(VariantToDate(vl), VariantToDate(vr), OpCode);
+    ctDate:     Result := DoVarCmpDate(VariantToDate(vl), VariantToDate(vr), OpCode);
     ctCurrency: Result := DoVarCmpCurr(VariantToCurrency(vl), VariantToCurrency(vr));
 {$endif}
     ctString:

+ 49 - 0
tests/webtbs/tw13110.pp

@@ -0,0 +1,49 @@
+program project1;
+
+{$mode objfpc}{$H+}
+
+uses
+  {$IFDEF UNIX}{$IFDEF UseCThreads}
+  cthreads,
+  {$ENDIF}{$ENDIF}
+  Classes, Sysutils, variants;
+
+
+procedure TestMatch(ATestNo: Integer; Value1: TDateTime; Value2: Variant; shouldmatch: boolean);
+const
+  cDateTime = 'yyyy-mm-dd HH:mm:ss.zzz';
+var
+  result: Boolean;
+begin
+  writeln('========= ' + IntToStr(ATestNo) + ' =============');
+  writeln(' value1=' + FormatDateTime(cDateTime, value1));
+  writeln(' value2=', FormatDateTime(cDateTime, value2));
+  result := (value1 = value2);
+  writeln(' Do they match?  result=', Result);
+  writeln(' ');
+  if (result<>shouldmatch) then
+    halt(1);
+end;
+
+
+var
+  lDate: TDateTime;
+  lSearch: variant;
+begin
+  lDate := EncodeDate(1999,02,06)+EncodeTime(20,0,0,1);
+  lSearch := EncodeDate(1999,02,06)+EncodeTime(20,0,0,1);
+  TestMatch(1, lDate, lSearch, true);
+
+  lDate := EncodeDate(1999,02,06)+EncodeTime(20,0,0,1);
+  lSearch := EncodeDate(1999,02,06)+EncodeTime(20,0,0,2);
+  TestMatch(2, lDate, lSearch, false);
+
+  lDate := EncodeDate(1999,02,06)+EncodeTime(20,0,0,1);
+  lSearch := EncodeDate(1999,02,06)+EncodeTime(20,0,0,4);
+  TestMatch(3, lDate, lSearch, false);
+
+  lDate := EncodeDate(1999,02,06)+EncodeTime(20,0,0,1);
+  lSearch := EncodeDate(1999,02,06)+EncodeTime(20,0,0,5);
+  TestMatch(4, lDate, lSearch, false);
+end.
+