BUG correction in Delphi 6 SOAP source code

zhaozj2021-02-17  49

BUG correction in Delphi 6 SOAP source code

Recently I was using Delphi 6 to make a project about SOAP, and the tracked source code found some bugs in the source code of Delphi 6 when debugging the program :(

In the xsbuiltins.pas file below the Delphi / Source / SOAP directory, the 438th line is as follows:

Procedure TXSDATE.XSTONATIVE (Value: WideString);

VAR

Tempdate: TDATETIME;

Begin

Fadditionaleardigits: = POS (XmLDateseParetor, Value) - (1 XmldefaultyearDigits);

Tempdate: = strtodate (xmldatetostr (value, fadditionalAardIgits); // Note this line of code

Decodedate (Tempdate, Fyear, Fmonth, FDAY);

END;

Among them, an XMLDATETOSTR function is called, the following is the code of the function (in the 241 line of xsbuiltins.pas):

Function XmldateTostr (adode: wideString; adddigits: word = 0): WideString;

Begin

Result: = Copy (Adate, XMLMONTHPOS AddDigits, 2) DateSeparetor

Copy (Adate, XmLDayPOS AddDigits, 2)

Dateseparator Copy (Adate, XMlyearpos, XmldefaultyearDigits AddDigits);

END;

Note that the date format returned by XMLDATETOSTR is MM-DD-YYYY. For example, if passing the parameter addate = '2001-12-08', the result of XMLDATETOSTR ('2001-12-08', 0) is '12 -08-2001 '. The second parameter of XMLDATETOSTR adddigits is the number of digits of extra age. It is estimated to solve the problem of millennium, and the standard 10-bit date format AddDigits is always 0.

Now the problem is coming, go back to Xstonative code, this line code:

Tempdate: = Strtodate (XmldateTstr (Value, FadditionalEardIgits);

The return value of the function XMLDateTostr is called the Strtodate this function. The function of the function start is to transform the string to the date. The parameter of this function should be a string representing the date, but the character string format of the date must meet the current platform. Regional settings, such as the short date of our common Chinese platform, is generally YYYY-MM-DD, and the English platform is generally MM-DD-YYYY, so if you call strTodate () on the Chinese platform to format a format " "MM-DD-YYYY" strings will generate a date format error! !

Here is the content of the STRTODATE function in the help of Delphi:

Function Strtodate (const s: string): TDATETIME;

Description

Call Strtodate to Parse A String That Specifies a Date. If S Does Not Contain A Valid Date,

STRTODATE RAISES An EconvertERROR Exception.s Must Consist of Two or Three Numbers, Separated by The CharacterDefined by The Dateseparator Global Variable.

THE ORDER for Month, Day, And Year Is Determined by The ShortdateFormat Global Variable - Possible

Combinations are m / d / y, d / m / y, AND Y / m / d.

Process decodedate (Tempdate, fyear, fmonth, fday); last line code

Decodedate (Tempdate, Fyear, Fmonth, FDAY);

The role is to resolve Tempdate into fyear, fmonth, and fday, in fact, you can resolve these three domains directly from the date represented by the original string, so you can solve this bug slightly.

The specific approach is to change the function that starts with the 433th line in the xsbuiltins.pas file below the Delphi / SOURCE / SOAP directory.

Procedure TXSDATE.XSTONATIVE (Value: WideString);

Begin

Fadditionaleardigits: = POS (XmLDateseParetor, Value) - (1 XmldefaultyearDigits);

Try

Fyear: = STRTOINT (Copy (Value, XMlyearpos, XmldefaultyearDigits FadditionalEardIgits);

FMONTH: = StrtOINT (Copy (Value, XmLDayPos FadditionalEardIgits, 2);

FDAY: = STRTOINT (Copy (Value, XMLMONTHPOS FADDitionAlYardigits, 2));

Except

Raise econverterror.createresfmt (@sinvaliddate, [value]);

END;

END;

In the beginning of the file xsbuiltins.pas, add

Interface

Uses sysutils, invokeregistry, sysconst; // plus sysconst, because resource string SINVALIDDATE is defined in sysConst.pas

In addition, in the xsbuiltins.pas file below the Delphi / Source / SOAP directory, the following functions:

// Get Small Int Using Digits in Value, Positive or NEGATIVE.

Function IntfromValue (Value: WideString; Digits: Integer): SMALLINT; Begin

Result: = 0;

IF value [1] = '-' THEN

Result: = STRTOINT (VALUE)

Else if value <> '' THEN

Result: = STRTOINT (Copy (Value, 1, DIGITS);

END;

Very obvious BUG! If the parameter value = '' is executed to IF value [1] = '-' Ten .. An error: (In fact, I encountered this in the process of my program, when SOAP passes the date time passed through XML When there is no millisecond field including time, it will encounter a case where IntFromValue is called. The function after modification should be as follows:

// modified by starfish

Function IntfromValue (Value: WideString; Digits: Integer): Smallint

Begin

IF value = '' THEN

Result: = 0

Else if Value [1] = '-' Then

Result: = STRTOINT (VALUE)

Else

Result: = STRTOINT (Copy (Value, 1, DIGITS);

END;

Moreover

Function TXSTIME.GETASTIME: TDATETIME;

Function TXSDATE.GETASDATE: TDATETIME;

Function TXSCUSTOMDATETIME.GETASDATETIME: TDATETIME

There are also BUGs that I have previously said, and programmers who write this code have forgotten the datetime format will be different from different systems. Below is the xsbuiltins.pas file I have completely modified, and all the modified places have been annotated.

Note: I can't guarantee that the code after my revised code must be completely correct, but I can affirm that there are many bugs in its original code!

The following modified xsbuiltins.pas file, put it into the Delpi / Source / SOAP / directory overwrite the original files and recompile all SOAP projects.

{********************************************************** ******}

{}

{Borland Delphi Visual Component Library}

{SOAP Support}

{}

{CopyRight (c) 2001 Borland Software Corporation}

{}

{********************************************************** ******}

Unit xsbuiltins;

Interface

// sysconst, dateutils is address by starfish

Uses Sysutils, InvokeRegistry, sysconst, dateutils;

Const

SOAPTIMEPREFIX = 'T';

XmLDateseParetor = '-';

XMLHOFFSETMINUSMARKER = '-';

XMLHOFFSETPLUSMARKER = ' ';

XMLTIMESEPARATOR = ':';

XMLMONTHPOS = 6;

XMLDAYPOS = 9; XMlyearpos = 1;

XMLMilsecpos = 10;

Xmldefaultyeardigits = 4;

XMLDURATIONSTART = 'P';

XMLDURATIONYEAR = 'Y';

XMLDURATIONMONTH = 'm';

XMLDURATIONDAY = 'D';

XMLDURATIONHOUR = 'h';

XMLDURATIONMINUTE = 'm';

XmLdurationSecond = 's';

ResourceString

SINVALIDHOUR = 'Invalid Hour:% d';

SINVALIDMINUTE = 'Invalid Minute:% D';

SINVALIDSECOND = 'INVALID Second:% D';

SINVALIDFRACTIONSECOND = 'Invalid Second:% F';

SINVALIDMILLISECOND = 'Invalid MilliseCond:% D';

SINVALIDHOUROFFSET = 'Invalid Hour Offset:% D';

SINVALIDDAY = 'INVALID DAY:% D';

SINVALIDMONTH = 'INVALID MONTH:% D';

SINVALIDDURATION = 'Invalid Duration String:% s';

Type

{forward declaratives}

TXSDURATION = Class;

TXSTIME = Class;

TXSDATE = Class;

TXSDATETIME = Class;

{TxStime}

TXSTIME = Class (TremotableXS)

Private

FHOUR: WORD;

Fminute: Word;

FSecond: Word;

FmilliseCond: Word;

FHOUROFFSET: smallint;

FminuteOffset: smallint;

Function Buildhouroffset: WideString;

protected

Function GetAstime: TDATETIME;

Procedure setAstime (Value: tdatetime);

Procedure set (const value: word);

Procedure Setminute (Const Value: Word);

Procedure setSecond (Const Value: Word);

Procedure setmillisecond (const value: word);

Procedure setHouroffset (Const value: smallint);

Procedure setminuteoffset (Const value: smallint);

public

Function Clone: ​​TXSTIME;

Property Hour: Word Read FHOUR WRITE SETHOUR Default 0;

Property Minute: Word Read Fminute Write Setminute DEFAULT 0;

Property Second: Word Read FSecond Write SetSecond Default 0; Property Millisecond: Word Read FmilliseCond Write SetMilliseCond Default 0;

Property Hourofset: Smallint Read Fharoufset Write SetHOFFSet Default 0;

Property MinuteOffset: Smallint Read FminuteOffset Write setminuteOffset

Procedure xstonative (value: wideString); OVERRIDE;

Function NativeToxs: WideString; Override;

Property Astime: Tdatetime Read GetAstime Write SetAstime;

END;

{TXSDATE}

TXSDATE = Class (TremotableXS)

Private

FadditionalEardigits: Word;

FMONTH: WORD;

FDAY: WORD;

Fyear: Word;

FMaxDay: Word;

Fmaxmonth: Word;

FMINDAY: WORD;

FMINMONTH: WORD;

protected

Function Getasdate: TDATETIME;

Procedure setasdate (Value: tdatetime);

Procedure setmonth (Const value: Word);

Procedure setDay (const value: word);

Procedure setYear (Const value: Word);

Property MaxDay: Word Read Fmaxday Write Fmaxday;

Property Maxmonth: Word Read Fmaxmonth Write FmaxMonth;

Property MINDAY: Word Read FMinday Write FMinday;

Property MinMonth: Word Read FMINMONTH WRITE FMINMONTH;

public

CONSTRUCTOR CRETE; OVERRIDE;

Property Month: Word Read Fmonth Write SetMonth Default 0;

Property Day: Word Read FDAY WRITE SETDAY DEFAULT 0;

Property Year: Word Read Fyear Write SetYear Default 0;

Function Clone: ​​TXSDATE;

Procedure xstonative (value: wideString); OVERRIDE;

Function NativeToxs: WideString; Override;

Property Asdate: TDATETIME READ Getasdate Write SetAsdate;

END;

{TXSCUSTOMDATETIME}

TXSCUSTOMDATETIME = Class (TREMOTABLEXS)

Private

FDATEPARAM: TXSDATE;

FTIMEPARAM: TXSTIME;

protected

Function GetasDateTime: TDATETIME;

Function gethour: Word;

Function getminute: Word;

Function GetSecond: Word;

Function GetMonth: Word;

Function Getday: Word; Function GetYear: Word;

Function getMillisecond: Word;

Function Gethouroffset: smallint;

Function getminuteOffset: smallint;

Procedure setasDatetime (value: tdatetime);

Procedure set (const value: word); virtual;

Procedure setminute (const value: word); virtual;

Procedure setsecond (const value: word); virtual;

Procedure setmillisecond (const value: word); virtual;

Procedure setHouroffset; virtual;

Procedure setminuteOffset; virtual;

Procedure setMonth; virtual;

Procedure setDay (const value: word); virtual;

Procedure setYear (const value: word); virtual;

public

CONSTRUCTOR CRETE; OVERRIDE;

DESTRUCTOR DESTROY; OVERRIDE;

Property Asdatetime: TDATETIME READ GetASdateTime Write SetAsDateTime;

Property Hour: Word Read Gethour Write SetHour Default 0;

Property Minute: Word ReadMinute Write Setminute Default 0;

Property Second: Word Read GetSecond Write SetSecond Default 0;

// the folowing line is address by starfish

Property Millisecond: Word ReadMilliseCond Write SetMilliseCond Default 0;

Property Month: Word ReadMonth Write SetMonth Default 0;

Property Day: Word ReadDay Write setday default 0;

Property Year: Word Read getyear Write setYear Default 0;

END;

{TXSDATETIME}

TXSDATETIME = Class (TXSCUSTOMDATETIME)

Private

Function ValidValue (Value, Subtract, Min, Max: Integer; Var Remainder: Integer;

public

Function ComparedateTimeParam (Const Value1, Value2: TxsDateTime): TXSDURATION;

public

Function Clone: ​​TXSDATETIME;

Property Millisecond: Word ReadMilliseCond Write SetMilliseCond Default 0;

Property Houroffset: Smallint Read Gethouroffset Write setOffset Default 0;

Property MinuteOffset: Smallint ReadGETMINUTEOFFSET WRITE SETMINUTEOFFSET DEFAULT 0; Procedure Xstonative (Value: WideString); OVERRIDE

Function NativeToxs: WideString; Override;

END;

TXSDURATION = Class (TXSCustomDateTime)

Private

FDECIMALSECOND: DOUBLE;

Function getDecimalvalue (const APARAM: STRING; Const atype: string): Double;

Function GetIntegerValue (const APARAM: STRING; Const atYpe: String): Integer;

Function GetNuMERICSTRING (Const APARAM: STRING;

Const Decimals: boolean = false: WideString;

protected

Procedure setDecimalsecond (const value: double);

public

CONSTRUCTOR CRETE; OVERRIDE;

Procedure xstonative (value: wideString); OVERRIDE;

Function NativeToxs: WideString; Override;

Property Decimalsecond: Double Read FDecimalsecond Write setDecimalsecond;

END;

EXSDATETIMEEXCEPTION = Class (Exception);

{Utility function}

Function datetimetoxdatetime (value: tdatetime; calclocalbias: boolean = false): TXSDATETIME

IMPLEMENTATION

Uses soapconst, windows;

{EXCEPTION ROUTINES}

Procedure SOAPDATETIMEERROR (Const Message: String); Local

Begin

Raise EXSDATETIMEEXCEPTION.CREATE (Message);

END;

Procedure SoapdateTimeErrorfmt (const message: string; local;

Begin

SOAPDATETIMEERROR (Format (Message, Args));

END;

{Utility functions}

Procedure AdduTCBIAS (VAR DATETIME: TXSDATETIME);

VAR

INFO: TTIMEZONEINFORMATION;

Status: DWORD;

Begin

Status: = GetTimeZoneInformation (Info);

IF (status = time_zone_id_unknown) or (status = time_zone_id_invalid) THEN

SoapDatetimeError (SINVALIDTIMEZONE);

DateTime.Houroffset: = Info.Bias Div 60;

DateTime.minuteOffset: = Info.bias - (DateTime.Houroffset * 60);

END;

Function datetimetoxdatetime (value: tdatetime; calclocalbias: boolean = false): txsdatetime; begin

Result: = txsdatetime.create;

Result.asdatetime: = value;

IF CalClocalbias Then

Addutcbias (Result);

END;

Procedure Parsexmldate (Adate: WideString; VAR Year, Month, Day: Word);

Begin

Year: = StrtOINT (Copy (Adate, XMlyearpos, 4));

Month: = StrtOINT (Copy (Adate, XMLMONTHPOS, 2));

Day: = STRTOINT (Copy (Adate, XmLDayPos, 2));

END;

Function XmldateTostr (adode: wideString; adddigits: word = 0): WideString;

Begin

Result: = Copy (Adate, XMLMONTHPOS AddDigits, 2) DateSeparetor

Copy (Adate, XmLDayPOS AddDigits, 2)

Dateseparator Copy (Adate, XMlyearpos, XmldefaultyearDigits AddDigits);

END;

{The Following Code Has A Bug, Modified by Starfish

// Get Small Int Using Digits in Value, Positive or Negative. Function IntFromValue (Value: WideString; Digits: Integer): Smallint; Begin

Result: = 0;

IF value [1] = '-' THEN

Result: = STRTOINT (VALUE)

Else if value <> '' THEN

Result: = STRTOINT (Copy (Value, 1, DIGITS);

END;

}

// modified by starfish

Function IntfromValue (Value: WideString; Digits: Integer): Smallint

Begin

IF value = '' THEN

Result: = 0

Else if Value [1] = '-' Then

Result: = STRTOINT (VALUE)

Else

Result: = STRTOINT (Copy (Value, 1, DIGITS);

END;

{TxStime}

Function TXSTIME.CLONE: TXSTIME;

Begin

Result: = txstime.create;

Result.Hour: = HOUR;

Result.minute: = minute;

Result.second: = Second;

Result.millisecond: = MilliseCond;

Result.Houroffset: = Houroffset;

Result.minuteOffset: = minuteoffset;

END;

Procedure TXSTIME.SETHOUR (Const Value: Word); Begin

IF value

FHOUR: = Value

Else

SoapDatetimeErrorfmt (SINVALIDHOUR, [VALUE]);

END;

Procedure TXSTIME.SETMINUTE (Const Value: Word);

Begin

IF value <60 THEN

Fminute: = value

Else

SoapdatetimeErrorfmt (SINVALIDMINUTE, [VALUE]);

END;

Procedure TXSTIME.SETSECOND (Const Value: Word);

Begin

IF value <60 THEN

Fsecond: = Value

Else

SoapDatetimeErrorfmt (SINVALIDSECOND, [VALUE]);

END;

Procedure TXSTIME.SETMILLISECOND (Const Value: Word);

Begin

IF value <1000 Then

Fmillisecond: = Value

Else

SoapDatetimeErrorfmt (SINVALIDMILLISECOND, [VALUE]);

END;

Procedure TXSTIME.SETHOUROFFSET (Const Value: Smallint);

Begin

IF ABS (Value) <= (Hoursperday Div 2) THEN

FHOUROFFSET: = Value

Else

SoapDatetimeErrorfmt (SINVALIDHOUROFFSET, [VALUE]);

END;

Procedure TXSTIME.SETMINUTEOFFSET (Const Value: Smallint);

Begin

IF ABS (Value) <60 THEN

FminuteOffset: = value

Else

SoapdatetimeErrorfmt (SINVALIDMINUTE, [VALUE]);

END;

Procedure TXSTIME.XSTONATIVE (Value: WideString);

VAR

Tempvalue: wideString;

Temptime: TDATETIME;

HouroffSetpos: integer;

Begin

Tempvalue: = StringReplace (Copy (Value, 1, 8), XMLTIMESEPARATOR, TIMESEPARATOR, []);

Temptime: = startIME (TEMPVALUE);

Decodetime (Temptime, FHOUR, FMINUTE, FSECOND, FMILLISECOND);

TempValue: = Copy (Value, Xmlmilsecpos, 3);

Millisecond: = IntFromValue (TempValue, 3);

HouroffSetPos: = POS (Xmlhouroffsetminusmarker, value);

If HouroffSetPos = 0 THEN

HouroffSetPos: = POS (XmlhouroffSetplusmarker, value);

IF HouroffSetPos> 0 THEN

Begin

TempValue: = Copy (Value, HouroffSetPos 1, 2);

Houroffset: = IntfromValue (TempValue, 2); TempValue: = Copy (Value, HouroffSetPos 4, 2);

IF TempValue <> '' THEN

MinuteOffset: = IntFromValue (TempValue, 2);

END;

END;

Function TXSTIME.BUILDHOUROFFSET: WIDESTRING;

VAR

Marker: String;

Begin

IF ABS (HOUROFSET) MinuteOffset <> 0 THEN

Begin

IF Houroffset> 0 Then

Marker: = XmlhouroffSetplusmarker

Else

Marker: = Xmlhouroffsetminusmarker;

Result: = INTOSTR (ABS (HOUROFFSET));

IF ABS (Houroffset) <10 THEN

Result: = '0' Result;

IF ABS (MinuteOffset)> 9 THEN

Result: = Result XMLTIMESEPARATOR INTOSTR (ABS (MinuteOffset))

Else IF ABS (MinuteOffset)> 0 THEN

Result: = Result XMLTIMESEPARATOR '0' INTOSTR (ABS (MINUTEOFFSET))

Else

Result: = Result XMLTIMESEPARATOR '00';

Result: = marker result;

END;

END;

Function TXSTIME.NATIVETOXS: WIDESTRING;

VAR

Temptime: TDATETIME;

Formatstring: String;

Begin

IF Hour Minute Second = 0 THEN EXIT;

Temptime: = Encodetime (Hour, minute, second, millisecond); // Exception thrown if invalid

FormatString: = Format ('hh% snorth% sss.zzz', [xmltimseparator, xmltimseparator]);

Result: = formatdatetime (FormatString, Temptime) Buildhouroffset

END;

Procedure Txstime.setastime (Value: tdatetime);

Begin

Decodetime (Value, FHour, Fminute, FSecond, FmilliseCond);

END;

{The Following Function Has A Bug! Rewrite by Starfish

Function TXSTIME.GETASTIME: TDATETIME;

VAR

TimeString: String;

Colon: String;

Begin

COLON: = TimeseParator;

TimeString: = INTOSTR (HOUR) COLON INTOSTR (Minute) Colon

INTTOSTR (SECOND); Result: = Strtotime (TIMESTRING);

END;

}

Function TXSTIME.GETASTIME: TDATETIME;

Begin

Result: = Encodetime (Hour, Minute, SECOND, MilliseCond);

END;

{TXSDATE}

Constructor TXSDATE.CREATE;

Begin

Inherited Create;

Fmaxmonth: = 12;

FMINMONTH: = 1;

FMaxDay: = 31;

FMINDAY: = 1;

END;

Function TXSDATE.CLONE: TXSDATE;

Begin

Result: = TXSDATE.CREATE;

Result.day: = day;

Result.month: = month;

Result.Year: = year;

END;

Procedure txsdate.setMonth (Const value: Word);

Begin

IF (value <= fmaxmonth) and (value> = fminmonth) THEN

FMONTH: = Value

Else

SoapDatetimeErrorfmt (SINVALIDMONTH, [VALUE]);

END;

Procedure txsdate.setday (const value: word);

Begin

IF (value <= fmaxday) and (value> = fminday) THEN / PERFORM MORE COMPLETE CHECK WHEN ALL VALUES SET

FDAY: = Value

Else

SoapDateTimeErrorfmt (SINVALIDDAY, [VALUE]);

END;

Procedure txsdate.setyear (const value: word);

Begin

Fyear: = Value

END;

// The folowing code has a bug! Rewrite by starfish

{

Procedure TXSDATE.XSTONATIVE (Value: WideString);

VAR

Tempdate: TDATETIME;

Begin

Fadditionaleardigits: = POS (XmLDateseParetor, Value) - (1 XmldefaultyearDigits);

Tempdate: = Strtodate (XmldateTstr (Value, FadditionalEardIgits);

Decodedate (Tempdate, Fyear, Fmonth, FDAY);

END;

}

Procedure TXSDATE.XSTONATIVE (Value: WideString);

Begin

Fadditionaleardigits: = POS (XmLDateseParetor, Value) - (1 XmldefaultyearDigits);

Try

Fyear: = STRTOINT (Copy (Value, XMlyearpos, XmldefaultyearDigits FadditionalEardIgits);

FMONTH: = StrtOINT (Copy (Value, XmLDayPos FadditionalEardIgits, 2);

FDAY: = STRTOINT (Copy (Value, XMLMONTHPOS FADDitionAlYearDigits, 2); Except

Raise econverterror.createresfmt (@sinvaliddate, [value]);

END;

END;

Function TXSDATE.NATIVETOXS: WIDESTRING;

VAR

Tempdate: TDATETIME;

Formatstring: String;

Begin

IF Year Month Day = 0 THEN EXIT;

Tempdate: = encodedate (Year, Month, day); // Exception thrown if invalid

FormatString: = Format ('YYYY% SMM% SDD', [XmLDateseParetor]);

Result: = formatdatetime (FormatString, Tempdate);

END;

{THE FOLLOWING CODE HAS A BUG! REWRITE BY STARFISH

Function TXSDATE.GETASDATE: TDATETIME;

VAR

DateString: String;

Slash: String;

Begin

Slash: = dateseparator;

DateString: = INTOSTR (MONTH) SLASH INTOSTR (DAY) SLASH INTOSTR (YEAR);

Result: = strtodate (dateString);

END;

}

Function TXSDATE.GETASDATE: TDATETIME;

Begin

Result: = Encodedate (Year, Month, Day);

END;

Procedure txsdate.setasdate (Value: tdatetime);

Begin

Decodedate (Value, Fyear, Fmonth, FDAY);

END;

{TXSCUSTOMDATETIME}

Constructor TXSCUSTOMDATETIME.CREATE;

Begin

Inherited Create;

FDATEPARAM: = TXSDATE.CREATE;

FTIMEPARAM: = Txstime.create;

END;

Destructor TXSCUSTOMDATETIME.DESTROY;

Begin

FDATEPARAM.FREE;

FTIMEPARAM.FREE;

Inherited destroy;

END;

Function TXSCUSTOMDATETIME.GETHOUR: WORD;

Begin

Result: = fTimeParam.Hour;

END;

Function TXSCUSTOMDATETIME.GETMINUTE: WORD;

Begin

Result: = fTimeParam.minute;

END;

Function TXSCUSTOMDATETIME.GETSECOND: WORD;

Begin

Result: = fTimeParam.second;

END;

Function TXSCUSTOMDATETIME.GETMILLISECOND: WORD;

Begin

Result: = fTimeParam.milliseCond;

END;

Function TXSCUSTOMDATETIME.GETHOUROFFSET: Smallint; Begin

Result: = fTimeParam.Houroffset;

END;

Function TXSCUSTOMDATETIME.GETMINUTEOFFSET: smallint

Begin

Result: = fTimeParam.minuteOffset;

END;

Function TXSCUSTOMDATETIME.GETMONTH: WORD;

Begin

Result: = fdateParam.month;

END;

Function TXSCUSTOMDATETIME.GETDAY: WORD;

Begin

Result: = fdateParam.day;

END;

Function TXSCUSTOMDATETIME.GETYEAR: WORD;

Begin

Result: = fdateParam.Year;

END;

Procedure TXSCustomDatetime.SetHour (Const Value: Word);

Begin

FTIMEPAram.sethour (Value);

END;

Procedure TXSCustomDatetime.Setminute (const value: word);

Begin

FTIMEPAram.Setminute (Value);

END;

Procedure TXSCUScustomDatetime.setSecond (Const Value: Word);

Begin

FTIMEPAram.SetSecond (Value);

END;

Procedure TXSCustomDatetime.SETMILLISECOND (Const Value: Word);

Begin

FtimeParam.SetMillisecond (Value);

END;

Procedure TXSCUSTOMDATETIME.SETHOUROFFSET (Const Value: Smallint);

Begin

FTIMEPAram.SetHOUROFFSET (Value);

END;

Procedure txscustomDatetime.setminuteOffset (const value: smallint);

Begin

FTIMEPAram.SetminuteOffset (Value);

END;

Procedure TXSCUScustomDatetime.SetMonth (Const Value: Word);

Begin

FDATEPARAM.SETMONTH (VALUE);

END;

Procedure TXSCustomDatetime.setday (const value: word);

Begin

FdateParam.Setday (Value);

END;

Procedure TXSCustomDatetime.setyear (Const Value: Word);

Begin

FdateParam.SetyEar (Value);

END;

Procedure txscustomDatetime.setAsettime (Value: tdatetime);

Begin

FdateParam.asdate: = value;

FTIMEPARAM.AStime: = Value;

END;

{The Following Code Has A Bug, Modified by Starfish

Function TXSCUSTOMDATETIME.GETASDATETIME: TDATETIME

VAR

DateString: String;

Slash: String;

Colon: String;

Begin

Slash: = dateseparator; colon: = timeseparator;

DateString: = INTOSTR (MONTH) SLASH INTSTR (DAY) SLASH INTOSTR (YEAR)

'' INTOSTR (HOUR) COLON INTOSTR (Minute) Colon

INTOSTR (SECOND);

Result: = stratodatetime (dateString);

END;

}

Function TXSCUSTOMDATETIME.GETASDATETIME: TDATETIME

Begin

Result: = EncodeDateTime (Year, Month, Day, Hour, Minute, Second, MilliseCond);

END;

{TXSDATETIME}

Function TXSDATETIME.CLONE: TXSDATETIME;

Begin

Result: = txsdatetime.create;

Result.fdateParam.day: = day;

Result.fdateParam.month: = Month;

Result.fdateParam.Year: = year;

Result.ftimeParam.Hour: = HOUR;

Result.ftimeParam.minute: = minute;

Result.ftimeparam.second: = second;

Result.ftimeParam.Millisecond: = MilliseCond;

Result.ftimeParam.Houroffset: = HOUROFFSET;

Result.ftimeParam.minuteOffset: = minuteoffset;

END;

Procedure TXSDatetime.xstonative (Value: WideString);

VAR

TimeString, DateString: WideString;

TimePosition: integer;

Begin

TimePosition: = POS (SOAPTIMEPREFIX, VALUE);

IF TimePosition> 0 THEN

Begin

DateString: = Copy (Value, 1, TimePosition-1);

TimeString: = Copy (Value, TimePosition 1, Length (Value) - TIMEPSITION;

FDATEPARAM.XSTONATIVE (dateString);

FTIMEPARAM.XSTONATIVE (TIMESTRING);

END ELSE

FDATEPARAM.XSTONATIVE (VALUE);

END;

Function TXSDATETIME.NATIVETOXS: WIDESTRING;

VAR

TimeString: WideString;

Begin

TimeString: = fTimeParam.nativeToxs;

IF TIMESTRING <> '' THEN

Result: = fdateParam.nativeTox SOAPTIMEPREFIX TIMESTRING

Else

Result: = fdateParam.nATIVETOXS;

END;

Function TXSDatetime.validValue (Value, Subtract, Min, Max: Integer; Var Remainder: Integer): Integer; Begin

RESULT: = Value - Subtract;

Remainder: = 0;

IF results

Begin

REMAINDER: = 1;

INC (Result, Max);

END;

END;

Function TXSDateTime.comParedateTimeParam (const value1, value2: txsdatetime): TXSDURATION;

VAR

Remainder, Milliseconds, Seconds: Integer

Begin

Result: = TXSDURATION.CREATE;

Try

Milliseconds: = ValidValue (Value1.Millisecond, Value2.MilliseCond, 0, 1000, Remain);

Seconds: = ValidValue (Value1.second Remainder, Value2.Second, 0, 60, Remain);

Result.Decimalsecond: = Seconds MilliseConds / 1000;

Result.minute: = ValidValue (Value1.minute Remainder, Value2.minute, 0, 60, Remain);

Result.Hour: = ValidValue (Value1.Hour Remainder, Value2. Hour, 0, 24, Remain);

Result.day: = ValidValue (Value1.day Remainder, Value2.day, 0, 31, Remain);

Result.month: = ValidValue (Value1.month Remainder, Value2.mont, 0, 12, Remain);

Result.year: = ValidValue (ValidValue (Value1.year Remainder, Value2.year, -9999, 0, Remainder);

Except

Result.free;

Result: = NIL;

END;

END;

{TXSDURATION}

Constructor TXSDURATION.CREATE;

Begin

Inherited Create;

FDATEPARAM.MAXDAY: = 30;

FDATEPARAM.MINDAY: = 0;

FDATEPARAM.MAXMONTH: = 11;

FDATEPARAM.MINMONTH: = 0;

END;

Procedure TXSDURATION.SETDECIMALSECOND (Const Value: Double);

Begin

IF value <60 THEN

FDecimalsecond: = Value

Else

SoapDateTimeErrorfmt (SINVALIDFRActionSECOND, [VALUE]);

END;

Function TXSDURATION.GETNUMERICSTRING (Const APARAM: STRING;

Const Decimals: boolean = false: WideString;

VAR

I, J: Integer;

Begin

I: = POS (Atype, Aparam);

J: = i;

While (i> 0) and ((Aparam [I-1] in ['0' .. '9']) or

(Decimals and (aparam [i-1] = '.')))))

DEC (i);

IF j> i Then

Result: = Copy (Aparam, i, J-i)

Else

Result: = '0';

END;

Function TXSDURATION.GETINTEGERVALUE (Const Aparam: string): Integer;

Begin

Result: = start (getNuMericstring (APARAM, ATYPE));

END;

Function TXSDURATION.GETDECIMALVALUE (const APARAM: STRING; Const atype: String): Double;

Begin

Result: = start (getNuMericstring (Aparam, atype, true);

END;

Procedure TXSDURATION.XSTONATIVE (Value: WideString);

VAR

DateString, TimeString: String;

TimePosition: integer;

Begin

IF value [1] <> xmldurationstart the

SoapDatetimeErrorfmt (SINVALIDDURATION, [VALUE]);

TimePosition: = POS (SOAPTIMEPREFIX, VALUE);

IF TimePosition> 0 THEN

Begin

TimeString: = Copy (Value, TimePosition 1, Length (Value) - TimePosition;

DateString: = Copy (value, 1, timeposition - 1);

END ELSE

DateString: = value;

Year: = GetIntegerValue (DateString, XmLdureyear);

Month: = GetIntegerValue (Datestring, XmLdurationMonth);

Day: = GetIntegerValue (DateString, XmLdurationDay);

IF TimePosition> 0 THEN

Begin

Hour: = GetIntegerValue (TimeString, XMLDURATIONHOUR);

Minute: = GetIntegerValue (TimeString, XMLDURATIONMINUTE);

Decimalsecond: = getDecimalvalue (TimeString, XmLdurationSecond);

END;

END;

{Format IS 'P1Y2M3DT10H30M12.3S'}

Function TXSDURATION.NATIVETOXS: WIDESTRING;

Begin

Result: = XMLDURATIONSTART

INTTOSTR (YEAR) XMLDURATIONYEAR

INTOSTR (MONTH) XMLDURATIONMONTH

INTOSTR (DAY) XMLDURATIONDAY SOAPTIMEPREFIX INTOSTR (HOUR) XMLDURATIONHOUR

INTTOSTR (Minute) XMLDURATIONMINUTE

FLOATTOSTR (DECIMALSECOND) XMLDURATIONSECOND;

END;

Initialization

RemclassRegistry.registerXSClass (TxsDatetime, Xmlschemanamespace, 'DateTime', '', true)

RemclassRegistry.registerXSclass (Txstime, Xmlschemanamespace, 'Time', '', true);

RemclassRegistry.registerXSClass (TXSDATE, XMLSChemanamespace, 'Date', '', True);

RemclassRegistry.registerXSclass (TXSDuration, Xmlschemanamespace, 'Duration', '', true);

Finalization

RemclassRegistry.unregisterXSClass (TXSDateTime);

RemclassRegistry.unregisterXSClass (TXSTIME);

RemclassRegistry.unregisterXSClass (TXSDATE);

RemclassRegistry.unregisterXSClass (TXSDuration);

End.

转载请注明原文地址:https://www.9cbs.com/read-30832.html

New Post(0)