IBM DFSORT, 11 3 lignes de 71, 72 ou 80 caractères
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)
Les deux réponses au format de sortie en colonnes ont résisté à l'épreuve du temps. Cela me donne une "boucle", en quelque sorte, dans la mesure où OUTFIL REPEAT = copie autant de fois l'enregistrement courant.
Technique différente pour arriver à la valeur, qui semble plus longue mais plus courte car je ne peux pas trouver de moyen inconditionnel pour gérer le 12e record de l'année suivante, et le rendre conditionnel signifie notamment IFTHEN=(WHEN=
, deux fois et d'autres choses. Gagner sur les balançoires (le premier du mois est le moyen le plus simple de le faire) perdre beaucoup sur les ronds-points (exigences de syntaxe particulières).
Cela utilise une fonction intégrée (toutes les fonctions de DFSORT sont intégrées) pour trouver le dernier jour du mois. Ajoute ensuite un jour (fonction) pour accéder au premier du mois suivant et utilise la fonction PREVDSUN pour obtenir le dimanche précédent (qui sera toujours le dernier dimanche du mois précédent, comme précédemment).
Lorsque vous transformez l'année (saisie) en une date valide, un numéro de séquence à deux chiffres est utilisé pour le mois, et cette valeur est également copiée pour le jour, car le point de départ n'a pas d'importance tant qu'il est valide, comme nous le sommes après le dernier jour du mois initialement: 5,2
est plus court que C'01'
.
Voici le détail:
OPTION COPY - copie le fichier d'entrée dans la sortie
OUTFIL - pour permettre à plusieurs fichiers de sortie, avec une sélection et une mise en forme différentes, de produire des rapports formatés. Utilisé de préférence au plus court en INREC
raison de l'utilisation de REPEAT=
.
REPEAT = 12 - produit 12 copies de chaque enregistrement. Dans cet exemple, il ne peut y avoir qu'un seul enregistrement d'entrée (contrairement à la version précédente) en raison du SEQNUM.
5: - commencez à la colonne 5 du dossier.
SEQNUM, 2, ZD - numéro de séquence, commence par défaut à un, deux chiffres, "décimale zonée" (pour non signé, ce sera le même que le caractère).
1,8 - copiez les octets 1 de la longueur 8 vers l'emplacement actuel (9). En effet, le Y4T doit voir 8, sinon un format de date différent sera utilisé.
Y4T - date au format ccyymmdd (en raison du 8 immédiatement devant).
LASTDAYM - Dernier jour du mois (également possible de la semaine, du trimestre et de l'année).
TOJUL = - sortie date-conversion pour les fonctions de date (TOJUL est un caractère de moins que TOGREG)
9,7 - maintenant qu'il fait 7 longs, Y4T va être CCYYDDD.
ADDDAYS - ajoute un certain nombre de jours, s'ajustant automatiquement si le mois / l'année suivant (peut également être ADDMONS et ADDYEARS)
PREVDSUN - la date julienne entre en jeu, le dimanche précédent est localisé, TOGREG pour obtenir le format de sortie correct, avec le séparateur "-" (pourrait être tout ce que vous aimez comme séparateur)
12X - des blancs pour nettoyer le gâchis qui nous a permis de le faire en si peu de temps
Les résultats de ce qui précède, pour 2014, sont les suivants:
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
Quelque chose est nécessaire pour dire au SORT quoi faire. Il n'y a pas de défaut. OPTION COPY
est le plus court, SORT FIELDS=COPY
est équivalent mais plus long.
Le travail lui-même effectué cette fois-ci OUTFIL
(pour permettre l'utilisation de REPEAT). Le code de travail est sans doute l'un de 160 (2 * 80), 144 (2 * 72), 140 (72 + 69) ou 138 (70 + 68) (à l'exclusion des blancs de début, de la poursuite forcée et des blancs de fin).
Étant donné que le récepteur devrait savoir ce qu'ils font, je pense que je peux dire que le code DFSORT pour répertorier le dernier dimanche de chaque mois pour n'importe quelle année à partir de 1900 (se déroulera à partir de l'année 0001, mais j'évite la recherche car bien) jusqu'à 9999 (bien que DFSORT prenne en charge les années jusqu'à 9999, la solution précédente ne fonctionnerait pas dans l'année 9999 puisque la 12e date va dans l'année suivante) peut être tweeté.
Pourquoi le code est-il si long, s'il existe des fonctions intégrées particulièrement adaptées?
Les définitions de champ sont éphémères. Un champ est uniquement défini comme un emplacement particulier dans les données (qui est un enregistrement) pour son utilisation immédiate. En d'autres termes, les champs ne sont pas définis en tant que tels, mais sont définis pour chaque utilisation et uniquement pour une utilisation. Les fonctions de date doivent savoir quels (parmi de nombreux) formats de date sont utilisés pour la source, et la sortie doit être dans un format de date, ce qui doit être spécifié.
Maintenant que nous avons une date julienne ... à confirmer?
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)
En a besoin JCL
//LASTSUNG EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTOUT DD SYSOUT=*
//SYSIN DD *
Et un fichier d'entrée (une autre ligne de JCL et trois éléments de données instream):
//SORTIN DD *
2014
1900
2000
Produit:
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
Fonctionnera réellement jusqu'à l'année 9999.
DFSORT est le produit de tri IBM Mainframe. Les données peuvent être manipulées, mais comme le tri est essentiel et que les tris sont souvent volumineux et de longue durée, les cartes de contrôle DFSORT n'ont pas de constructions en boucle, donc nous ne pouvons pas mettre un SORT dans une boucle. Rend les choses un peu longues pour des tâches comme le golf.
Pourquoi publier la réponse, c'est parce que DFSORT a une PREVDday
fonction. Donc, dimanche dernier d'un mois est facile. C'est le dimanche précédent (PREVDSUN) jusqu'au premier jour du mois suivant.
C'était aussi amusant de le faire dans un "opérande" (OVERLAY), un peu comme tout faire dans sprintf
ou similaire.
Ici, il n'est pas golfé:
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)
Bien qu'il ne soit pas tout à fait abusif, il ne serait pas habituel de tenter de regrouper tout cela en un seul OVERLAY, et il y a des choses apparemment inutiles qui sont nécessaires pour que tout puisse aller dans un OVERLAY. Il y a de la place pour le golf, mais comme cela ne supprimerait qu'une seule ligne au maximum, je ne suis pas tenté.
L'INREC est traité pour chaque enregistrement.
OVERLAY permet de modifier le contenu d'un enregistrement existant. Si l'enregistrement est étendu au-delà de sa longueur dans le processus, ce n'est pas un problème.
1,4 est l'année qui vient. Il a un littéral de 0201, puis les 1,8 successifs le répètent 11 fois pour donner un long mandrin de 96 octets,
La douzième année du record actuel étendu est ajoutée à 1 et son mois est passé à 1 (janvier).
Les 10 mois restants sont passés de 3 à 11.
Ensuite, il y a 12, dans l'ordre inverse (en raison de la superposition) de ce type de chose:
127:X,89,8,Y4T,PREVDSUN,TOGREG=Y4T(-),
Le n: est un numéro de colonne sur l'enregistrement. Le X insère un blanc. 89,8 prend les données de cette colonne / longueur, Y4T les traite comme une date CCYYMMDD, PREVDSUM fonctionne le dimanche précédent, TOGREG = Y4T (-) les affiche comme une date grégorienne CCYY-MM-DD.
Parce que vous obtenez des ordures si la source et la cible d'une partie particulière d'un OVERLAY se chevauchent de manière destructrice, la dernière 11:X,18,120,6X)
réorganisation et masque un peu le désordre.
Les manuels et les documents peuvent être consultés à l' adresse : http://www-01.ibm.com/support/docview.wss?uid=isg3T7000080 et incluent le guide de programmation d'application DFSORT de 900+ pages.
Comme avec tous les produits IBM, tous les manuels sont disponibles gratuitement (à l'exception d'une quantité atrocement petite de très chers que seul un très petit nombre de personnes dans le monde prétendraient même comprendre).
Toutes les cartes de contrôle DFSORT doivent commencer par un blanc. La colonne 72 est uniquement utilisée pour la continuation (tout élément non vide fera l'affaire, mais * est conventionnel). La colonne 72 est suivie d'une zone de numéro de séquence qui est ignorée, ce qui fait que chaque enregistrement 80 octets.
Un autre couple de solutions à venir, peut-être.