Tuesday, November 15, 2005

VFP DATE() behavior change in VFP 9

Last week Mike Potjer reported a problem in HackCX Professional with the logic to decode the TimeStamp column of the VCX he was hacking while using VFP 9. The error reported is:
Error: (11) 'Function argument value, type, or count is invalid.' happened in frmhackmain.convert() on line 75
The line of code triggering the error has been working for a very long time. In fact, the code I use to decode the TimeStamp column has been around for more than 10 years with the only tweak being a change to comply with SET STRICTDATE TO 2 and a cleaner implementation to be Y2K compliant. The line of code triggering the error:
lcRetVal = lcRetVal + DTOC(DATE(lnYear, lnMonth, lnDay))
The TimeStamp should have been decoded properly as it was a valid TimeStamp. The values of lnYear, lnMonth, and lnDay were 2004.8074, 12.918774, and 29.0077209 respectively. In VFP 8 the value of lcRetVal was the character equivalent of {^2004/12/29} and in VFP 9 (both RTM and the SP1 Beta) the code errors.

Mike's bug report was one of the best I have seen. He provided me the steps, the error log HackCX recorded, and a screen shot of the debugger with all the details surrounding the line of code. It literally took me five minutes to reproduce the problem, make the fix, and send Mike the updated version. He tested it with the Class Library he hacked and all is well.

I was initially thinking of reporting this issue to Microsoft as a bug. As I was creating the reproducible steps, noting the observed behavior and discussing the expected results I started thinking about this in more detail. Here is the test code I was going to send to the Fox Team:

?DATE(2005.3232, 12.2323, 19.3232) && fails
?DATE(2005.3232, 12, 19) && Works

?DATE(2005.3232, 12, 19.3232) && Works

?DATE(2005.3232, 12, 31.3232) && Fails

?DATE(2005.3232, 11.99989, 19.988976) && Works, uses integer of parameters

I struggled with the expected results part of the report. I initially wrote down that I wanted the INT() of the parameter passed in. But what if I really calculated a number like 31.9898 as the day of the month. Should it round to the next day? In the context of my TimeStamp converter I want the INT() and this is how I fixed the code. I am not sure how other FoxPro developers would want this to work and thus came to the conclusion that a valid parameter cannot be bigger than a real date. The decimal portion of the month and day could be larger than the valid values. Therefore the error message reported by VFP was dead on and the documentation in the Help file notes valid parameter values (it just does not say how it addresses the decimal part of the parameter so you have to interpret the parameters as literal maximums).

The DATE() behavior has changed and this little tweak in VFP to tighten down the correct behavior of a function could bite you like me, so I thought I would share the story in case you run across this in your development. Thanks again to Mike Potjer for the excellent bug report and making me think a little about how this function is working.

New version of HackCX Professional will be posted this afternoon for existing and future customers to download.


At 11/17/2005 07:57:00 AM, Anonymous Vassilis Aggelakos said...

This is really a must know Rick!

Thank you for your detailed post.



Post a Comment

<< Home