Как прочитать дату в Java из поля COMP-3 в COBOL?
Я пытаюсь прочитать файл данных COBOL с помощью JRecord, так как у меня есть запись заголовка и запись сведений, поэтому я проанализировал 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 ответа
Большая проблема заключается в преобразовании EBCDIC в ascii.
Создание JRecord строитель
ICobolIOBuilder iob = CobolIoProvider.getInstance()
.newIOBuilder(copybookName)
.setCopybookFileFormat(Convert.FMT_OPEN_COBOL)
.setSplitCopybook(CopybookLoader.SPLIT_01_LEVEL);
не включает setFont, поэтому на ПК с Unix / Linux / Windows это означает, что файл является ASCII. Что не очень хорошо, если вы работаете в Window / Linux / Unix и файл был создан на мэйнфрейме, также действительно ли данные поступают из 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
Так что вам нужно
- Двоичный перевод для получения необработанного файла EBCDIC. Если это файл RECFM=VB на мэйнфрейме, сначала преобразуйте его в RECFM=FB.
Добавьте setFont("cp037") к шагу IOBuilder (если вы используете ebcdic в США. Для разных стран существуют разные EBCDIC, например, cp273 для Германии) .
ICobolIOBuilder iob = CobolIoProvider.getInstance() .newIOBuilder(copybookName) .setCopybookFileFormat(Convert.FMT_MAINFRAME) .setSplitCopybook(CopybookLoader.SPLIT_01_LEVEL) .setFont("cp037");
Что бы это ни стоило, даты выглядят в формате CYYMMDD, где C=0 - 1900, а C=1 - 2000
Если я не прав, предоставьте необработанные данные и тетрадь
Другой альтернативой является ошибка в 1 байт при смещении тетради.
например
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
- Comp-5 в GNU-Cobol (на оборудовании Intel) не имеет большого окончания (мэйнфрейм имеет старшие порядковые номера) .
- Зональная десятичная дробь отличается
- разные с плавающей запятой (комп-1, комп-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.
Из документации и того, как JRecords, кажется, настроен, вы сможете заменить
line.getFieldValue(field).asString();
с
line.getFieldValue(field).asInt();
чтобы получить какой-то значимый результат. Если это int будет 20151204 или что-то еще, что еще неизвестно - но если я правильно помню мои дни COBOL, то, вероятно, yyyyMMdd просто хранится как число