Everybody loves Saturdays and Sundays, right? Well, no. Sometimes applications don't.
In the first column in this series, we looked at the Get Current Local Time (CEELOCT) and Convert Lilian Date to Character Format (CEEDATE) APIs. Today, we will review the Convert Date to Lilian Format (CEEDAYS) and Calculate Day of Week from Lilian Date (CEEDYWK) APIs.
The CEEDAYS API allows us to convert any date in the range of October 15, 1582, through December 31, 9999, inclusive. The API documentation can be found here, and I've repeated the API's parameter list below:
Required Parameter Group:
1 | input_char_date | Input | VSTRING |
2 | picture_string | Input | VSTRING |
3 | output_Lilian_date | Output | INT4 |
Omissible Parameter:
4 | fc | Output | FEEDBACK |
The CEEDAYS API is essentially the CEEDATE API in reverse. The first parameter, input_char_date, is a formatted date value such as 05/20/2008, 20080520, or 080520 for May 20, 2008, and the second parameter, picture_string, is a variable-length character string describing how to interpret the input_char_date parameter. The formatting options, and there are many, can be found in the CEEDAYS API documentation. The third parameter, output_Lilian_date, is the Lilian-formatted date that represents the value of the input_char_date parameter. As we know from the first column in this series, the Lilian value 155447 would be equivalent to the Gregorian date May 20, 2008. The fourth parameter, fc, is the common error code structure used by CEE APIs.
The following program, GREGTOLIL, will convert a Gregorian date in format YYYYMMDD to a Lilian-formatted value, add 60 to this value, convert this result to a MM/DD/YYYY value, and then display the formatted result. While I've hard-coded the duration (60 days) and the picture string, you could just as easily have these as parameters to the GREGTOLIL program.
Pgm Parm(&YYMDGreg)
Dcl Var(&YYMDGreg) Type(*Char) Len(8)
Dcl Var(&CurLilDate) Type(*Int)
Dcl Var(&NewLilDate) Type(*Int)
Dcl Var(&NewGregDt) Type(*Char) Len(32)
CallPrc Prc(CEEDAYS) Parm((&YYMDGreg) ('YYYYMMDD') +
(&CurLilDate) (*Omit))
ChgVar Var(&NewLilDate) Value(&CurLilDate + 60)
CallPrc Prc(CEEDATE) Parm((&NewLilDate) +
('MM/DD/YYYY') (&NewGregDt) (*Omit))
SndPgmMsg Msg(&NewGregDt) ToPgmQ(*Ext)
EndPgm
Running GREGTOLIL with 'CALL GREGTOLIL ('20080321')' will result in the message 05/20/2008 being displayed. Likewise, 'CALL GREGTOLIL ('20080325')' will result in the message 05/24/2008 being displayed.
Depending on how this calculated date is to be used, this value 05/24/2008 may or may not be a concern. The potential problem is that if we look at a calendar, we see that May 24, 2008, falls on a Saturday. For some applications, this is OK; for others, we might want to move the date out to the following Monday. Can this be handled within our program? The answer of course is yes.
The Calculate Day of Week from Lilian Date (CEEDYWK) API takes as input a Lilian-formatted date and returns the day of week. The API documentation can be found here, and the parameter list is shown below:
Required Parameter Group:
1 | input_Lilian_date | Input | INT4 |
2 | output_day_no | Output | INT4 |
Omissible Parameter:
3 | fc | Output | FEEDBACK |
The CEEDYWK API has two required parameters and one omissible parameter. The first parameter, input_Lilian_date, is the Lilian date value we want to determine the day of week for. The second parameter, output_day_no, is a signed 4-byte integer value (TYPE(*INT) in CL) and is an output from the API. When output_day_no is 1, the input_Lilian_date is a Sunday, 2 is a Monday, and so on through 7, which indicates Saturday. With this knowledge, we can now have a modified program, GREGTOLIL2, which adds a minimum of 60 days to the input date and a maximum of 62 in the case of the calculated date falling on a Saturday. The source for GREGTOLIL2 is shown below.
Pgm Parm(&YYMDGreg)
Dcl Var(&YYMDGreg) Type(*Char) Len(8)
Dcl Var(&CurLilDate) Type(*Int)
Dcl Var(&NewLilDate) Type(*Int)
Dcl Var(&DayOfWeek) Type(*Int)
Dcl Var(&NewGregDt) Type(*Char) Len(32)
CallPrc Prc(CEEDAYS) Parm((&YYMDGreg) ('YYYYMMDD') +
(&CurLilDate) (*Omit))
ChgVar Var(&NewLilDate) Value(&CurLilDate + 60)
CallPrc Prc(CEEDYWK) Parm((&NewLilDate) (&DayOfWeek) +
(*Omit))
If Cond(&DayOfWeek = 1) Then(ChgVar +
Var(&NewLilDate) Value(&NewLilDate + 1))
If Cond(&DayOfWeek = 7) Then(ChgVar +
Var(&NewLilDate) Value(&NewLilDate + 2))
CallPrc Prc(CEEDATE) Parm((&NewLilDate) +
('MM/DD/YYYY') (&NewGregDt) (*Omit))
SndPgmMsg Msg(&NewGregDt) ToPgmQ(*Ext)
EndPgm
Running GREGTOLIL2 with 'CALL GREGTOLIL2 ('20080325')' will now result in the message 05/26/2008 being displayed rather than the previous 05/24/2008 value of GREGTOLIL.
So that's the program. Or is it? While GREGTOLIL2 does avoid calculating dates that fall on a Saturday or Sunday, you might, if you again look at your calendar, notice that May 26 is a holiday in the United States. If we didn't want to generate dates on weekends, it's probably safe to assume we don't want to be generating dates that are holidays either. In the next column in this series, we'll look at one possible solution that addresses how to handle holidays. We won't be using any additional CEE APIs beyond what you already know. Rather, the discussion will be directed to other capabilities of CL.
One bit of advice seems appropriate before I close. When using the CEEDATE API to return a Lilian date in character format, you might recall that one option is to have the day of week returned in a format such as Saturday, 24 May 2008. This may make you think you don't need to call the CEEDYWK API as you could just look for the character string "Saturday." This would work in some cases, but I wouldn't recommend it. The exposure is that this string, along with the character string "May," can be translated into various languages. If you are running in the United States with National Language Version 2924 installed, you would get Saturday, but in a different language environment, you may very well get character strings returned such as Samstag (German) or субботу (Russian). When you need to determine the day of week, use the CEEDYWK API so that the parameter output_day_no will be the value 1 for Saturday, independent of what National Language Version your program might be running in. Even for companies that do business in only one country, I recommend writing any application as if it might run anywhere in the world. You never know what acquisitions your company may make in the future, and I strongly believe in writing applications that, where possible, can accommodate future changes...especially if, as in this case, calling CEEDYWK is the only effort required.
Having said that, in the next column, we'll actually stop using CEEDYWK! For flexibility purposes, I do not want each application program determining if a given day is Saturday, Sunday, or a holiday and then making adjustments to the calculated date. You can be sure that as soon as we do that, the company will decide to start working every other Saturday and you'd have to change all of your programs! We will be looking at a much more flexible approach, one that minimizes the likelihood of application maintenance in order to accommodate company calendar changes. But that doesn't mean you shouldn't use CEEDYWK in other situations. There are many times when you may want to know the day of the week, and CEEDYWK will be just what you need.
More CL Questions?
Wondering how to accomplish a function in CL? Send your CL-related questions to me at http://b9.mail.yahoo.com/ym/brucevining.com/Compose?To=
LATEST COMMENTS
MC Press Online