How NOT to increment date field [NAV 2009 bug]

davorpdavorp Member Posts: 17
I was just porting some code from NAV 2009 to NAV 2013 which included certain Date functions.

Of course you always assume that internally date variable is just another integer like variable and in most cases you would be right - you can assign some value to it (just remember to do it in ddmmyyD format to make the compiler happy), calculate difference between two dates just by subtracting two date variables, and increment and decrement it using arithmetic operators + and -.

So during the testing phase I noticed that I was not getting the same results on NAV 2013 and NAV 2009 version of the code. One of those "Hmmm, this should not be like this..." kind of moments...
Since I didn't change the code segment in question while porting it and since NAV 2009 code was well tested and widely used in production, could it be that NAV 2013 actually had a bug in date calculations? :shock:

So a few debugging sessions later I stumble across the following code:
EndDate += 1;
Simple and logical compound assignment statement, right?

Take the date variable, increment it by one day and store it in the original variable. Right?

Sure. It works just like that in NAV7, but in NAV6 on the other hand...
Well, if you have no objections to February 2nd following January 31st, while February 1st is nowhere to be found you're more tolerant to your calendar days taking vacation than I am :wink:

It turns out that NAV6 and NAV5 and possibly older versions have a bug when using compound assignment += statement with date variables and instead of incrementing by one day, date gets incremented by two days.

But if NAV7 is doing it correctly then why was NAV6 giving me good results and NAV7 wasn't?

Turns out that the code following compound assignment was actually overcoming the first NAV bug with another "bug" of its own so while being passed date which is off by one day (+2D instead of +1D) it was correcting for it by using "< EndDate" instead of "<= EndDate" in test statement and all was well.

Test cases passed, code works, user are happy...

Until NAV7 comes along and fixes the compound assignment statement
#-o

So to summarize, I would say if you're still writing code for older NAV versions, it would best to avoid compound assignment with Date variable and stick to the proven:
DateVariable := DateVariable + 1;
or better still
DateVariable := CALCDATE('<+1D>', DateVariable);
and don't forget to always encapsulate DateExpression in < and > characters to make it non language dependent.

Comments

  • lvanvugtlvanvugt Member Posts: 774
    Thanx for sharing.
    Haven't be aware of this issue in older versions. Being a C programmer myself before I started working with NAV, I was using the compound assigments by default getting some marvelled faces from colleagues who hadn't know that it existed in NAV.
    However, from NAV programming standards perspective it is common (or actually a rule) to not use them, for readibility reasons as
    LineNo += 1;
    
    looks (almost) the same as
    LineNo := 1;
    
    and quickly reading both lines of code is error prone. So the standard says to write it like
    LineNo := LineNo + 1;
    
    Luc van Vugt, fluxxus.nl
    Never stop learning
    Van Vugt's dynamiXs
    Dutch Dynamics Community
  • davorpdavorp Member Posts: 17
    Hm, interesting point about readability.
    Then again there is also another way to look at it, like when both variables are long record names with long field names, as in this example from NAV7 W1 code (one of 931 usages of += or -= in there according to grep :wink: ):
    TempInvoicingSpecification."Quantity Invoiced (Base)" += TempInvoicingSpecification."Qty. to Invoice (Base)";
    
    To me this is more readable than using
    TempInvoicingSpecification."Quantity Invoiced (Base)" := TempInvoicingSpecification."Quantity Invoiced (Base)" + TempInvoicingSpecification."Qty. to Invoice (Base)";
    
    (if it even fits in one line)
    Then if you throw into the mix some copy/pasting of many similar lines where you need to change source variable on both sides of the assignment instead of only on one side and the potential for introducing errors does somewhat increase.

    Besides, I would think that += is still a lot more different from := than := is from, say, ;= (not that I would know anybody that ever tried compiling any code with ;= as assignment statement :whistle: )
Sign In or Register to comment.