Since the beginning of time on OS/400, the beloved ancestor of IBM i, six long dates have always used the "1940 rule" to determine the century.
If Year >= 40 then Century = 19
If Year < 40 then Century = 20
2039 is not that far in the future, only 17 years away, IBM has developed a replacement rule, "1970 rule".
If Year >= 70 then Century = 19
If Year < 70 then Century = 20
As part of the IBM i 7.5 announcement IBM has said that the new rule will be implemented in a future release or Technology Refresh.
IBM is giving a foretaste of the new rule in 7.5. I used the word "foretaste" as the "1940 rule" has not been replaced, but the new rule can be implemented on top of it, if you so desire. The rule can either be applied to your entire system, which I do NOT recommend, or it can be implemented just to the current job.
In 7.5 the "1970 rule" is implemented by an Environmental Variable: QIBM_QBASEYEAR
If you wanted to apply this to your entire partition, which is NOT what I recommend, you would use the following command:
ADDENVVAR ENVVAR(QIBM_QBASEYEAR) VALUE(1970) LEVEL(*SYS) |
By all means you can delete the environment variable, but who knows what effects it will have on all of the jobs using your applications.
It is safer to just apply it to the current job:
ADDENVVAR ENVVAR(QIBM_QBASEYEAR) VALUE(1970) LEVEL(*JOB) REPLACE(*YES) |
I then need to use the Change Job Command, CHGJOB, to apply the job's environmental variable to the job.
CHGJOB JOB(*) DATFMT(*MDY) |
As I am in the USA I would use the Date Format of *MDY. If you use another date format, *DMY or *YMD, you would use that in this parameter.
I can check if the environmental variable has been added to the current job using the Work With Environmental Variables command, WRKENVVAR.
Work with Environment Vars (*JOB) Type options, press Enter. 1=Add 2=Change 4=Remove 5=Display details 6=Print Opt Name Value _ _ PASE_USRGRP_LIMITED 'N' _ QIBM_PASE_USE_PRESTART_J > 'Y' _ LANG '/QSYS.LIB/EN_US.LOCALE' _ ILE_DEBUGGER_1 'ALLOW_WIDE_SCREEN' _ QIBM_QBASEYEAR '1970' |
Alas, this screen does not show at which level the environmental variable has been applied. The only way I could see that was to use the "2", and I could see the level at the bottom of that screen.
There is another "change" that was explained in the announcement. For any command parameter that is defined as *DATE you can enter the date as either six long or eight long, which includes the century. I tested on all the partitions I have with different releases and found that I could use the eight long date in IBM i 7.3 and up.
Below is what I found running tests in one session that had the environmental variable and another did not.
The first tests I performed were with date parameters in commands.
First command with a date that came to minds is the Submit Job command, SBMJOB. If I use the Schedule Date parameter with the date of 01/01/40 in the job without the environmental variable I get the following:
SBMJOB CMD(CALL PGM(A)) SCDDATE(010140) Specified date or time has passed. |
The error message comes as no surprise as January 1, 1940 has passed.
I can submit the job with the eight long date:
SBMJOB CMD(CALL PGM(A)) SCDDATE(01012040) |
And the job is successfully submitted.
In the job with the environmental variable when I use the six long date:
SBMJOB CMD(CALL PGM(A)) SCDDATE(010140) |
The job is successful as the date this time has been interpreted as January 1, 2040. But you have to assume what I am telling you.
To show this with the actual dates I built my own command: MYCMD
01 CMD PROMPT('My command for dates') 02 PARM KWD(DATE) TYPE(*DATE) PROMPT(*DATE) |
My command has only one parameter, a *DATE type. Below is the Command Processing Program, or CPP, for this command.
01 PGM PARM(&DATE) 02 DCL VAR(&DATE) TYPE(*CHAR) LEN(7) 03 DMPCLPGM 04 ENDPGM |
Lines 1 and 2: The command passes one parameter to the CPP, the date. Which I have defined as a character variable. Why seven long? The date is passed from the command to the program in *CYMD format.
Line 3: I want to generate a program dump, within which will be value of the &DATE variable.
First time I ran my command was in the job was still using the "1940 rule".:
MYCMD DATE(010140) |
Looking in the job log I can see that the date starts with "0", which indicates that the century is "19".
Variable Type Length Value *...+....1 &DATE *CHAR 7 '0400101' |
When I use the eight long date with the command:
MYCMD DATE(01012040) |
The dump shows that the century is "1", and the date is January 1, 2040.
Variable Type Length Value *...+....1 &DATE *CHAR 7 '1400101' |
Another test with the "1940 rule", this time with the date of January 1,1969.
MYCMD DATE(010169) |
This returns the century of "0", i.e. January 1, 1969:
Variable Type Length Value *...+... &DATE *CHAR 7 '0690101' |
Now into the job with the environmental variable, and the "1970 rule". Executing my command with the date 010140:
MYCMD DATE(010140) |
With the "1970 rule" this is interpreted as January 1, 2040:
Variable Type Length Value *...+....1 &DATE *CHAR 7 '1400101' |
I am not going to test 01012040 as it is obvious what the result for that will be.
Now for date 010169:
MYCMD DATE(010169) |
The date has been interpreted as January 1, 2069.
Variable Type Length Value *...+... &DATE *CHAR 7 '1690101' |
What about in the common IBM i programming languages. IBM said they would still use the old rule, but I wanted to really make sure.
First up CL. I thought the best way to test converting six to eight long dates was to use the Convert Date command, CVTDAT:
01 DCL VAR(&DATE1) TYPE(*CHAR) LEN(6) VALUE('010140') 02 DCL VAR(&DATE2) TYPE(*CHAR) LEN(10) 03 CVTDAT DATE(&DATE1) TOVAR(&DATE2) FROMFMT(*MDY) TOFMT(*ISO) |
Line 1: The six long date that will be converted to *ISO, with date separator characters.
line 2: The converted date will be in this variable.
Line 3: The CVTDAT command.
No matter which job I ran it in the value returned in &DATE2 was '1940-01-01'.
I tried RPG next.
01 **free 02 dsply %date('010140':*mdy0) ; 03 *inlr = *on ; |
Again it did not matter which job I ran it in the displayed value was:
DSPLY 1940-01-01 |
I have written before about SQL's date "windowing" and as far as I can tell this remains unchanged.
Go ahead test anything that uses a command with a date parameter in it. Until the "1970 rule" is applied to CL and RPG, and I would assume Cobol, there is, IMHO, only limited testing that could be performed. But I would like to thank IBM for giving us the feature so that we are aware of what the future will bring, and we can start testing what would need to change to implement a new rule.
You can learn more about the "1970 rule" environmental variable from the IBM website here.
This article was written for IBM i 7.5.
Thank you
ReplyDelete