Y2K Error in Natural Mask

Edit (7/20): This is a LEAP YEAR problem. I get an error with 02292004.

Hello, I was creating a Natural Date subprogram to do things like change date to EOM, prior EOM, next EOM, EOQ, etc (with date conversion thrown in as a freebee - one stop shopping) and came across this error while testing the subprogram.

In the subprogram I have the following code in a DECIDE statement:
VALUE ‘MMDDYYYY’, ‘mmddyyyy’
IF DATE-IN-8 NE MASK(MMDD1800-2099)
DATE-FORMAT-ERROR := TRUE
ESCAPE MODULE
END-IF
MOVE EDITED DATE-IN-8 TO #DATE (EM=MMDDYYYY)

Edit: Please note that the mask test works for MASK(MMDDYYYY).

If I pass a dates of format ‘mmddyyy’ I get an error for ‘02291900’ which I expect, but I also get an error for ‘02292000’ which I don’t. Y2K was a leap year. ‘02282000’ passes okay. The report is below:

[color=“blue”]CHANGE BY MONTHS: 0
CHANGE BY YEARS: 0
CHANGE BY DAYS : 0
FUNCTION: FORMAT IN: mmddyyyy FORMAT OUT: mm/dd/yy
FORMAT ERR: E DATE IN: 02291900 DATE OUT: xxxxxxxxx

CHANGE BY MONTHS: 0
CHANGE BY YEARS: 0
CHANGE BY DAYS : 0
FUNCTION: FORMAT IN: mmddyyyy FORMAT OUT: mm/dd/yy
FORMAT ERR: E DATE IN: 02292000 DATE OUT: xxxxxxxxx

CHANGE BY MONTHS: 0
CHANGE BY YEARS: 0
CHANGE BY DAYS : 0
FUNCTION: FORMAT IN: mmddyyyy FORMAT OUT: mm/dd/yy
FORMAT ERR: DATE IN: 02282000 DATE OUT: 02/28/00 [/color]

Is this a known problem ? Is there a fix ?

I believe what is happening is that since you are not using the full date mask in your condition “MASK = (MMDDYYYY)”, Natural uses the current year to evaluate leap days. You would run into this problem if you tried to evaluate an MMDD field with "MASK = (01-12DD). In this case, Natural evaluates the DD using the current month, since it can’t tell from the 01-12 that the first two bytes are the month.

The way around this is to have two conditions:

IF DATE-IN-8 NE MASK(MMDDYYYY)
OR DATE-IN-8 NE MASK (....1800-2099)
  DATE-FORMAT-ERROR := TRUE

Happy coding!

Thanks, jeromelb. But that code doesn’t work even if I use only:
IF DATE-IN-8 NE MASK(MMDDYYYY)
DATE-FORMAT-ERROR := TRUE

In addition, there is a specific date in DATE-IN-8, 02292000, so that’s the date the mask should test. There is no confusion as to which year should be tested.

Can anyone help ?

(Edit: since there must be a humongous table behind the scenes with all the years with #days since 1582, for performance sake couldn’t a leap year indicator be added to this table?)

Hmmm,

the code jeromelb posts works fine. Don’t know what Problem you have with it. My Testprogram looks like this:

 
DEFINE DATA                          
LOCAL                                
01 DATE-IN-8 (A8)                    
01 DATE-FORMAT-ERROR (L)             
END-DEFINE                           
DATE-IN-8 := '02292100'              
IF DATE-IN-8 NE MASK(MMDDYYYY)       
OR DATE-IN-8 NE MASK (....1800-2099) 
  DATE-FORMAT-ERROR := TRUE          
END-IF                               
WRITE DATE-FORMAT-ERROR              
END                                  

And to your specific “Date confusion” If you test an alphanumeric Variable against a Mask like your example then Natural see’s only that you would test month and day (1800-2099) is not a year than only a range of alphanumeric type. So that Natural would test the MMDD against Systemyear and the Rest against the 2nd part of you Mask.

Also a Problem would be

 
IF DATE-IN-8 NE MASK (02DD2000)  

here Natural tests the Day against days of the Month where you test it. Today a Test of 02312000 would give a true back.

I hope that i understood your Problem. :smiley:

Greetings Sascha

Thanks for your reply, Sascha.

Jerome’s program ‘works’ if you mean that it runs. It does run!
(btw: your test program is using year 2100 not 2000)

However, it just proves my point that there is a problem with the mask since the error flag is set to ‘true’. (Please note that the logic is ‘NE’ not ‘EQ’)

So no, I don’t think you understood my problem which is that a test under mask (MMDDYYYY) of the year 02292000 gives an error.

I tested the mask MMDDYYYY against a value of 02292000 on Natural versions 3.1.6, 4.1.4, 6.1.1, and 6.2.1, and all versions found the date to be valid. I tried several other leap years and non-leap years, and the mask worked as expected.

Ralph, thanks for your reply.

Please clarify.

Are you saying the test “IF DATE-IN-8 NE MASK(MMDDYYYY )” returns a False or a True condition ? (may I have your test code?)

Or are you saying the move “MOVE EDITED DATE-IN-8 TO #DATE (EM=MMDDYYYY)” works correctly ?

We appear to have Natural version 4.1.3 installed and while the MOVE works for me, the condition test returns True, i.e. the date 02292000 is invalid.

EDIT: I take that back. MASK (MMDDYYYY) works while mask (MMDD1800-2099) fails (I had another later check of the latter type in the program).

But really guys, the latter mask only gives a range check for the year. There is a specific date to be tested in the variable. The fact that the latter mask fails is a bug.

Thanks for your help.[/b]

OK, “The”. May I call you The? :slight_smile:

I separated the masks to be sure which was flagging the error.

DEFINE DATA                                    
LOCAL                                          
01 DATE-IN-8 (A8)                              
01 DATE-FORMAT-ERROR1 (L)                      
01 DATE-FORMAT-ERROR2 (L)                      
END-DEFINE                                     
DATE-IN-8 := '02292000'                        
IF DATE-IN-8 NE MASK(MMDDYYYY)                 
  DATE-FORMAT-ERROR1 := TRUE                   
  WRITE 'Error1:' DATE-FORMAT-ERROR1 (EM=F/T)  
END-IF                                         
IF DATE-IN-8 NE MASK (....1800-2399)           
  DATE-FORMAT-ERROR2 := TRUE                   
  WRITE 'Error2:' DATE-FORMAT-ERROR2 (EM=F/T)  
END-IF                                         
END                                            

The first mask will check for consistency of the month, day, and year, including a leap year check of 0229, but it will allow invalid years. For example, it will consider 02291504 a valid date. The second mask is used to verify the year range and will trap 1504. As you can see I used a larger year range than the original example.

ps I don’t usually respond to posts from anonymous members or pseudonyms, but I wanted to support previous posts from Jerome and Sascha.

Thanks, Ralph.

I got the bottom line. Mask(MMDDYYYY) works but no year range check except I guess 1582 thru I belive 2600+. While if you use the mask with a year range, e.g (MMDD1800-2099), there is a BUG where it ignores the year on the date passed to it and uses the current year to check the valid day range. I will work around this BUG because it’s probably described as a FEATURE by this time … :smiley:

And by the by, thespin as in “The Spin” is my nickname and I use this userid in all the forums I join. Is that a problem for you ?

What type is the Variable you would test against the Mask(MMDD1800-2099) if it is Type A or N then that Mask isn’t a Date range check!

I think Natural such as other Languages use a Parser which parse the Code at your example the Maskstatement from left to right. So that your Mask is splitt into 2 Masks in Background. The First Mask is (MMDD) the 2nd Mask would be (…1800-2099)! Then your if-statement is tested in 2 Steps. Step 1 would check the (MMDD)

0229 isn’t a valid date this year. If you run your Programm at 2008 it would be valid.

Then Natural checks the 2nd Part of your String and 1800-2099 would be right but only if both parts gives back an true the test could be true.

Once again the Natural parser don’t know if your A8/N8 variable is an Date or only a Number or a String. It only knows that it is an A8/N8. So this would not be a bug.

Use the If-Statement of jeromelb that exactly does a Date-range-check.

Have a look at http://techcommunity.softwareag.com/ecosystem/documentation/natural/nat421mf/pg/pg_furth_lcc_0640.htm#Checking_Dates

Greetings
Sascha

Thanks, Sascha. I see that the FEATURE is documented.

So is COBOL’s “MULTIPLY A BY B” placing the resulting in B … :?

I disagree!

The documentation says “MM” is checked for valid month, “DD” checks for valid day and “YY” or “YYYY” checks for valid years. Missing parts of the mask are replaced by the values of the current date (eg “YY” is filled up with current century).

In your mask check, there is no YY or YYYY, only a range of 4 digit numbers. That you have placed the numbers on a position where the reader expects the year, does not mean that Natural must expect this, too. Your mask can semantically expressed as:

IF DATE-IN-8 NE MASK(MMDD) OR DATE-IN-8 NE MASK(....1800-2399)

There is no implicity like in your cobol example.

PS. Like Ralph, I would also like to know, to whom I answer. From jeromelb I think I know who he is (from SAG-L).

Thanks, Wilfried, for your input.

I have NO PROBLEM with Natural not assuming that a range in the mask is the year (though it could be a logical assumption based on context). “Missing parts of the mask are replaced by the values of the current date (eg “YY” is filled up with current century)” is exactly what I disagree with.

If it’s not natural for Natural to make an assumption even based on context (this would of course be documented), it’s even less logical for Natural to edit MMDD based on current year. What would have made more sense is that if the mask has only MMDD and the month is 02, then DD = 01 thru 29 should pass edit.

“That’s my story and I am sticking to it.” :smiley:

(and none of you know me from Adam - so you can call me Adam if you like)

Ok, Adam :slight_smile:

to check a date, it must consist of the parts day, month and year (any other is a sequence of numbers and may not be interpreted as a date). So Natural has the convention to fill up missing parts from the current date. They could als have made the convention to fill up missing parts from a predefined default date, but they didn’t.

Also the documentation reads (exactly for your problem!)

BTW. I would also better like Natural to interpret my code as I meant it, not as I wrote it. :wink:

“BTW. I would also better like Natural to interpret my code as I meant it, not as I wrote it.”

Touche … :slight_smile: