问题
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.
回答1:
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
- 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.
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");
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.
回答2:
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
来源:https://stackoverflow.com/questions/34093560/how-to-read-a-date-in-java-from-a-comp-3-field-in-cobol