Find if a Year is Leap Year

It is quite easy to identify if a given Year is a Leap Year or not using COBOL intrinsic functions. To be a Leap Year, the Year should be divisible by 4 and not divisible by 100. If divisible by 100, then it should also be divisible by 400.












The following code is present in the Screenshot above.

01 WS-YEAR                     PIC 9(04). 

EVALUATE TRUE                                  
    WHEN FUNCTION MOD (WS-YEAR 4)   NOT ZERO    
    WHEN FUNCTION MOD (WS-YEAR 100)     ZERO    
     AND FUNCTION MOD (WS-YEAR 400) NOT ZERO    
    DISPLAY 'IT IS NOT A LEAP YEAR ' WS-YEAR 
WHEN OTHER                                      
    DISPLAY 'IT IS A LEAP YEAR     ' WS-YEAR 
END-EVALUATE.


Another way of identifying is by converting it to Gregorian Date as given below.





















The following code is present in the Screenshot above.

01 WS-JULIAN-DATE.
    05 WS-JULIAN-YR            PIC 9(04).
    05 WS-JULIAN-DDD           PIC 9(03)  VALUE 060.
01 WS-JULIAN-DATE-R REDEFINES WS-JULIAN-DATE PIC 9(07).

01 WS-GREGORIAN-DATE           PIC 9(08).
    05 WS-GREGORIAN-DATE-R REDEFINES WS-GREGORIAN-DATE.
        10 WS-GREGORIAN-YR     PIC 9(04).
        10 WS-GREGORIAN-MM     PIC 9(02).
        10 WS-GREGORIAN-DD     PIC 9(02).

01 WS-YEAR                     PIC 9(04).

MOVE WS-YEAR       TO WS-JULIAN-YR.

COMPUTE WS-GREGORIAN-DATE = FUNCTION DATE-OF-INTEGER 
                            (FUNCTION INTEGER-OF-DAY 
                            (WS-JULIAN-DATE-R)).

IF WS-GREGORIAN-MM = 02
    DISPLAY 'IT IS A LEAP YEAR     ' WS-YEAR
ELSE
    DISPLAY 'IT IS NOT A LEAP YEAR ' WS-YEAR 
END-IF.

Get the Last Date of the Month

Using COBOL intrinsic functions, we can find the last Date of the Month for any given Gregorian Date.




















The below code is present in the above screenshot.

01 WS-MONTH-END-DD             PIC X(24) VALUE              
                               '312831303130313130313031'. 
01 WS-TBL-MONTH-END REDEFINES WS-MONTH-END-DD.              
    05 TBL-MONTH-END-DAY       PIC 9(02) OCCURS 12 TIMES.  

01 WS-GREG-DATE. 
   05 WS-GREG-YEAR             PIC 9(04). 
   05 WS-GREG-MNTH             PIC 9(02). 
   05 WS-GREG-DAY              PIC 9(02). 

EVALUATE TRUE                                      
    WHEN FUNCTION MOD (WS-GREG-YEAR 4)   NOT ZERO    
    WHEN FUNCTION MOD (WS-GREG-YEAR 100)     ZERO      
     AND FUNCTION MOD (WS-GREG-YEAR 400) NOT ZERO 
    MOVE '28' TO WS-TBL-MONTH-END (3: 2)          
WHEN OTHER                                        
    MOVE '29' TO WS-TBL-MONTH-END (3: 2)          
END-EVALUATE                                      
                                                  
MOVE TBL-MONTH-END-DAY(WS-GREG-MNTH)              
                           TO WS-GREG-DAY 
        
DISPLAY 'LAST-DATE OF MONTH:' WS-GREG-DATE

Difference between 2 Timestamps in Seconds

We can leverage the language environment callable service CEESECS which will convert timestamp to seconds.








































The below code is present in the above screenshot.

01 WS-SECOND1                 COMP-2.      
01 WS-SECOND2                 COMP-2.      
01 WS-TIMESTAMP-1             PIC X(26).  
01 WS-TIMESTAMP-2             PIC X(26).  
01 WS-FORMAT                  PIC X(26).  
01 WS-DIFFERENCE              PIC +9(09).                    
                                                        
01  WS-FC-CODE.                                          
    05 FC-SEVERITY            PIC S9(4) COMP.          
    05 FC-MESSAGE             PIC S9(4) COMP.          
    05 FILLER                 PIC X(08).              

MOVE '2004-03-23-15.35.39.838149' TO WS-TIMESTAMP-1 
MOVE '2004-05-17-13.07.18.234567' TO WS-TIMESTAMP-2 
MOVE 'YYYY-MM-DD-HH.MI.SS.999999' TO WS-FORMAT      
                                                    
CALL 'CEESECS' USING WS-TIMESTAMP-1,                
               WS-FORMAT,                            
               WS-SECOND1,                          
               WS-FC-CODE                            

IF FC-SEVERITY = +0                                  
   CONTINUE                                          
ELSE                                                
   DISPLAY 'CEESECS ROUTINE ERROR' 
   PERFORM INHOUSE-ABEND-ROUTINE 
END-IF                                              
                                                    
CALL 'CEESECS' USING WS-TIMESTAMP-2,                
               WS-FORMAT,                            
               WS-SECOND2,                          
               WS-FC-CODE                            

IF FC-SEVERITY = +0                                  
   CONTINUE                                          
ELSE                                                
   DISPLAY 'CEESECS ROUTINE ERROR' 
   PERFORM INHOUSE-ABEND-ROUTINE 
END-IF                                              
                                                    
COMPUTE WS-DIFFERENCE = WS-SECOND2 - WS-SECOND1      
                                                    
DISPLAY 'THE DIFFERENCE BETWEEN 2 TIMESTAMPS IS:'    
         WS-DIFFERENCE


Find difference between 2 Dates

To calculate the difference between 2 given Dates, COBOL intrinsic functions can be used.








The below code is present in the above screenshot.

01 WS-DATE-DIFF                PIC S9(08) COMP. 
01 WS-DATE1                    PIC 9(08). 
01 WS-DATE2                    PIC 9(08).  

COMPUTE WS-DATE-DIFF = FUNCTION INTEGER-OF-DATE(WS-DATE2) -  
                       FUNCTION INTEGER-OF-DATE(WS-DATE1)

Subtract Days from a Gregorian Date

We can easily subtract number of Days from a given Gregorian Date to get a past Date using COBOL intrinsic functions.








The below code is present in the above screenshot.

01 WS-GREGORIAN-DATE           PIC 9(08). 
01 WS-SUB-DAYS                 PIC 9(08). 
01 WS-PAST-DATE                PIC 9(08). 

     COMPUTE WS-PAST-DATE  = FUNCTION DATE-OF-INTEGER            
       (FUNCTION INTEGER-OF-DATE(WS-GREGORIAN-DATE) - WS-SUB-DAYS)

Add Days to a given Gregorian Date

We can easily add number of Days to a given Gregorian Date to get a future Date using COBOL intrinsic functions.








The below code is present in the above screenshot.

01 WS-FUTURE-DATE              PIC 9(08). 
01 WS-ADD-DAYS                 PIC 9(08). 
01 WS-GREGORIAN-DATE           PIC 9(08). 

COMPUTE WS-FUTURE-DATE = FUNCTION DATE-OF-INTEGER            
  (FUNCTION INTEGER-OF-DATE(WS-GREGORIAN-DATE) + WS-ADD-DAYS)

Convert Gregorian Date to Julian Date and vice-versa

We often need to convert date from one format to another. This can be done using COBOL intrinsic functions.











The below code is present in the above screenshot.

01 WS-GREGORIAN-DATE           PIC 9(08).    
01 WS-JULIAN-DATE              PIC 9(07).    

COMPUTE WS-JULIAN-DATE    = FUNCTION DAY-OF-INTEGER      
                            (FUNCTION INTEGER-OF-DATE    
                            (WS-GREGORIAN-DATE))        
                                                                                                              
COMPUTE WS-GREGORIAN-DATE = FUNCTION DATE-OF-INTEGER 
                            (FUNCTION INTEGER-OF-DAY 
                            (WS-JULIAN-DATE))

Shortest COBOL program that runs successfully

The below is the shortest COBOL code that will compile and execute successfully. It can be used to generate the compiler listing with explanations.


Shortest COBOL Program which ABENDs during execution

The shortest COBOL code that will compile successfully but ABEND during execution is of 3 lines. 






But if NOCMPR2 Compiler Option (obsolete with Enterprise COBOL) is used, the PROCEDURE DIVISION is not needed thus reducing it to 2 lines.

Quine Program

Quine is a computer program which accepts no input and produces a copy of its own source code as its only output. Please find below a sample quine in COBOL.



Summing Fields

Sort can be used to sum fields using SORT and SUM statements. Let's take the below example of a list of Students appearing for different Subjects in Mechanical Engineering. The Maximum Score for each Subject and the Score secured by each Student in the Subject is provided.














If we have a requirement to get the Total Score for each Student and the Maximum Score possible for each, SUM statement will be useful.

















The below code is present in the above screenshot.

//SORTJCL# JOB (NXYZ),'SORT',NOTIFY=&SYSUID,CLASS=0,MSGCLASS=5
//***************************************************************
//* SORT JOB TO SUM ON TWO FIELDS FOR SORT ON ANOTHER FIELD  
//***************************************************************
//JS0100   EXEC PGM=SORT
//   PARM='DYNALLOC=(SYSDA,255),VSCORE=2M,VSCORET=256M'
//SORTIN   DD DISP=SHR,DSN=Input File Name,
//SORTOUT  DD DSN=Output File Name,
//         DISP=(NEW,CATLG,DELETE),
//         SPACE=(CYLS,(100,40),RLSE),                              
//         DATACLAS=DCTCOM,VOL=(,,,24)
//SYSOUT   DD SYSOUT=*
//SYSIN    DD *
 SORT FIELDS=(1,7,CH,A)
 SUM FIELDS=(35,3,ZD,53,3,ZD)                       
/*

The final output will have the Sum Total of Marks for all Subjects for each Student as well as the Total Marks Secured by the Student across all Subjects.








For the Subject field, the first row will be retained. It maybe more prudent to remove this field from the final result using an OUTREC statement.

Skip and select records from file

We can use SORT to select records from input file to output file. The following JCL can be used for skipping some records from the input file (10 in the example) and then selecting a particular number of records (100 in the example) to the output file.













The below code is present in the above screenshot.

//SORTJCL# JOB (NXYZ),'SORT',NOTIFY=&SYSUID,CLASS=0,MSGCLASS=5
//***************************************************************
//* SORT JOB TO SKIP SOME RECORDS AND THEN SELECT SOME RECORDS  
//***************************************************************
//JS0100   EXEC PGM=SORT
//SORTIN   DD DISP=SHR,DSN=Input File Name,
//SORTOUT  DD DSN=Output File Name,
//         DISP=(NEW,CATLG,DELETE),
//         SPACE=(CYLS,(100,40),RLSE),
//         DATACLAS=DCTCOM,VOL=(,,,24)
//SYSOUT   DD SYSOUT=*
//SYSIN    DD *
 OPTION COPY,SKIPREC=10,STOPAFT=100                       
/*