Several Intrinsic Functions can be used in evaluating data items:
If you want to know the ordinal position of a certain character in the collating sequence, reference the ORD function using the character in question as the argument, and ORD will return an integer representing that ordinal position. One convenient way to do this is to use the substring of a data item as the argument to ORD:
IF FUNCTION ORD (CUSTOMER-RECORD(1:1)) IS > 194 THEN ...
On the other hand, if you know what position in the collating sequence you want but do not know what character it corresponds to, then reference the CHAR function using the integer ordinal position as the argument, and CHAR will return the desired character:
INITIALIZE CUSTOMER-NAME REPLACING ALPHABETIC BY FUNCTION CHAR(65).
The results of alphanumeric functions might be of varying lengths and values depending on the function arguments.
In the following example, the amount of data moved to R3 and the results of the COMPUTE statement depend on the values and sizes of R1 and R2:
01 R1 PIC X(10) VALUE "e". 01 R2 PIC X(05) VALUE "f". 01 R3 PIC X(05) VALUE "g". 01 R4 PIC X(20) VALUE SPACES. 01 L PIC 99. . . . MOVE FUNCTION MEAN(R1 R2 R3) TO R4. COMPUTE L = FUNCTION LENGTH(FUNCTION MEAN(R1 R2 R3)).
Here R2 is evaluated to the mean value. Therefore, assuming that the symbol represents a blank space, the string "f " would be moved to R4 (the unfilled character positions in R4 are padded with spaces), and L evaluates to the value of 5. If R1 were the value "f", then R1 would be the mean value, and the string "f " would be moved to R4 (the unfilled character positions in R4 would be padded with spaces); the value 10 would be assigned to L.
You might be dealing with variable-length output from alphanumeric functions. Plan you program code accordingly. For example, you might need to think about using variable-length record files when it is possible that the records you will be writing might be of different lengths:
FILE SECTION. FD OUTPUT-FILE. 01 CUSTOMER-RECORD PIC X (80). WORKING-STORAGE SECTION. 01 R1 PIC X (50). 01 R2 PIC X (70). . . . WRITE CUSTOMER-RECORD FROM FUNCTION MEAN(R1 R2 R3).
If you have two or more alphanumeric data items and want to know which data item contains the largest value (evaluated according to the collating sequence), use the MAX or ORD-MAX function, supplying the data items in question as arguments. If you want to know which item contains the smallest value, you would use the MIN or ORD-MIN function.
The MAX and MIN functions simply return the contents of one of the variables you supply. For example, with these data definitions:
05 Arg1 Pic x(10) Value "THOMASSON ". 05 Arg2 Pic x(10) Value "THOMAS ". 05 Arg3 Pic x(10) Value "VALLEJO ".
the following statement;
Move Function Max(Arg1 Arg2 Arg3) To Customer-record(1:10)
would assign "VALLEJO " to the first ten character positions of Customer-record.
If MIN were used instead, then "THOMAS " would be returned.
The functions ORD-MAX and ORD-MIN return an integer that represents the ordinal position of the argument with the largest or smallest value in the list of arguments you have supplied (counting from the left). If the ORD-MAX function were used in the example above, you would receive a syntax error message at compile time, because you would be attempting to reference a numeric function in an invalid place (see WebSphere Development Studio: ILE COBOL Reference). The following is a valid example of the ORD-MAX function:
Compute x = Function Ord-max(Arg1 Arg2 Arg3)
This would assign the integer 3 to x, if the same arguments were used as in the previous example. If ORD-MIN were used instead, the integer 2 would be returned.
The results of alphanumeric functions might be of varying lengths and values depending on the function arguments. In the following example, the amount of data moved to R3 and the results of the COMPUTE statement depend on the values and sizes of R1 and R2:
01 R1 Pic x(10) value "e". 01 R2 Pic x(05) value "f". 01 R3 Pic x(20) value spaces. 01 L Pic 99. . . Move Function Max(R1 R2) to R3 Compute L = Function Length(Function Max(R1 R2))
Here, R2 is evaluated to be larger than R1. Therefore, assuming that the symbol represents a blank space, the string "f " would be moved to R3 (the unfilled character positions in R3 are padded with spaces), and L evaluates to the value 5. If R1 were the value "g" then R1 would be larger than R2, and the string "g " would be moved to R3 (the unfilled character positions in R3 would be padded with spaces); the value 10 would be assigned to L.
You might be dealing with variable-length output from alphanumeric functions. Plan your program code accordingly. For example, you might need to think about using variable-length record files when it is possible that the records you will be writing might be of different lengths:
File Section. FD Output-File. 01 Customer-Record Pic X(80). Working-Storage Section. 01 R1 Pic x(50). 01 R2 Pic x(70). . . Write Customer-Record from Function Max(R1 R2)
The LENGTH function is useful in many programming contexts for determining the length of string items. The following ILE COBOL statement shows moving a data item, such as a customer name, into the particular field in a record that is for customer names:
MOVE CUSTOMER-NAME TO CUSTOMER-RECORD(1:FUNCTION LENGTH(CUSTOMER-NAME)).
In addition to the LENGTH function, another technique to find the length of a data item is to use the LENGTH OF special register.
There is a fundamental difference between the LENGTH OF special register and the LENGTH Intrinsic Function. FUNCTION LENGTH returns the length of an item in character positions, whereas LENGTH OF returns the length of an item in bytes. In most cases, this makes little difference except for items with a class of DBCS.
For example:
77 CUSTOMER-NAME PIC X(30). 77 CUSTOMER-LOCATION-ASIA PIC G(50).
Coding either FUNCTION LENGTH(CUSTOMER-NAME) or LENGTH OF CUSTOMER-NAME will return 30; however coding FUNCTION LENGTH(CUSTOMER-LOCATION-ASIA) will return 50, whereas LENGTH OF CUSTOMER-LOCATION-ASIA will return 100.
Whereas the LENGTH function can only be used where arithmetic expressions are allowed, the LENGTH OF special register can be used in a greater variety of contexts. For example, the LENGTH OF special register can be used as an argument to an Intrinsic Function that allows integer arguments. (An Intrinsic Function cannot be used as an operand to the LENGTH OF special register.) The LENGTH OF special register can also be used as a parameter in a CALL statement.
If you want to know the date and time the program was compiled as provided by the system on which the program was compiled, you can use the WHEN-COMPILED function. The result returned has 21 character positions with the first 16 positions in the format:
YYYYMMDDhhmmsshh
to show the four-digit year, month, day, and time (in hours, minutes, seconds, and hundredths of seconds) of compilation.
The WHEN-COMPILED special register is another technique you can use to find the date and time of compilation. It has the format:
MM/DD/YYhh.mm.ss
The WHEN-COMPILED special register supports only a two-digit year and carries the time out only to seconds. The special register can only be used as the sending field in a MOVE statement.
If you want to know if a date-time, alphanumeric, numeric packed, or zoned item is a valid date, time, or timestamp data item, you can use the TEST-DATE-TIME intrinsic function. It can be useful to test for valid date-time data items before completing a move or calculation using another date-time intrinsic function, such as ADD-DURATION, or SUBTRACT-DURATION. The following example shows how to test for date-time data items:
IF FUNCTION TEST-DATE-TIME (date-3 DATE) = B'1' MOVE DATE-3 TO CUTOFF-DATE.
You can use intrinsic functions to work with durations between dates, times, and timestamps. For example, if you have two dates, and you want to know how many months fall in between the two dates, you can use the FIND-DURATION function to calculate this. You can also calculate due dates and stale dates (dates that have passed) using the ADD-DURATION and SUBTRACT-DURATION intrinsic functions.
For more information on using date-time data items, refer to Working with Date-Time Data Types.
The following example shows how to calculate how many days fall between two dates in date-time format:
01 YYYYMMDD FORMAT DATE "@Y%m%d". 01 EXPIRY-DATE FORMAT DATE "%m/%d/@Y" VALUE "10/31/1997". 01 DURATION PIC S9(5). . . . MOVE FUNCTION CURRENT-DATE(1:8) TO YYYYMMDD. COMPUTE DURATION = FUNCTION FIND-DURATION (YYYYMMDD EXPIRY-DATE DAYS). IF DURATION <= 0 THEN DISPLAY 'Expiry date, ' EXPIRY-DATE ' has passed.' END-IF.
The FIND-DURATION intrinsic function above subtracts YYYYMMDD from EXPIRY-DATE. If the date in YYYYMMDD becomes later than October 31, 1997, then the duration will be returned as a negative value. A duration of zero days or a negative number of days would indicate an expiry.
Assuming that the current date is November 1, 1997, the output of the above program would be:
Expiry date 10/31/1997 has passed.
The following example shows how to calculate a due date in a date-time format:
01 YYYYMMDD FORMAT DATE "@Y%m%d". 01 DATE-TIME-FORM FORMAT DATE "%m/%d/@Y". . . . MOVE FUNCTION CURRENT-DATE(1:8) TO YYYYMMDD. MOVE FUNCTION ADD-DURATION (YYYYMMDD DAYS 90) TO DATE-TIME-FORM. DISPLAY 'Due Date: ' DATE-TIME-FORM.
Assuming that the current date is October 8, 1997, the output of the above program would be:
Due Date: 01/06/1998
To calculate if a date is so far in the past that it invalidates the dated piece (such as a cheque), you could use the SUBTRACT-DURATION intrinsic function as follows:
01 YYYYMMDD FORMAT DATE "@Y%m%d". 01 STALE-DATE FORMAT DATE "%m/%d/@Y". 01 cheque-date FORMAT DATE "%m/%d/@Y" VALUE "03/09/1997". . . . MOVE FUNCTION CURRENT-DATE(1:8) TO YYYYMMDD. MOVE FUNCTION SUBTRACT-DURATION (YYYYMMDD DAYS 180) TO STALE-DATE. IF STALE-DATE > cheque-date THEN DISPLAY 'Cheque date, ' cheque-date ', is stale-dated.' DISPLAY 'The stale-date is: ' STALE-DATE END-IF.
Assuming that the current date is October 8, 1997, the output of the above program would be:
Cheque date, 03/09/1997, is stale-dated. The stale date is: 04/11/1997
(C) Copyright IBM Corporation 1992, 2005. All Rights Reserved.