如何从COBOL中的COMP-3字段读取Java中的日期?

时间:2015-12-04 16:58:35

标签: java date cobol mainframe jrecord

我正在尝试使用JRecord读取COBOL数据文件,因为我有一个Header记录和详细记录,因此我使用SPLIT_01_LEVEL和CopyBook文件格式解析为FMT_OPEN_COBOL。我在平面文件中有几个日期字段作为COMP-3字段,我无法理解如何将它们转换为Java日期字段。

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();

CopyBook的字段为

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.

当我按上面解析时,输出是

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

请帮我将这些字段转换为Java日期字段。

2 个答案:

答案 0 :(得分:6)

最大的问题是有一个 EBCDIC到ascii 的转换。

JRecord构建器

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

不包含 setFont ,因此在Unix / Linux / Windows PC上,这表示该文件是ASCII。如果你在Window / Linux / Unix上运行并且文件是在大型机上创建的,那么这是不好的,同样是Data真正来自GNUCobol ???。

数据看起来是通过EBCDIC - > Ascii转换???或者可能移动1个字节。如果它确实是GNU_Cobol,您可能需要其他格式之一,例如FMT_OPEN_COBOL_MVS

以下所有4个号码都是无效的comp-3 号码:

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

MPOH-ORDER-DATE现在为x'11 26 61 40',而EBCDIC原件可能是 x'11 50 81 7c'即

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

所以你需要

  1. 获取原始EBCDIC文件的二进制传输。如果它是主机上的RECFM = VB文件,请先将其转换为RECFM = FB。
  2. 将setFont(“cp037”)添加到IOBuilder步骤(如果您使用的是US ebcdic。不同国家/地区有不同的EBCDIC,例如德国的cp273)。

    ICobolIOBuilder iob = CobolIoProvider.getInstance()
             .newIOBuilder(copybookName)
                 .setCopybookFileFormat(Convert.FMT_MAINFRAME)
                 .setSplitCopybook(CopybookLoader.SPLIT_01_LEVEL)
                 .setFont("cp037");
    
  3. 值得一提的是,日期看起来是CYYMMDD格式,其中C = 0是1900而C = 1是2000

  4. 如果我不正确,请提供原始数据和Copybook

    另一种选择是字帖位移中的1字节错误

    e.g。

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

    但它看起来不像日期???

    Convert.FMT_MAINFRAME和Convert.FMT_OPEN_COBOL之间没有太大区别。但这些是差异:

    • GNU Cobol有1,2,4,8字节的二进制整数,而大型机有2,4,8
    • GNU-Cobol中的Comp-5(在intel硬件上)是小结局(大型机是big-endian)。
    • 分区十进制不同
    • 不同的浮点数(comp-1,comp-2)。

    以下字段是您可以看到差异的地方:

    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.
    

答案 1 :(得分:1)

从Docs以及如何设置JRecords,您应该能够替换

line.getFieldValue(field).asString();

line.getFieldValue(field).asInt();

获得一些有意义的结果。如果那个int将是20151204或其他东西完全还有待观察 - 但如果我正确地记住了我的COBOL天,它可能是yyyyMMdd只是存储为数字