----------------------------------------------------------------------------- [BUG/PRB.] VFP 9.0 FIX - ROUND THE DATETIME DATA TO INTEGER SECONDS January 2024 ----------------------------------------------------------------------------- CCB 1. BUG: There is a test program from Mr. Tomas Tamm: *PROC testcomparedatetime dt1=DATETIME(2017,1,1,0,0,0) dt2=DATETIME(2017,1,1,0,0,0) FOR li=1 TO 10000000 dt1 = dt1+60 dt2 = DATETIME(YEAR(dt1),MONTH(dt1),DAY(dt1),HOUR(dt1),MINUTE(dt1),SEC(dt1)) IF dt2 != dt1 ? "After "+TRANSFORM(li)+" iterations of adding 60 seconds to dt1" ? "dt1 = "+TRANSFORM(dt1) ? "dt2 = "+TRANSFORM(dt2) ? "dt1 and dt2 visibly seem to be equal" ? "But dt1 = dt2 evaluates to "+TRANSFORM(dt1=dt2) ? "dt2 - dt1 = "+TRANSFORM(dt2-dt1) EXIT ENDIF ENDFOR WAIT RETURN * END OF PROC TESTCOMPAREDATETIME. Usually, we think dt2 is always equal to dt1, but it will display: After 139810 iterations of adding 60 seconds to dt1 dt1 = 04/08/17 02:10:00 AM dt2 = 04/08/17 02:10:00 AM dt1 and dt2 visibly seem to be equal But dt1 = dt2 evaluates to .F. dt2 - dt1 = 1 2. CAUSE: VFP uses the Value structure to save the value of the variables: // An expression's value. Typedef struct { char ev_type; char ev_padding; short ev_width; unsigned ev_length; long ev_long; double ev_real; CCY ev_currency; MHANDLE ev_handle; ULONG ev_object; } Value; For the datetime data, ev_type = 'T' ev_real = Date + (seconds/86400.0) VFP uses the floating-point number to save the datetime data, for example, dt1=DATETIME(2017,1,2,3,4,5) dt1.ev_real = VAL(SYS(11,DATE(2017,1,2))) + ((3*60+4)*60+5)/86400.0 = 2457756.1278356481340 For the test program testcomparedatetime, After 139810 iterations of adding 60 seconds, dt1.ev_real = 2457852.0902719907460 dt2.ev_real = 2457852.0902777779850 dt2.ev_real - dt1.ev_real = 5.7872384786605834960E-06 5.7872384786605834960E-06 * 86400.0 = 0.5000174045562744140 > 0.5 (seconds) So dt2 != dt1. If we enable rounding the datetime data to integer seconds in Visual FoxPro Advanced, Visual FoxPro Advanced will round the datetime data to integer seconds, for example, DATETIME() Function, seconds number + datetime expression. datetime expression + seconds number, datetime expression - seconds number, datetime expression - datetime expression. For the statement in the test program testcomparedatetime: dt1 = dt1+60 Visual FoxPro Advanced will calculate: dt1.ev_real = dt1.ev_real+60 and then round dt1.ev_real to integer seconds: dt1.ev_real = floor(dt1.ev_real * 86400.0 + 0.5) / 86400.0 After 139810 iterations of adding 60 seconds, dt1.ev_real = 2457852.0902777775190 dt2.ev_real = 2457852.0902777779850 dt2.ev_real - dt1.ev_real = 4.6566128730773925780E-10 4.6566128730773925780E-10 * 86400.0 = 0.0000402331352233887 < 0.5 (seconds) So dt2 == dt1. 3. RESOLUTION: We can write some code to fix the BUG. Label58fd6b :: sub eax , 05449h ;0x0058fd6b : 2d49540000 je Label58fda5 ;0x0058fd70 : 7433 sub eax , 05h ;0x0058fd72 : 83e805 jne Label58fe1d ;0x0058fd75 : 0f85a2000000 fld qword ptr [ Data91fbc8 ] ;0x0058fd7b : dd05c8fb9100 fld qword ptr [ esi + 16 ] ;0x0058fd81 : dd4610 fucompp ;0x0058fd84 : dae9 fstsw ax ;0x0058fd86 : dfe0 test byte ptr ah , 044h ;0x0058fd88 : f6c444 jnp Label420eae ;0x0058fd8b : 0f8b1d11e9ff fld qword ptr [ ebx + 16 ] ;0x0058fd91 : dd4310 fmul qword ptr [ Data922280 ] ;0x0058fd94 : dc0d80229200 fadd qword ptr [ esi + 16 ] ;0x0058fd9a : dc4610 ; ; ------------------------------------------------------------------ ; VFP 9.0 FIX - ROUND THE DATETIME DATA TO INTEGER SECONDS ; December 2017 ; ------------------------------------------------------------------ ; CCB ; ; Round the datetime data to integer seconds. ; ; 2017/12/20, by ccb ; cmp dword ptr vfpa_sys9002_data,00h je Label58fd9d sub esp , 08h fstp qword ptr [ esp ] call Fun87c7af Label58fd9d :: fstp qword ptr [ esi + 16 ] ;0x0058fd9d : dd5e10 jmp Label420eae ;0x0058fda0 : e90911e9ff Label58fda5 :: fld qword ptr [ Data91fbc8 ] ;0x0058fda5 : dd05c8fb9100 fld qword ptr [ esi + 16 ] ;0x0058fdab : dd4610 fucompp ;0x0058fdae : dae9 fstsw ax ;0x0058fdb0 : dfe0 test byte ptr ah , 044h ;0x0058fdb2 : f6c444 jnp Label420eae ;0x0058fdb5 : 0f8bf310e9ff fild dword ptr [ ebx + 12 ] ;0x0058fdbb : db430c fmul qword ptr [ Data922280 ] ;0x0058fdbe : dc0d80229200 fadd qword ptr [ esi + 16 ] ;0x0058fdc4 : dc4610 ; ; ------------------------------------------------------------------ ; VFP 9.0 FIX - ROUND THE DATETIME DATA TO INTEGER SECONDS ; December 2017 ; ------------------------------------------------------------------ ; CCB ; ; Round the datetime data to integer seconds. ; ; 2017/12/20, by ccb ; cmp dword ptr vfpa_sys9002_data,00h je Label58fdc7 sub esp , 08h fstp qword ptr [ esp ] call Fun87c7af Label58fdc7 :: fstp qword ptr [ esi + 16 ] ;0x0058fdc7 : dd5e10 jmp Label420eae ;0x0058fdca : e9df10e9ff 4. APPLIES TO: VFP 6.0.8167.0 VFP 6.0.8961.0 (SP5) VFP 7.0.0.9262 VFP 7.0.0.9465 (SP1) VFP 8.0.0.2521 VFP 8.0.0.3117 (SP1) VFP 9.0.0.2412 VFP 9.0.0.3504 (SP1) VFP 9.0.0.4611 (SP2) VFP 9.0.0.5015 (SP2) VFP 9.0.0.5411 (SP2) VFP 9.0.0.5721 (SP2) VFP 9.0.0.5815 (SP2) VFP 9.0.0.6303 (SP2) VFP 9.0.0.6602 (SP2) VFP 9.0.0.7423 (SP2) The bug has been fixed in VFP Advanced. 5. REFERENCE WEBSITES: 1, baiyujia.com: http://www.baiyujia.com http://www.baiyujia.com/vfpdocuments/f_vfp9fix37.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix23.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix24.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix97.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix98.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix123.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix124.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix255.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix256.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix257.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix258.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix259.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix260.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix303.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix304.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix305.asp http://www.baiyujia.com/vfpdocuments/f_vfp9fix306.asp 2, foxite.com: https://www.foxite.com/archives/problem-0000100367.htm https://www.foxite.com/archives/is-this-a-bug-0000106513.htm 3, sunyear.com.tw: http://vfp.sunyear.com.tw/viewtopic.php?t=4314 6. OTHER: For reference only, there is no guarantees. Any questions or suggestions, please send me an email at ccb2000@163.com. |