How To Read a Date in Java from a COMP-3 field in COBOL?

2.9k Views Asked by At

I am trying to read a COBOL data file using JRecord, in that I have a Header record and Detail record, so I parsed with SPLIT_01_LEVEL and CopyBook File format as FMT_OPEN_COBOL. I have few date fields in the flat file as COMP-3 fields, and I am unable to understand on how to convert them into Java Date fields.

ICobolIOBuilder iob = CobolIoProvider.getInstance()
                 .newIOBuilder(copybookName)
                     .setCopybookFileFormat(Convert.FMT_OPEN_COBOL)
                     .setSplitCopybook(CopybookLoader.SPLIT_01_LEVEL);
//I fetched fields as below
line.getFieldValue(field).asString();

The CopyBook have fields as

MPOH-ENTRY-DATE              PIC S9(7) COMP-3.
MPOH-STATUS-DATE             PIC S9(7) COMP-3.
MPOH-APPROVED-DATE           PIC S9(7) COMP-3.
MPOH-ORDER-DATE              PIC S9(7) COMP-3.

When I parsed as above the output is

MPOH-ENTRY-DATE : 11261a1
MPOH-STATUS-DATE : 11261a1
MPOH-APPROVED-DATE : 11261a1
MPOH-ORDER-DATE : 11266140

Please help me in converting these fields to Java Date fields.

2

There are 2 best solutions below

5
On

From the Docs and how JRecords seems to be setup, you should be able to replace

line.getFieldValue(field).asString();

with

line.getFieldValue(field).asInt();

to get some meaningful result. If that int will be 20151204 or something else entirely remains to be seen - but if I remember my COBOL days correctly, it's probably yyyyMMdd just stored as number

3
On

The big problem is there has been an EBCDIC to ascii conversion.

The JRecord builder creation

ICobolIOBuilder iob = CobolIoProvider.getInstance()
             .newIOBuilder(copybookName)
                 .setCopybookFileFormat(Convert.FMT_OPEN_COBOL)
                 .setSplitCopybook(CopybookLoader.SPLIT_01_LEVEL);

does not include the setFont, so on a Unix / Linux / Windows PC, this indicates the file is ASCII. Which is not good if you are running on Window / Linux / Unix and the file was created on the mainframe, Also is the Data really comming from GNUCobol ???.

The data looks to has been through a EBCDIC -> Ascii conversion ??? or possibly shifted by 1 byte. If it really is GNU_Cobol you may need one of the other formats e.g. FMT_OPEN_COBOL_MVS


All 4 of the following numbers are not valid comp-3 numbers:

MPOH-ENTRY-DATE : 11261a1
MPOH-STATUS-DATE : 11261a1
MPOH-APPROVED-DATE : 11261a1
MPOH-ORDER-DATE : 11266140

The MPOH-ORDER-DATE is now x'11 26 61 40' while the EBCDIC original may of been x'11 50 81 7c' i.e.

CYY = 115 (or 2015)
 MM =  08 
 DD =  17

So you need to

  1. A binary transfer to Get the raw EBCDIC file. If it is a RECFM=VB file on the mainframe, convert it to RECFM=FB first.
  2. Add setFont("cp037") to the IOBuilder step (if you are using US ebcdic. There are different EBCDIC's for different countries e.g. cp273 for germany) .

    ICobolIOBuilder iob = CobolIoProvider.getInstance()
             .newIOBuilder(copybookName)
                 .setCopybookFileFormat(Convert.FMT_MAINFRAME)
                 .setSplitCopybook(CopybookLoader.SPLIT_01_LEVEL)
                 .setFont("cp037");
    
  3. For what it worth, the Dates look to be in a CYYMMDD format where C=0 is 1900 and C=1 is 2000


If I am not correct, please provide the raw data and the Copybook

The other alternative is a 1 byte error in the copybook displacement

e.g.

MPOH-ENTRY-DATE : 1?11261
MPOH-STATUS-DATE : 1?11261
MPOH-APPROVED-DATE : 1?11261
MPOH-ORDER-DATE : 112661

But it does not look like a Date ???


There not a big difference between Convert.FMT_MAINFRAME and Convert.FMT_OPEN_COBOL. But these are the differences:

  • GNU Cobol has 1, 2 ,4, 8 byte binary integers while the mainframe has 2, 4, 8
  • Comp-5 in GNU-Cobol (on intel hardware) is little ending (mainframe is big-endian).
  • Zoned decimal is different
  • different floating point (comp-1, comp-2).

The following fields are where you would seee a difference:

03 f1              pic s9(3).
03 f2              pic s99 comp.
03 f3              pic s9(4) comp-5  
03 f4     comp-1.
03 f5     comp-2.