IBM DFSORT, 11 3 строки по 71, 72 или 80 символов
OPTION COPY
OUTFIL REPEAT=12,OVERLAY=(5:SEQNUM,2,ZD,5,2,1,8,Y4T,LASTDAYM,TOJUL=Y4T*
,9,7,Y4T,ADDDAYS,+1,TOJUL=Y4T,1:16,7,Y4T,PREVDSUN,TOGREG=Y4T(-),12X)
Два ответа с колоночным форматом вывода выдержали испытание временем. Это дает мне "цикл", вроде того, что в OUTFIL REPEAT = копирует текущую запись много раз.
Другой способ получить значение, которое кажется длиннее, но короче, так как я не могу выработать какой-либо безусловный способ справиться с 12-й записью следующего года и сделать ее условной, включая IFTHEN=(WHEN=
, дважды и некоторые другие вещи. Прибыль на колебаниях (первый месяц - самый простой способ сделать это) сильно проигрывает на перекрестках (особые требования к синтаксису).
При этом используется встроенная функция (все функции в DFSORT встроены), чтобы найти последний день месяца. Затем добавляет один день (функцию), чтобы перейти к первому из следующего месяца, и использует функцию PREVDSUN, чтобы получить предыдущее воскресенье (которое всегда будет последним воскресеньем в предыдущем месяце, как и раньше).
При преобразовании года (ввода) в действительную дату для месяца используется двузначный порядковый номер, и это значение копируется также и для дня, поскольку начальная точка не имеет значения, если она действительна, как мы после последнего дня месяца изначально: 5,2
короче C'01'
.
Вот деталь:
OPTION COPY - копировать входной файл в выходной
OUTFIL - позволяет нескольким выходным файлам с различным выбором и форматированием создавать отформатированные отчеты. Используется предпочтительнее, чем короче INREC
из-за использования REPEAT=
.
REPEAT = 12 - произвести 12 копий каждой записи. В этом примере из-за SEQNUM может быть только одна входная запись (в отличие от предыдущей версии).
5: - начать с колонки 5 записи.
SEQNUM, 2, ZD - порядковый номер, по умолчанию начинается с одной, двух цифр, «десятичного зонного» (для беззнаковых, какими они будут, так же, как и символ).
1,8 - скопировать байты 1 на длину 8 в текущее местоположение (9). Это потому, что Y4T должен видеть это 8, иначе будет использоваться другой формат даты.
Y4T - дата в формате ccyymmdd (из-за 8 перед ним).
LASTDAYM - последний день месяца (также возможны неделя, квартал и год).
TOJUL = - выводить преобразование даты для функций даты (TOJUL на один символ меньше, чем TOGREG)
9,7 - теперь, когда это 7 длинных, Y4T будет CCYYDDD.
ADDDAYS - добавляет количество дней, корректируется автоматически, если переходит в следующий месяц / год (также могут быть ADDMONS и ADDYEARS)
PREVDSUN - наступает юлианская дата, расположено предыдущее воскресенье, TOGREG, чтобы получить правильный формат вывода, с разделителем "-" (может быть любым, что вам нравится в качестве разделителя)
12X - пробелы, чтобы убрать беспорядок, который позволил нам сделать это таким коротким способом
Выход из вышеперечисленного за 2014 год:
2014-01-26
2014-02-23
2014-03-30
2014-04-27
2014-05-25
2014-06-29
2014-07-27
2014-08-31
2014-09-28
2014-10-26
2014-11-23
2014-12-28
Что-то требуется, чтобы сказать СОРТУ, что делать. Там нет по умолчанию. OPTION COPY
самый короткий, SORT FIELDS=COPY
эквивалентный, но более длинный.
Саму работу он проделал на этот раз OUTFIL
(чтобы разрешить использование REPEAT). Рабочий код может быть любым из 160 (2 * 80), 144 (2 * 72), 140 (72 + 69) или 138 (70 + 68) (исключая начальные пробелы, принудительное продолжение и конечные пробелы).
Учитывая, что получатель должен знать, что он делает, я думаю, что могу сказать, что код DFSORT для перечисления последнего воскресенья каждого месяца для любого года с 1900 года (будет выполняться с года 0001, но я избегаю исследования, так как хорошо) до 9999 (хотя DFSORT поддерживает годы до 9999, предыдущее решение не будет работать в 9999, так как 12-е число переходит в следующий год) можно твитнуть.
Почему код такой длинный, если есть особенно подходящие встроенные функции?
Определения полей эфемерны. Поле определяется только как конкретное местоположение в данных (которое является записью) для его немедленного использования. Иными словами, поля не определены как таковые, но определены для каждого использования и только для использования. Функции даты должны знать, какой (из многих) форматов даты используется для источника, и выходные данные должны быть в формате даты, так что это должно быть указано.
Теперь, когда у нас свидание в юлианском стиле ... TBC?
OPTION COPY
INREC OVERLAY=(1,4,C'0201',1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8,1,8*
,94:C'1',89:1,4,ZD,ADD,+1,ZD,LENGTH=4,14:C'3',22:C'4',30:C'5',38:C'6',*
46:C'7',54:C'8',62:C'9',69:C'10',77:C'11',85:C'12',127:X,89,8,Y4T,PREV*
DSUN,TOGREG=Y4T(-),116:X,81,8,Y4T,PREVDSUN,TOGREG=Y4T(-),105:X,73,8,Y4*
T,PREVDSUN,TOGREG=Y4T(-),94:X,65,8,Y4T,PREVDSUN,TOGREG=Y4T(-),83:X,57,*
8,Y4T,PREVDSUN,TOGREG=Y4T(-),72:X,49,8,Y4T,PREVDSUN,TOGREG=Y4T(-),61:X*
,41,8,Y4T,PREVDSUN,TOGREG=Y4T(-),50:X,33,8,Y4T,PREVDSUN,TOGREG=Y4T(-),*
39:X,25,8,Y4T,PREVDSUN,TOGREG=Y4T(-),28:X,17,8,Y4T,PREVDSUN,TOGREG=Y4T*
(-),17:X,09,8,Y4T,PREVDSUN,TOGREG=Y4T(-),1:1,8,Y4T,PREVDSUN,TOGREG=Y4T*
(-),11:X,18,120,6X)
Нуждается в некоторых JCL
//LASTSUNG EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTOUT DD SYSOUT=*
//SYSIN DD *
И входной файл (еще одна строка JCL и три элемента данных instream):
//SORTIN DD *
2014
1900
2000
Производит:
2014-01-26 2014-02-23 2014-03-30 2014-04-27 2014-05-25 2014-06-29 2014-07-27 2014-08-31 2014-09-28 2014-10-26 2014-11-30 2014-12-28
1900-01-28 1900-02-25 1900-03-25 1900-04-29 1900-05-27 1900-06-24 1900-07-29 1900-08-26 1900-09-30 1900-10-28 1900-11-25 1900-12-30
2000-01-30 2000-02-27 2000-03-26 2000-04-30 2000-05-28 2000-06-25 2000-07-30 2000-08-27 2000-09-24 2000-10-29 2000-11-26 2000-12-31
Будет действительно работать до 9999 года.
DFSORT - это продукт IBM для сортировки мэйнфреймов. Данными можно манипулировать, но поскольку сортировка является ключевой, а сортировки часто бывают большими и длительными, у контрольных карт DFSORT нет циклических конструкций, поэтому мы не можем поместить SORT в цикл. Делает вещи немного скучными для таких задач, как гольф.
Зачем размещать ответ, потому что DFSORT имеет PREVDday
функцию. Так что в последнее воскресенье месяца это просто. Это предыдущее воскресенье (PREVDSUN) первого дня следующего месяца.
Было также забавно делать это в пределах одного «операнда» (OVERLAY), немного похоже на то, чтобы делать все это внутри sprintf
или аналогично.
Вот это не разгромлено:
OPTION COPY
INREC OVERLAY=(1,4,C'0201',1,8,1,8,1,8,1,8,1,8,1,8,
1,8,1,8,1,8,1,8,
1,8,94:C'1',89:1,4,ZD,ADD,+1,ZD,LENGTH=4,
14:C'3',22:C'4',30:C'5',38:C'6',46:C'7',54:C'8',
62:C'9',69:C'10',77:C'11',85:C'12',
127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
116:X,81,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
105:X,73,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
94:X,65,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
83:X,57,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
72:X,49,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
61:X,41,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
50:X,33,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
39:X,25,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
28:X,17,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
17:X,09,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
1:1,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
11:X,18,120,6X)
Хотя это и не совсем оскорбление, не принято пытаться втиснуть все это в один ОВЕРЛАЙ, и есть некоторые, казалось бы, ненужные вещи, которые необходимы, чтобы все это могло войти в один ОВЕРХЛЕЙ. Есть кое-что для игры в гольф, но так как он удалит только одну строчку, я не испытываю соблазна.
INREC обрабатывается для каждой записи.
OVERLAY позволяет изменять содержимое существующей записи. Если в процессе запись выходит за пределы его длины, это не проблема.
1,4 наступает год. К нему добавляется литерал 0201, а затем последовательные 1,8 повторяют это 11 раз, чтобы получить один длинный патрон из 96 байт,
К 12-му году расширенной текущей записи добавляется 1, а месяц - 1 (январь).
Оставшиеся 10 месяцев заменены на 3-11.
Тогда есть 12, в обратном порядке (из-за OVERLAY) этого типа вещи:
127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
N: номер столбца в записи. X вставляет пробел. 89,8 берет данные из этого столбца / длины, Y4T обрабатывает их как дату CCYYMMDD, PREVDSUM определяет предыдущее воскресенье, TOGREG = Y4T (-) выводит их как григорианскую дату CCYY-MM-DD.
Поскольку вы получаете мусор, если источник и цель определенной части OVERLAY деструктивно перекрываются, финал 11:X,18,120,6X)
переставляет и маскирует немного беспорядка.
Руководства и документы можно найти по адресу: http://www-01.ibm.com/support/docview.wss?uid=isg3T7000080 , и включает руководство по программированию приложений DFSORT на 900+ страниц.
Как и для всех продуктов IBM, все руководства доступны бесплатно (за исключением мучительно небольшого количества очень дорогих книг, которые даже очень небольшое количество людей в мире даже притворятся, что поймут).
Все контрольные карты DFSORT должны начинаться с пробела. Столбец 72 используется только для продолжения (подойдет любой непустой, но * обычный). За столбцом 72 следует область порядкового номера, которая игнорируется, делая каждую запись 80 байтов.
Может быть, еще пара решений.