diff --git a/wst/trunk/base_service_intf.pas b/wst/trunk/base_service_intf.pas index 654cd65ce..0ccc0bfc2 100644 --- a/wst/trunk/base_service_intf.pas +++ b/wst/trunk/base_service_intf.pas @@ -400,6 +400,14 @@ type { TDateRemotable } TDateRemotable = class(TBaseDateRemotable) + public + class function ToStr(const ADate : TDateTimeRec):string;override; + class function Parse(const ABuffer : string):TDateTimeRec;override; + end; + + { TDateTimeRemotable } + + TDateTimeRemotable = class(TBaseDateRemotable) protected function GetDatepart(const AIndex : Integer) : Integer;override; public @@ -1734,7 +1742,8 @@ begin r.Register(sXSD_NS,TypeInfo(Double),'double').AddPascalSynonym('Double'); r.Register(sXSD_NS,TypeInfo(Extended),'decimal').AddPascalSynonym('Extended'); - r.Register(sXSD_NS,TypeInfo(TDateRemotable),'dateTime').AddPascalSynonym('TDateRemotable'); + r.Register(sXSD_NS,TypeInfo(TDateTimeRemotable),'dateTime').AddPascalSynonym('TDateTimeRemotable'); + r.Register(sXSD_NS,TypeInfo(TDateRemotable),'date').AddPascalSynonym('TDateRemotable'); {$IFDEF WST_HAS_TDURATIONREMOTABLE} r.Register(sXSD_NS,TypeInfo(TDurationRemotable),'duration').AddPascalSynonym('TDurationRemotable'); {$ELSE WST_HAS_TDURATIONREMOTABLE} @@ -5632,17 +5641,29 @@ end; { TDateRemotable } -class function TDateRemotable.ToStr(const ADate: TDateTimeRec): string; +class function TDateRemotable.ToStr(const ADate : TDateTimeRec) : string; begin - Result := xsd_DateTimeToStr(ADate); + Result := xsd_DateTimeToStr(ADate,xdkDate); end; -class function TDateRemotable.Parse(const ABuffer: string): TDateTimeRec; +class function TDateRemotable.Parse(const ABuffer : string) : TDateTimeRec; begin - Result := xsd_StrToDate(ABuffer); + Result := xsd_StrToDate(ABuffer,xdkDate); end; -function TDateRemotable.GetDatepart(const AIndex: Integer): Integer; +{ TDateTimeRemotable } + +class function TDateTimeRemotable.ToStr(const ADate: TDateTimeRec): string; +begin + Result := xsd_DateTimeToStr(ADate,xdkDateTime); +end; + +class function TDateTimeRemotable.Parse(const ABuffer: string): TDateTimeRec; +begin + Result := xsd_StrToDate(ABuffer,xdkDateTime); +end; + +function TDateTimeRemotable.GetDatepart(const AIndex: Integer): Integer; begin case AIndex of 3 : Result := HourOf(AsDate); @@ -5675,7 +5696,7 @@ class procedure TBaseDateRemotable.Save( var buffer : string; begin - buffer := TDateRemotable(AObject).AsString; + buffer := TBaseDateRemotable(AObject).AsString; AStore.BeginObject(AName,ATypeInfo); try AStore.PutScopeInnerValue(TypeInfo(string),buffer); @@ -5697,7 +5718,7 @@ begin try strBuffer := ''; AStore.GetScopeInnerValue(TypeInfo(string),strBuffer); - (AObject as TDateRemotable).AsString := strBuffer + (AObject as TBaseDateRemotable).AsString := strBuffer finally AStore.EndScopeRead(); end; @@ -5706,8 +5727,8 @@ end; procedure TBaseDateRemotable.Assign(Source: TPersistent); begin - if Source.InheritsFrom(TDateRemotable) then begin - FDate := TDateRemotable(Source).FDate; + if Source.InheritsFrom(TBaseDateRemotable) then begin + FDate := TBaseDateRemotable(Source).FDate; end else begin inherited Assign(Source); end; @@ -6847,8 +6868,8 @@ begin end else begin if Source.InheritsFrom(TTimeRemotable) then Self.Data := TTimeRemotable(Source).Data - else if Source.InheritsFrom(TDateRemotable) then - Self.Data := DateTimeToTimeRec(TDateRemotable(Source).AsUTCDate) + else if Source.InheritsFrom(TDateTimeRemotable) then + Self.Data := DateTimeToTimeRec(TDateTimeRemotable(Source).AsUTCDate) else inherited Assign(Source); end; diff --git a/wst/trunk/base_xmlrpc_formatter.pas b/wst/trunk/base_xmlrpc_formatter.pas index 60477ee91..560629726 100644 --- a/wst/trunk/base_xmlrpc_formatter.pas +++ b/wst/trunk/base_xmlrpc_formatter.pas @@ -1263,7 +1263,9 @@ begin if ( ATypeInfo^.Kind = tkClass ) then begin locClass := GetTypeData(ATypeInfo)^.ClassType; if locClass.InheritsFrom(TAbstractSimpleRemotable) then begin - if locClass.InheritsFrom(TDateRemotable) then + if locClass.InheritsFrom(TDateTimeRemotable) or + locClass.InheritsFrom(TDateRemotable) + then locScopeType := stXmlRpcDate else locScopeType := stSimpleContent; diff --git a/wst/trunk/date_utils.pas b/wst/trunk/date_utils.pas index 06e9499b4..bfa9ee2dd 100644 --- a/wst/trunk/date_utils.pas +++ b/wst/trunk/date_utils.pas @@ -65,11 +65,27 @@ const Negative : False; ); - function xsd_TryStrToDate(const AStr : string; out ADate : TDateTimeRec) : Boolean; - function xsd_StrToDate(const AStr : string) : TDateTimeRec; {$IFDEF USE_INLINE}inline;{$ENDIF} +type + TXsdDateKind = ( xdkDateTime, xdkDate ); - function xsd_DateTimeToStr(const ADate : TDateTimeRec) : string;overload; - function xsd_DateTimeToStr(const ADate : TDateTime) : string;overload; + function xsd_TryStrToDate( + const AStr : string; + out ADate : TDateTimeRec; + const ADateKind : TXsdDateKind + ) : Boolean; + function xsd_StrToDate( + const AStr : string; + const ADateKind : TXsdDateKind + ) : TDateTimeRec; {$IFDEF USE_INLINE}inline;{$ENDIF} + + function xsd_DateTimeToStr( + const ADate : TDateTimeRec; + const ADateKind : TXsdDateKind + ) : string; overload; + function xsd_DateTimeToStr( + const ADate : TDateTime; + const ADateKind : TXsdDateKind + ) : string;overload; function xsd_TimeToStr(const ATime : TTimeRec) : string; function xsd_TryStrToTime(const AStr : string; out ADate : TTimeRec) : Boolean; @@ -184,7 +200,11 @@ begin ( a.MinuteOffset = b.MinuteOffset ); end; -function xsd_TryStrToDate(const AStr : string; out ADate : TDateTimeRec) : Boolean; +function xsd_TryStrToDate( + const AStr : string; + out ADate : TDateTimeRec; + const ADateKind : TXsdDateKind +) : Boolean; const DATE_SEP_CHAR = '-'; TIME_MARKER_CHAR = 'T'; TIME_SEP_CHAR = ':'; var @@ -262,30 +282,38 @@ begin if ReadInt(m,DATE_SEP_CHAR) then begin Inc(bufferPos); if ReadInt(d,#0) then begin - Inc(bufferPos); tz_hh := 0; tz_mn := 0; - if ( bufferPos > bufferLen ) then begin - hh := 0; - mn := 0; - ss := 0; - ssss := 0; + hh := 0; + mn := 0; + ss := 0; + ssss := 0; + if ( bufferPos >= bufferLen ) then begin ok := True; end else begin - ok := ( buffer[bufferPos -1] = TIME_MARKER_CHAR ) and ReadInt(hh,TIME_SEP_CHAR); + ok := ( buffer[bufferPos] in [TIME_MARKER_CHAR,'-','+'] ); if ok then begin - Inc(bufferPos); - ok := ReadInt(mn,TIME_SEP_CHAR); - if ok then begin + if ( buffer[bufferPos] = TIME_MARKER_CHAR ) then begin Inc(bufferPos); - ok := ReadInt(ss,#0); - if ok and ( bufferPos < bufferLen ) and ( buffer[bufferPos] = '.' ) then begin + ok := ( ADateKind = xdkDateTime ) and ReadInt(hh,TIME_SEP_CHAR); + if ok then begin Inc(bufferPos); - ok := ReadMiliSeconds(ssss); - end else begin - ssss := 0; + ok := ReadInt(mn,TIME_SEP_CHAR); + if ok then begin + Inc(bufferPos); + ok := ReadInt(ss,#0); + if ok and ( bufferPos < bufferLen ) and ( buffer[bufferPos] = '.' ) then begin + Inc(bufferPos); + ok := ReadMiliSeconds(ssss); + end else begin + ssss := 0; + end; + end; end; - if ok and ( bufferPos < bufferLen ) then begin + end; + if ok and ( bufferPos < bufferLen ) then begin + ok := ( buffer[bufferPos] in ['-','+'] ); + if ok then begin tz_negative := ( buffer[bufferPos] = '-' ); Inc(bufferPos); ok := ReadInt(tz_hh,TIME_SEP_CHAR); @@ -319,18 +347,25 @@ begin end; end; -function xsd_StrToDate(const AStr : string) : TDateTimeRec; +function xsd_StrToDate( + const AStr : string; + const ADateKind : TXsdDateKind +) : TDateTimeRec; begin - if not xsd_TryStrToDate(AStr,Result) then + if not xsd_TryStrToDate(AStr,Result,ADateKind) then raise EConvertError.CreateFmt(SERR_InvalidDate,[AStr]); end; {$HINTS OFF} -function xsd_DateTimeToStr(const ADate : TDateTimeRec) : string; +function xsd_DateTimeToStr( + const ADate : TDateTimeRec; + const ADateKind : TXsdDateKind +) : string; var locDate : TDateTime; d, m, y : Word; hh, mn, ss, ssss : Word; + locRes : string; begin //'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? locDate := ADate.Date; @@ -338,21 +373,30 @@ begin locDate := IncHour(locDate,-ADate.HourOffset); if ( ADate.MinuteOffset <> 0 ) then locDate := IncMinute(locDate,-ADate.MinuteOffset); - DecodeDateTime(locDate,y,m,d,hh,mn,ss,ssss); - if ( ssss = 0 ) then - Result := Format('%.4d-%.2d-%.2dT%.2d:%.2d:%.2dZ',[y,m,d, hh,mn,ss]) - else - Result := Format('%.4d-%.2d-%.2dT%.2d:%.2d:%.2d.%.3dZ',[y,m,d, hh,mn,ss,ssss]); + if ( ADateKind = xdkDate ) then begin + DecodeDate(locDate,y,m,d); + locRes := Format('%.4d-%.2d-%.2d',[y,m,d]); + end else begin + DecodeDateTime(locDate,y,m,d,hh,mn,ss,ssss); + if ( ssss = 0 ) then + locRes := Format('%.4d-%.2d-%.2dT%.2d:%.2d:%.2dZ',[y,m,d, hh,mn,ss]) + else + locRes := Format('%.4d-%.2d-%.2dT%.2d:%.2d:%.2d.%.3dZ',[y,m,d, hh,mn,ss,ssss]); + end; + Result := locRes; end; {$HINTS ON} -function xsd_DateTimeToStr(const ADate : TDateTime) : string; +function xsd_DateTimeToStr( + const ADate : TDateTime; + const ADateKind : TXsdDateKind +) : string; var tmpDate : TDateTimeRec; begin FillChar(tmpDate,SizeOf(TDateTimeRec),#0); tmpDate.Date := ADate; - Result := xsd_DateTimeToStr(tmpDate); + Result := xsd_DateTimeToStr(tmpDate,ADateKind); end; function xsd_TimeToStr(const ATime : TTimeRec) : string; diff --git a/wst/trunk/tests/test_suite/test_date_utils.pas b/wst/trunk/tests/test_suite/test_date_utils.pas index 69896fc1a..ecdb5ba48 100644 --- a/wst/trunk/tests/test_suite/test_date_utils.pas +++ b/wst/trunk/tests/test_suite/test_date_utils.pas @@ -36,6 +36,8 @@ type {$ENDIF WST_DELPHI} published procedure xsd_TryStrToDate_date_only(); + procedure xsd_TryStrToDate_date_timezone_1(); + procedure xsd_TryStrToDate_date_timezone_2(); procedure xsd_TryStrToDate_date_time(); procedure xsd_TryStrToDate_date_time_fractional_second(); procedure xsd_TryStrToDate_date_bad_separator(); @@ -78,11 +80,11 @@ begin //'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? FillChar(d,SizeOf(d),#0); d.Date := EncodeDate(1976,10,12) + EncodeTime(23,34,56,0); - CheckEquals(sDATE_1, xsd_DateTimeToStr(d)); + CheckEquals(sDATE_1, xsd_DateTimeToStr(d,xdkDateTime)); FillChar(d,SizeOf(d),#0); d.Date := EncodeDate(987,06,12) - EncodeTime(20,34,56,0); - CheckEquals(sDATE_2, xsd_DateTimeToStr(d)); + CheckEquals(sDATE_2, xsd_DateTimeToStr(d,xdkDateTime)); end; procedure TTest_DateUtils.xsd_DateTimeToStr_2(); @@ -93,10 +95,10 @@ var d : TDateTime; begin d := EncodeDate(1976,10,12) + EncodeTime(23,34,56,0); - CheckEquals(sDATE_1, xsd_DateTimeToStr(d)); + CheckEquals(sDATE_1, xsd_DateTimeToStr(d,xdkDateTime)); d := EncodeDate(987,06,12) - EncodeTime(20,34,56,0); - CheckEquals(sDATE_2, xsd_DateTimeToStr(d)); + CheckEquals(sDATE_2, xsd_DateTimeToStr(d,xdkDateTime)); end; procedure TTest_DateUtils.xsd_DateTimeToStr_fractional_second_1(); @@ -109,15 +111,15 @@ var begin FillChar(d,SizeOf(d),#0); d.Date := EncodeDate(1976,10,12) + EncodeTime(23,34,56,7); - CheckEquals(sDATE_1, xsd_DateTimeToStr(d)); + CheckEquals(sDATE_1, xsd_DateTimeToStr(d,xdkDateTime)); FillChar(d,SizeOf(d),#0); d.Date := EncodeDate(1976,10,12) + EncodeTime(23,34,56,78); - CheckEquals(sDATE_2, xsd_DateTimeToStr(d)); + CheckEquals(sDATE_2, xsd_DateTimeToStr(d,xdkDateTime)); FillChar(d,SizeOf(d),#0); d.Date := EncodeDate(1976,10,12) + EncodeTime(23,34,56,789); - CheckEquals(sDATE_3, xsd_DateTimeToStr(d)); + CheckEquals(sDATE_3, xsd_DateTimeToStr(d,xdkDateTime)); end; procedure TTest_DateUtils.xsd_DateTimeToStr_fractional_second_2(); @@ -130,15 +132,15 @@ var begin FillChar(d,SizeOf(d),#0); d := EncodeDate(1976,10,12) + EncodeTime(23,34,56,7); - CheckEquals(sDATE_1, xsd_DateTimeToStr(d)); + CheckEquals(sDATE_1, xsd_DateTimeToStr(d,xdkDateTime)); FillChar(d,SizeOf(d),#0); d := EncodeDate(1976,10,12) + EncodeTime(23,34,56,78); - CheckEquals(sDATE_2, xsd_DateTimeToStr(d)); + CheckEquals(sDATE_2, xsd_DateTimeToStr(d,xdkDateTime)); FillChar(d,SizeOf(d),#0); d := EncodeDate(1976,10,12) + EncodeTime(23,34,56,789); - CheckEquals(sDATE_3, xsd_DateTimeToStr(d)); + CheckEquals(sDATE_3, xsd_DateTimeToStr(d,xdkDateTime)); end; procedure TTest_DateUtils.xsd_DateTimeToStr_timezone_1(); @@ -150,7 +152,7 @@ begin FillChar(d,SizeOf(d),#0); d.Date := EncodeDate(2002,10,10) + EncodeTime(12,0,0,0); d.HourOffset := 5; - CheckEquals('2002-10-10T07:00:00Z', xsd_DateTimeToStr(d)); + CheckEquals('2002-10-10T07:00:00Z', xsd_DateTimeToStr(d,xdkDateTime)); end; procedure TTest_DateUtils.xsd_TimeToStr_1(); @@ -335,10 +337,10 @@ var begin s := '23:34:56+12:34'; Check(xsd_TryStrToTime(s,d)); - CheckEquals(d.Hour,23,'Hour'); - CheckEquals(d.Minute,34,'Minute'); - CheckEquals(d.Second,56,'Second'); - CheckEquals(d.MilliSecond,0,'MilliSecond'); + CheckEquals(23,d.Hour,'Hour'); + CheckEquals(34,d.Minute,'Minute'); + CheckEquals(56,d.Second,'Second'); + CheckEquals(0,d.MilliSecond,'MilliSecond'); CheckEquals(12,d.HourOffset,'HourOffset'); CheckEquals(34,d.MinuteOffset,'MinuteOffset'); end; @@ -350,10 +352,10 @@ var begin s := '23:34:56-01:23'; Check(xsd_TryStrToTime(s,d)); - CheckEquals(d.Hour,23,'Hour'); - CheckEquals(d.Minute,34,'Minute'); - CheckEquals(d.Second,56,'Second'); - CheckEquals(d.MilliSecond,0,'MilliSecond'); + CheckEquals(23,d.Hour,'Hour'); + CheckEquals(34,d.Minute,'Minute'); + CheckEquals(56,d.Second,'Second'); + CheckEquals(0,d.MilliSecond,'MilliSecond'); CheckEquals(-1,d.HourOffset,'HourOffset'); CheckEquals(-23,d.MinuteOffset,'MinuteOffset'); end; @@ -365,10 +367,10 @@ var begin s := '23:34:56.78+12:34'; Check(xsd_TryStrToTime(s,d)); - CheckEquals(d.Hour,23,'Hour'); - CheckEquals(d.Minute,34,'Minute'); - CheckEquals(d.Second,56,'Second'); - CheckEquals(d.MilliSecond,78,'MilliSecond'); + CheckEquals(23,d.Hour,'Hour'); + CheckEquals(34,d.Minute,'Minute'); + CheckEquals(56,d.Second,'Second'); + CheckEquals(78,d.MilliSecond,'MilliSecond'); CheckEquals(12,d.HourOffset,'HourOffset'); CheckEquals(34,d.MinuteOffset,'MinuteOffset'); end; @@ -380,10 +382,10 @@ var begin s := '23:34:56.789-01:23'; Check(xsd_TryStrToTime(s,d)); - CheckEquals(d.Hour,23,'Hour'); - CheckEquals(d.Minute,34,'Minute'); - CheckEquals(d.Second,56,'Second'); - CheckEquals(d.MilliSecond,789,'MilliSecond'); + CheckEquals(23,d.Hour,'Hour'); + CheckEquals(34,d.Minute,'Minute'); + CheckEquals(56,d.Second,'Second'); + CheckEquals(789,d.MilliSecond,'MilliSecond'); CheckEquals(-1,d.HourOffset,'HourOffset'); CheckEquals(-23,d.MinuteOffset,'MinuteOffset'); end; @@ -394,7 +396,7 @@ const var d : TDateTimeRec; begin - CheckEquals(False,xsd_TryStrToDate(DATE_STR,d),Format('"%s" is not a valid date.',[DATE_STR])); + CheckEquals(False,xsd_TryStrToDate(DATE_STR,d,xdkDateTime),Format('"%s" is not a valid date.',[DATE_STR])); end; {$IFDEF FPC} @@ -430,17 +432,73 @@ var begin //'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? s := '1976-10-12'; - d := xsd_StrToDate(s); + d := xsd_StrToDate(s,xdkDateTime); DecodeDate(d.Date,y,m,dy); - CheckEquals(y,1976,'Year'); - CheckEquals(m,10,'Month'); - CheckEquals(dy,12,'Day'); + CheckEquals(1976,y,'Year'); + CheckEquals(10,m,'Month'); + CheckEquals(12,dy,'Day'); DecodeTime(d.Date,hh,mn,ss,ssss); - CheckEquals(hh,0,'Hour'); - CheckEquals(mn,0,'Minute'); - CheckEquals(ss,0,'Second'); + CheckEquals(0,hh,'Hour'); + CheckEquals(0,mn,'Minute'); + CheckEquals(0,ss,'Second'); CheckEquals(0,d.HourOffset,'HourOffset'); CheckEquals(0,d.MinuteOffset,'MinuteOffset'); + + d := xsd_StrToDate(s,xdkDate); + DecodeDate(d.Date,y,m,dy); + CheckEquals(1976,y,'Year'); + CheckEquals(10,m,'Month'); + CheckEquals(12,dy,'Day'); + DecodeTime(d.Date,hh,mn,ss,ssss); + CheckEquals(0,hh,'Hour'); + CheckEquals(0,mn,'Minute'); + CheckEquals(0,ss,'Second'); + CheckEquals(0,d.HourOffset,'HourOffset'); + CheckEquals(0,d.MinuteOffset,'MinuteOffset'); +end; + +procedure TTest_DateUtils.xsd_TryStrToDate_date_timezone_1(); +var + s : string; + d : TDateTimeRec; + y,m,dy : Word; + hh,mn,ss, ssss : Word; +begin + //'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? + s := '1976-10-12+11:34'; + d := xsd_StrToDate(s,xdkDate); + DecodeDate(d.Date,y,m,dy); + CheckEquals(1976,y,'Year'); + CheckEquals(10,m,'Month'); + CheckEquals(12,dy,'Day'); + DecodeTime(d.Date,hh,mn,ss,ssss); + CheckEquals(0,hh,'Hour'); + CheckEquals(0,mn,'Minute'); + CheckEquals(0,ss,'Second'); + CheckEquals(11,d.HourOffset,'HourOffset'); + CheckEquals(34,d.MinuteOffset,'MinuteOffset'); +end; + +procedure TTest_DateUtils.xsd_TryStrToDate_date_timezone_2(); +var + s : string; + d : TDateTimeRec; + y,m,dy : Word; + hh,mn,ss, ssss : Word; +begin + //'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? + s := '1976-10-12-11:34'; + d := xsd_StrToDate(s,xdkDate); + DecodeDate(d.Date,y,m,dy); + CheckEquals(1976,y,'Year'); + CheckEquals(10,m,'Month'); + CheckEquals(12,dy,'Day'); + DecodeTime(d.Date,hh,mn,ss,ssss); + CheckEquals(0,hh,'Hour'); + CheckEquals(0,mn,'Minute'); + CheckEquals(0,ss,'Second'); + CheckEquals(-11,d.HourOffset,'HourOffset'); + CheckEquals(-34,d.MinuteOffset,'MinuteOffset'); end; procedure TTest_DateUtils.xsd_TryStrToDate_date_time(); @@ -452,15 +510,15 @@ var begin //'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? s := '1976-10-12T23:34:56'; - d := xsd_StrToDate(s); + d := xsd_StrToDate(s,xdkDateTime); DecodeDate(d.Date,y,m,dy); - CheckEquals(y,1976,'Year'); - CheckEquals(m,10,'Month'); - CheckEquals(dy,12,'Day'); + CheckEquals(1976,y,'Year'); + CheckEquals(10,m,'Month'); + CheckEquals(12,dy,'Day'); DecodeTime(d.Date,hh,mn,ss,ssss); - CheckEquals(hh,23,'Hour'); - CheckEquals(mn,34,'Minute'); - CheckEquals(ss,56,'Second'); + CheckEquals(23,hh,'Hour'); + CheckEquals(34,mn,'Minute'); + CheckEquals(56,ss,'Second'); CheckEquals(0,d.HourOffset,'HourOffset'); CheckEquals(0,d.MinuteOffset,'MinuteOffset'); end; @@ -471,7 +529,7 @@ const var d : TDateTimeRec; begin - CheckEquals(False,xsd_TryStrToDate(DATE_STR,d),Format('"%s" is not a valid date.',[DATE_STR])); + CheckEquals(False,xsd_TryStrToDate(DATE_STR,d,xdkDateTime),Format('"%s" is not a valid date.',[DATE_STR])); end; procedure TTest_DateUtils.xsd_TryStrToDate_date_time_fractional_second(); @@ -486,7 +544,7 @@ procedure TTest_DateUtils.xsd_TryStrToDate_date_time_fractional_second(); y,m,dy : Word; hh,mn,ss, ssss : Word; begin - d := xsd_StrToDate(AString); + d := xsd_StrToDate(AString,xdkDateTime); DecodeDate(d.Date,y,m,dy); CheckEquals(AY,y,'Year'); CheckEquals(AM,m,'Month'); @@ -519,7 +577,7 @@ var begin //'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? s := '1976-10-12T23:34:56+12:34'; - d := xsd_StrToDate(s); + d := xsd_StrToDate(s,xdkDateTime); DecodeDate(d.Date,y,m,dy); CheckEquals(y,1976,'Year'); CheckEquals(m,10,'Month'); @@ -541,7 +599,7 @@ var begin //'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? s := '1976-10-12T23:34:56-01:23'; - d := xsd_StrToDate(s); + d := xsd_StrToDate(s,xdkDateTime); DecodeDate(d.Date,y,m,dy); CheckEquals(y,1976,'Year'); CheckEquals(m,10,'Month'); @@ -563,7 +621,7 @@ var begin //'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? s := '1976-10-12T23:34:56Z'; - d := xsd_StrToDate(s); + d := xsd_StrToDate(s,xdkDateTime); DecodeDate(d.Date,y,m,dy); CheckEquals(y,1976,'Year'); CheckEquals(m,10,'Month'); @@ -585,7 +643,7 @@ var begin //'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? s := '1976-10-12T23:34:56+00:00'; - d := xsd_StrToDate(s); + d := xsd_StrToDate(s,xdkDateTime); DecodeDate(d.Date,y,m,dy); CheckEquals(y,1976,'Year'); CheckEquals(m,10,'Month'); @@ -598,7 +656,7 @@ begin CheckEquals(0,d.MinuteOffset,'MinuteOffset'); s := '1976-10-12T23:34:56-00:00'; - d := xsd_StrToDate(s); + d := xsd_StrToDate(s,xdkDateTime); DecodeDate(d.Date,y,m,dy); CheckEquals(y,1976,'Year'); CheckEquals(m,10,'Month'); diff --git a/wst/trunk/tests/test_suite/test_suite_utils.pas b/wst/trunk/tests/test_suite/test_suite_utils.pas index 55ea6cda0..b5b5642e4 100644 --- a/wst/trunk/tests/test_suite/test_suite_utils.pas +++ b/wst/trunk/tests/test_suite/test_suite_utils.pas @@ -24,7 +24,8 @@ uses const TestFilesPath = {$IFDEF WST_DELPHI}'.' +{$ENDIF WST_DELPHI}'.' + PathDelim + 'files' + PathDelim; - + EPSILON_DATE = 0.00004; + type { TWstBaseTest } diff --git a/wst/trunk/tests/test_suite/test_support.pas b/wst/trunk/tests/test_suite/test_support.pas index 67045633c..6da58d180 100644 --- a/wst/trunk/tests/test_suite/test_support.pas +++ b/wst/trunk/tests/test_suite/test_support.pas @@ -296,9 +296,9 @@ type procedure Equal(); end; - { TTest_TDateRemotable } + { TTest_TDateTimeRemotable } - TTest_TDateRemotable = class(TTestCase) + TTest_TDateTimeRemotable = class(TTestCase) published procedure FormatDate(); procedure FormatDate_ZERO(); @@ -314,6 +314,24 @@ type procedure Year(); end; + { TTest_TDateTimeRemotable } + + TTest_TDateRemotable = class(TTestCase) + published + procedure FormatDate(); + procedure FormatDate_ZERO(); + procedure ParseDate(); + procedure Assign(); + procedure Equal(); + procedure AsDate(); + procedure AsUTCDate(); + procedure HourOffset(); + procedure HourOffset_invalid_values(); + procedure MinuteOffset(); + procedure MinuteOffset_invalid_values(); + procedure Year(); + end; + { TTest_TDurationRemotable } TTest_TDurationRemotable = class(TTestCase) @@ -2240,9 +2258,9 @@ begin end; end; -{ TTest_TDateRemotable } +{ TTest_TDateTimeRemotable } -procedure TTest_TDateRemotable.FormatDate(); +procedure TTest_TDateTimeRemotable.FormatDate(); const sDATE_1 = '1976-10-12T23:34:56'; sDATE_2 = '0987-06-12T20:34:56'; @@ -2251,9 +2269,288 @@ var begin //'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? d := EncodeDate(1976,10,12) + EncodeTime(23,34,56,0); - CheckEquals(sDATE_1, Copy(TDateRemotable.ToStr(d),1,Length(sDATE_1))); + CheckEquals(sDATE_1, Copy(TDateTimeRemotable.ToStr(d),1,Length(sDATE_1))); d := EncodeDate(987,06,12) - EncodeTime(20,34,56,0); + CheckEquals(sDATE_2, Copy(TDateTimeRemotable.ToStr(d),1,Length(sDATE_2))); +end; + +procedure TTest_TDateTimeRemotable.ParseDate(); +var + s : string; + objd : TDateTimeRemotable; + d : TDateTimeRec; + y,m,dy : Word; + hh,mn,ss, ssss : Word; +begin + //'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? + s := '1976-10-12T23:34:56'; + d := TDateTimeRemotable.Parse(s); + DecodeDateTime(d.Date,y,m,dy, hh,mn,ss,ssss); + CheckEquals(1976,y,'Year'); + CheckEquals(10,m,'Month'); + CheckEquals(12,dy,'Day'); + CheckEquals(23,hh,'Hour'); + CheckEquals(34,mn,'Minute'); + CheckEquals(56,ss,'Second'); + + objd := TDateTimeRemotable.Create(); + try + objd.AsDate := d.Date; + CheckEquals(1976,objd.Year,'Year'); + CheckEquals(10,objd.Month,'Month'); + CheckEquals(12,objd.Day,'Day'); + CheckEquals(23,objd.Hour,'Hour'); + CheckEquals(34,objd.Minute,'Minute'); + CheckEquals(56,objd.Second,'Second'); + finally + FreeAndNil(objd); + end; +end; + +procedure TTest_TDateTimeRemotable.Assign(); +var + a, b : TDateTimeRemotable; +begin + b := nil; + a := TDateTimeRemotable.Create(); + try + b := TDateTimeRemotable.Create(); + Check(IsZero(a.AsDate - b.AsDate)); + + a.AsDate := Now(); + b.Assign(a); + Check(IsZero(a.AsDate - b.AsDate)); + + a.AsDate := Now() + 1; + a.Assign(b); + Check(IsZero(a.AsDate - b.AsDate)); + finally + b.Free(); + a.Free(); + end; +end; + +procedure TTest_TDateTimeRemotable.Equal(); +var + a, b : TDateTimeRemotable; + c : TClass_A; +begin + c := nil; + b := nil; + a := TDateTimeRemotable.Create(); + try + b := TDateTimeRemotable.Create(); + c := TClass_A.Create(); + + CheckEquals(False,a.Equal(nil)); + CheckEquals(False,a.Equal(c)); + + a.AsDate := Now(); + b.AsDate := a.AsDate; + CheckEquals(True,a.Equal(b)); + CheckEquals(True,b.Equal(a)); + + a.AsDate := a.AsDate + 1; + CheckEquals(False,a.Equal(b)); + CheckEquals(False,b.Equal(a)); + finally + c.Free(); + b.Free(); + a.Free(); + end; +end; + +procedure TTest_TDateTimeRemotable.FormatDate_ZERO(); +const sDATE = '1899-12-30T00:00:00'; +var + d : TDateTime; +begin + //'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? + d := 0; + CheckEquals(sDATE, Copy(TDateTimeRemotable.ToStr(d),1,Length(sDATE))); +end; + +procedure TTest_TDateTimeRemotable.AsDate(); +var + d : TDateTime; + locObj : TDateTimeRemotable; +begin + d := EncodeDateTime(1976,10,12,13,14,15,0); + locObj := TDateTimeRemotable.Create(); + try + locObj.AsDate := d; + CheckEquals(d, locObj.AsDate); + locObj.HourOffset := 4; + locObj.MinuteOffset := 5; + CheckEquals(d, locObj.AsDate); + + // test while (Hour|Minute)Offset is not null + locObj.HourOffset := 4; + locObj.MinuteOffset := 5; + locObj.AsDate := d; + CheckEquals(d, locObj.AsDate); + finally + locObj.Free(); + end; +end; + +procedure TTest_TDateTimeRemotable.AsUTCDate(); +var + d, dd : TDateTime; + locObj : TDateTimeRemotable; +begin + d := EncodeDateTime(1976,10,12,13,14,15,0); + locObj := TDateTimeRemotable.Create(); + try + locObj.AsUTCDate := d; + CheckEquals(d, locObj.AsUTCDate); + locObj.HourOffset := 4; + locObj.MinuteOffset := 5; + dd := date_utils.IncHour(d,-locObj.HourOffset); + dd := date_utils.IncMinute(dd,-locObj.MinuteOffset); + CheckEquals(dd, locObj.AsUTCDate); + + // test while (Hour|Minute)Offset is not null + locObj.AsUTCDate := dd; + CheckEquals(dd, locObj.AsUTCDate); + finally + locObj.Free(); + end; +end; + +procedure TTest_TDateTimeRemotable.HourOffset(); +var + locObj : TDateTimeRemotable; +begin + locObj := TDateTimeRemotable.Create(); + try + locObj.HourOffset := -5; + CheckEquals(-5, locObj.HourOffset); + locObj.HourOffset := 0; + CheckEquals(0, locObj.HourOffset); + locObj.HourOffset := 1; + CheckEquals(1, locObj.HourOffset); + locObj.HourOffset := 2; + CheckEquals(2, locObj.HourOffset); + finally + locObj.Free(); + end; +end; + +procedure TTest_TDateTimeRemotable.MinuteOffset(); +var + locObj : TDateTimeRemotable; +begin + locObj := TDateTimeRemotable.Create(); + try + locObj.MinuteOffset := -54; + CheckEquals(-54, locObj.MinuteOffset); + locObj.MinuteOffset := 0; + CheckEquals(0, locObj.MinuteOffset); + locObj.MinuteOffset := 20; + CheckEquals(20, locObj.MinuteOffset); + locObj.MinuteOffset := 56; + CheckEquals(56, locObj.MinuteOffset); + finally + locObj.Free(); + end; +end; + +procedure TTest_TDateTimeRemotable.HourOffset_invalid_values(); +var + locObj : TDateTimeRemotable; + + procedure check_invalid_value(const AValue : ShortInt); + var + ok : Boolean; + begin + try + locObj.HourOffset := AValue; + ok := False; + except + ok := True; + end; + Check(ok, Format('"%d" is not a valid hour offset',[AValue])); + end; + +begin + locObj := TDateTimeRemotable.Create(); + try + check_invalid_value(-50); + check_invalid_value(-24); + check_invalid_value(-15); + check_invalid_value(15); + check_invalid_value(24); + check_invalid_value(50); + finally + locObj.Free(); + end; +end; + +procedure TTest_TDateTimeRemotable.MinuteOffset_invalid_values(); +var + locObj : TDateTimeRemotable; + + procedure check_invalid_value(const AValue : ShortInt); + var + ok : Boolean; + begin + try + locObj.MinuteOffset := AValue; + ok := False; + except + ok := True; + end; + Check(ok, Format('"%d" is not a valid minute offset',[AValue])); + end; + +begin + locObj := TDateTimeRemotable.Create(); + try + check_invalid_value(-60); + check_invalid_value(-74); + check_invalid_value(-85); + check_invalid_value(65); + check_invalid_value(74); + check_invalid_value(80); + finally + locObj.Free(); + end; +end; + +procedure TTest_TDateTimeRemotable.Year(); +var + locObj : TDateTimeRemotable; +begin + locObj := TDateTimeRemotable.Create(); + try + locObj.AsDate := EncodeDate(1976,10,12); + CheckEquals(1976, locObj.Year); + locObj.AsDate := EncodeDate(2000,10,12); + CheckEquals(2000, locObj.Year); + locObj.AsDate := EncodeDate(2,10,12); + CheckEquals(2, locObj.Year); + {locObj.AsDate := EncodeDate(-1976,10,12); + CheckEquals(-1976, locObj.Year);} + finally + locObj.Free(); + end; +end; + +{ TTest_TDateRemotable } + +procedure TTest_TDateRemotable.FormatDate(); +const + sDATE_1 = '1976-10-12'; + sDATE_2 = '0987-06-12'; +var + d : TDateTime; +begin + d := EncodeDate(1976,10,12); + CheckEquals(sDATE_1, Copy(TDateRemotable.ToStr(d),1,Length(sDATE_1))); + + d := EncodeDate(987,06,12); CheckEquals(sDATE_2, Copy(TDateRemotable.ToStr(d),1,Length(sDATE_2))); end; @@ -2265,26 +2562,19 @@ var y,m,dy : Word; hh,mn,ss, ssss : Word; begin - //'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? - s := '1976-10-12T23:34:56'; + s := '1976-10-12'; d := TDateRemotable.Parse(s); DecodeDateTime(d.Date,y,m,dy, hh,mn,ss,ssss); - CheckEquals(y,1976,'Year'); - CheckEquals(m,10,'Month'); - CheckEquals(dy,12,'Day'); - CheckEquals(hh,23,'Hour'); - CheckEquals(mn,34,'Minute'); - CheckEquals(ss,56,'Second'); + CheckEquals(1976,y,'Year'); + CheckEquals(10,m,'Month'); + CheckEquals(12,dy,'Day'); objd := TDateRemotable.Create(); try objd.AsDate := d.Date; - CheckEquals(objd.Year,1976,'Year'); - CheckEquals(objd.Month,10,'Month'); - CheckEquals(objd.Day,12,'Day'); - CheckEquals(objd.Hour,23,'Hour'); - CheckEquals(objd.Minute,34,'Minute'); - CheckEquals(objd.Second,56,'Second'); + CheckEquals(1976,objd.Year,'Year'); + CheckEquals(10,objd.Month,'Month'); + CheckEquals(12,objd.Day,'Day'); finally FreeAndNil(objd); end; @@ -2300,11 +2590,11 @@ begin b := TDateRemotable.Create(); Check(IsZero(a.AsDate - b.AsDate)); - a.AsDate := Now(); + a.AsDate := Date(); b.Assign(a); Check(IsZero(a.AsDate - b.AsDate)); - a.AsDate := Now() + 1; + a.AsDate := Date() + 1; a.Assign(b); Check(IsZero(a.AsDate - b.AsDate)); finally @@ -2328,7 +2618,7 @@ begin CheckEquals(False,a.Equal(nil)); CheckEquals(False,a.Equal(c)); - a.AsDate := Now(); + a.AsDate := Date(); b.AsDate := a.AsDate; CheckEquals(True,a.Equal(b)); CheckEquals(True,b.Equal(a)); @@ -2344,11 +2634,10 @@ begin end; procedure TTest_TDateRemotable.FormatDate_ZERO(); -const sDATE = '1899-12-30T00:00:00'; +const sDATE = '1899-12-30'; var d : TDateTime; begin - //'-'? yyyy '-' mm '-' dd 'T' hh ':' mm ':' ss ('.' s+)? (zzzzzz)? d := 0; CheckEquals(sDATE, Copy(TDateRemotable.ToStr(d),1,Length(sDATE))); end; @@ -2358,7 +2647,7 @@ var d : TDateTime; locObj : TDateRemotable; begin - d := EncodeDateTime(1976,10,12,13,14,15,0); + d := EncodeDate(1976,10,12); locObj := TDateRemotable.Create(); try locObj.AsDate := d; @@ -2382,7 +2671,7 @@ var d, dd : TDateTime; locObj : TDateRemotable; begin - d := EncodeDateTime(1976,10,12,13,14,15,0); + d := EncodeDate(1976,10,12); locObj := TDateRemotable.Create(); try locObj.AsUTCDate := d; @@ -2395,7 +2684,7 @@ begin // test while (Hour|Minute)Offset is not null locObj.AsUTCDate := dd; - CheckEquals(dd, locObj.AsUTCDate); + CheckEquals(dd, locObj.AsUTCDate,EPSILON_DATE); finally locObj.Free(); end; @@ -4013,6 +4302,7 @@ initialization RegisterTest('Support',TTest_TObjectCollectionRemotable.Suite); RegisterTest('Support',TTest_TBaseComplexRemotable.Suite); RegisterTest('Support',TTest_TStringBufferRemotable.Suite); + RegisterTest('Support-Date',TTest_TDateTimeRemotable.Suite); RegisterTest('Support-Date',TTest_TDateRemotable.Suite); RegisterTest('Support-Date',TTest_TDurationRemotable.Suite); RegisterTest('Support-Date',TTest_TTimeRemotable.Suite); diff --git a/wst/trunk/tests/test_suite/testformatter_unit.pas b/wst/trunk/tests/test_suite/testformatter_unit.pas index 03ea8b074..b96774b02 100644 --- a/wst/trunk/tests/test_suite/testformatter_unit.pas +++ b/wst/trunk/tests/test_suite/testformatter_unit.pas @@ -42,7 +42,8 @@ type private FVal_32S: LongInt; FVal_Bool: Boolean; - FVal_Date: TDateRemotable; + FVal_Date : TDateRemotable; + FVal_DateTime: TDateTimeRemotable; FVal_Enum: TTestEnum; FVal_String: string; FVal_Time : TTimeRemotable; @@ -62,6 +63,7 @@ type {$IFDEF WST_UNICODESTRING} property Val_UnicodeString : UnicodeString Read FVal_UnicodeString Write FVal_UnicodeString; {$ENDIF WST_UNICODESTRING} + property Val_DateTime : TDateTimeRemotable read FVal_DateTime write FVal_DateTime; property Val_Date : TDateRemotable read FVal_Date write FVal_Date; property Val_Time : TTimeRemotable read FVal_Time write FVal_Time; End; @@ -2945,6 +2947,7 @@ end; procedure TTestFormatter.Test_Object(); const DATE_VALUE = 39000; + DATETIME_VALUE = 39000.1234; TIME_VALUE = '01:23:45.789Z'; Var f : IFormatterBase; @@ -2964,6 +2967,7 @@ begin {$ENDIF WST_UNICODESTRING} a.ObjProp.Val_String := '456'; a.ObjProp.Val_WideString := 'wide456'; + a.ObjProp.Val_DateTime.AsDate := DATETIME_VALUE; a.ObjProp.Val_Date.AsDate := DATE_VALUE; a.ObjProp.Val_Time.AsString := TIME_VALUE; {$IFDEF WST_UNICODESTRING} @@ -2981,7 +2985,7 @@ begin f.EndScope(); s := TMemoryStream.Create(); - f.SaveToStream(s); + f.SaveToStream(s); FreeAndNil(a); a := TClass_B.Create(); @@ -3006,6 +3010,7 @@ begin CheckEquals(Ord(teFour),Ord(a.ObjProp.Val_Enum)); CheckEquals('456',a.ObjProp.Val_String); CheckEquals(WideString('wide456'),a.ObjProp.Val_WideString); + CheckEquals(TDateTimeRemotable.ToStr(DATETIME_VALUE),TDateTimeRemotable.ToStr(a.ObjProp.Val_DateTime.AsDate)); CheckEquals(TDateRemotable.ToStr(DATE_VALUE),TDateRemotable.ToStr(a.ObjProp.Val_Date.AsDate)); CheckEquals(TIME_VALUE,a.ObjProp.Val_Time.AsString); {$IFDEF WST_UNICODESTRING} @@ -4657,7 +4662,7 @@ begin Check( ls.IndexOf('intv') >= 0 ); x := 'a'; f.BeginObjectRead(x,TypeInfo(TClass_A)); - CheckEquals(7{$IFDEF WST_UNICODESTRING}+1{$ENDIF}, f.GetScopeItemNames(ls), 'GetScopeItemNames.Count(a)'); + CheckEquals(8{$IFDEF WST_UNICODESTRING}+1{$ENDIF}, f.GetScopeItemNames(ls), 'GetScopeItemNames.Count(a)'); Check( ls.IndexOf('Val_Bool') >= 0 ); Check( ls.IndexOf('Val_Enum') >= 0 ); Check( ls.IndexOf('Val_String') >= 0 ); @@ -4666,7 +4671,7 @@ begin x := 'b'; f.BeginObjectRead(x,TypeInfo(TClass_A)); - CheckEquals(7{$IFDEF WST_UNICODESTRING}+1{$ENDIF}, f.GetScopeItemNames(ls), 'GetScopeItemNames.Count(b)'); + CheckEquals(8{$IFDEF WST_UNICODESTRING}+1{$ENDIF}, f.GetScopeItemNames(ls), 'GetScopeItemNames.Count(b)'); Check( ls.IndexOf('Val_Bool') >= 0 ); Check( ls.IndexOf('Val_Enum') >= 0 ); Check( ls.IndexOf('Val_String') >= 0 ); @@ -4755,6 +4760,7 @@ end; procedure TTestSOAPFormatter.do_test_Object(const AProps, AFilename: string); const DATE_VALUE = 39000; + DATETIME_VALUE = 39000.1234; TIME_VALUE = '01:23:45.789Z'; Var f : IFormatterBase; @@ -4774,6 +4780,7 @@ begin {$ENDIF WST_UNICODESTRING} a.ObjProp.Val_String := '456'; a.ObjProp.Val_WideString := 'wide456'; + a.ObjProp.Val_DateTime.AsDate := DATETIME_VALUE; a.ObjProp.Val_Date.AsDate := DATE_VALUE; a.ObjProp.Val_Time.AsString := TIME_VALUE; {$IFDEF WST_UNICODESTRING} @@ -4794,8 +4801,8 @@ begin s := TMemoryStream.Create(); f.SaveToStream(s); FreeAndNil(a); - //if not IsStrEmpty(AFilename) then - //s.SaveToFile(wstExpandLocalFileName(AFilename)); + if not IsStrEmpty(AFilename) then + s.SaveToFile(wstExpandLocalFileName(AFilename)); a := TClass_B.Create(); f := CreateFormatter(TypeInfo(TClass_B)); @@ -4820,6 +4827,7 @@ begin CheckEquals(Ord(teFour),Ord(a.ObjProp.Val_Enum)); CheckEquals('456',a.ObjProp.Val_String); CheckEquals(WideString('wide456'),a.ObjProp.Val_WideString); + CheckEquals(TDateTimeRemotable.ToStr(DATETIME_VALUE),TDateTimeRemotable.ToStr(a.ObjProp.Val_DateTime.AsDate)); CheckEquals(TDateRemotable.ToStr(DATE_VALUE),TDateRemotable.ToStr(a.ObjProp.Val_Date.AsDate)); {$IFDEF WST_UNICODESTRING} CheckEquals('unicode456',a.ObjProp.Val_UnicodeString); @@ -6297,6 +6305,7 @@ end; constructor TClass_A.Create(); begin inherited Create(); + FVal_DateTime := TDateTimeRemotable.Create(); FVal_Date := TDateRemotable.Create(); FVal_Time := TTimeRemotable.Create(); end; @@ -6305,6 +6314,7 @@ destructor TClass_A.Destroy(); begin FreeAndNil(FVal_Time); FreeAndNil(FVal_Date); + FreeAndNil(FVal_DateTime); inherited Destroy(); end;