RPG-IV : Variables date/heure (y compris V5R10)

BoTTom |    Changer de couleur
     RPG-IV reconnait les variables date/heure depuis la V3R10. 
 
                    SDD              SQL           RPG-IV     
 type de donnée :  | L = date      | DATE      |      D   |
                   | T = heure     | TIME      |      T   |
                   | Z = timestamp | TIMESTAMP |      Z   | 
 
   les dates peuvent avoir un des formats suivants :
 
   format      lg   présentation            séparateur       
    *YMD        8 40/01/01 à 39/12/31     au choix '.' '/' '-' '&'=blanc
    *DMY        8 01/01/40 à 31/12/39       - idem -
    *MDY        8 01/01/40 à 12/31/39       - idem -
    *JUL        6 40/001   à 39/365         - idem -
    *JOB        ? DSPF uniquement -> *DMY à l'écran / *ISO dans le programme
 
ou un format normalisé :
 
    *ISO       10 yyyy-mm-dd (format par dft) imposé '-'
    *USA       10 mm/dd/yyyy                    "    '/'
    *EUR       10 dd.mm.yyyy                    "    '.'
    *JIS       10 yyyy-mm-dd                    "    '-' (standard Japonais)


|    Changer de couleur
 
 Une variable de type heure accepte les formats suivants :
 
   format      lg   présentation            séparateur       
    *HMS        8 00:00:00 à 24:00:00     au choix '.' '/' '-' '&'=blanc
    *ISO        8 00.00.00 à 24.00.00     imposé '.'
    *USA        8 00:00 AM à 12:00 AM     imposé ':'
    *EUR        8 00.00.00 à 24.00.00     imposé '.'
    *JIS        8 00:00:00 à 24:00:00     imposé ':'
 
  Les variables horodatage n'ont qu'un seul format :
                  yyyy-mm-dd-hh.mm.ss.uuuuuu
                  <--date--><-heure-><micro-
                                      secondes>
 
 ces variables date sont stockées physiquement(format interne) sous la forme:
                 - date       =  4 octets
                 - heure      =  3 octets    ce qui permet toutes formes
                 - horodatage = 10 octets      de comparaisons.
 
 mais nous les voyons TOUJOURS (DSPPFM,RPG IV, DUMP) sous le format externe
  d'une "date éditée" (en clair, avec les séparateurs)


|    Changer de couleur
Ces paramètres peuvent être indiqués :
 
    sur une spécif I niveau zone  31-34 = format
                                  35    = séparateur
        quand la position 36 (type), contient D,T ou Z.
 
    sur une spécif O niveau zone  53-80 = format[séparateur]
 
Pour un fichier externe ces infos sont reprises de la définition SDD.
 
Sinon, le système recherche: !  sur la définition (spécif I, O ou D)
                             !  sur la spécif F (mot-clé DATFMT,TIMFMT)
                             !  sur la spécif H ( - idem -            )
                             V  *ISO par défaut.
 
Les mots-clés DATFMT, TIMFMT ont la syntaxe suivante:
 
                      DATFMT(format[séparateur])
                      TIMFMT(format[séparateur])
 [séparateur] n'est admis que pour les formats ayant un séparateur au choix.
 
 exemples : DATFMT(*EUR)  -  DATFMT(*DMY/)  -  TIMFMT(*ISO)


|    Changer de couleur
 Ne pas confondre DATFMT = format des variables date par défaut
                   et
                  DATEDIT = format de UDATE(6dt 0) et *DATE(8dt 0).
 
 Toute constante peut être précédée de T'    ', D'    ', Z'    ' .
 
 Exemple :
     DWDATE            S               D   DATFMT(*DMY/)
 puis                                 v-------------------[format specif H]
     C                   move      D'1995-07-15' wdate
  ou
     DWDATISO          S               D   DATFMT(*ISO)
     D                                     INZ(D'1995-07-15')
  ou encore
     Ddsdate           DS
     D cejour                          D   DATFMT(*ISO)  INZ
     D  an                            4   0OVERLAY(cejour)
     D  mois                          2   0OVERLAY(cejour:6)
     D  jour                          2   0OVERLAY(cejour:9)
     C                   move      *YEAR         an
     C                   move      *MONTH        mois
     C                   move      *DAY          jour


|    Changer de couleur
 manipulation :
 
  Toute comparaison de dates entre elles,
                       heures entre elles
    est cohérente indépendamment du format ! 
 
  La conversion est assurée par MOVE,MOVEL ou %DATE,%DEC en /free .
 
           date <-> date, etc..., changement de format transparent.
           numérique,caractère <-> Date
           numérique,caractère <-> heure
           numérique,caractère <-> horodatage
 
 le facteur 1 permet alors de préciser le format de l'élément
  numérique ou caractère.
 (*ISO, *EUR , *YMD , *DMY etc... plus *CYMD ou *JOBRUN)
 
 Exemple : 
     DNUMDAT           S              8  0 INZ(19950715)
     DWDATEUR          S               D   DATFMT(*EUR)
 
     C       *ISO        move      numdat        wdateur


|    Changer de couleur
 Pour les variables alpha, il est possible d'indiquer le séparateur dans le
  format (facteur 1 ou paramètre de %DATE ) :
 
   *fmtX  avec fmt pour le format et X pour le séparateur
                                     & pour un espace
                                     0 pour indiquer l'absence de séparateur
 
    *ymd/ indique une variable alpha de 8 c contenant   AA/MM/JJ
 
    *ymd.    "     "     "       "             "        AA.MM.JJ
 
    *ymd&    "     "     "       "             "        AA MM JJ
 
    *ymd0    "     "     "       "   de 6 c    "        AAMMJJ
 
       /free
         // exemple valide à partir de la V5R10 :
 
         datchar = '17092001'            ;
         datcmd = %DATE(datchar : *EUR0) ; //*EUR avec le chiffre 0
 
       /end-free


|    Changer de couleur
 le code opération TIME (historique) est modifié :
 
    TIME avec une zone résultat de 12 ==> HHMMSSAAMMJJ
                                   14 ==> HHMMSSAAAAMMJJ
                                date  ==> date en cours
                                heure ==> l'heure en cours
                                horodatage ==> l'horloge système
 
    En /free, utilisez %DATE(), %TIME(), %TIMESTP() [sans argument]
 
 Le nouveau code opération TEST, permet de tester la validité.
 
 TEST(D|T|Z)
 
 - la zone résultat est une variable numérique ou charactère
 
 - il faut indiquer un format en facteur 1 (comme le MOVE)
    et soit un indicateur (pos <<), soit (E) et tester: if %error.
 
Exemple :
 
     C       *YMD        TEST(D E)               datchar


|    Changer de couleur
 
 Notion de durée (avant la V5R10) :
 
  le code opération ADDDUR permet d'ajouter une durée à une date
                                     (le résultat est une date)
 
  Le code opération SUBDUR permet 1/ de soustraire une durée à une date
                                     (le résultat est une date)
 
                                  2/ de soustraire une date à une date
                                     (le résultat est une durée)
 
 Une durée est un entier numérique (constante ou variable [15 maxi])
  suivi d'un code (séparé par :), représentant la signification :
 
      *YEARS    ou *Y : la durée est exprimée en nbr d'années
      *MONTHS   ou *M                            nbr de mois
      *DAYS     ou *D                            nbr de jours
      *HOURS    ou *H                            nbr d'heures
      *MINUTES  ou *MN                           nbr de minutes
      *SECONDS  ou *S                            nbr de secondes
      *MSECONDS ou *MS                           nbr de microsecondes


|    Changer de couleur
 
  la version 5.10 permet de calculer avec des dates/heures en format
   libre :
 
           date2 = date1 + durée ;
 
           date3 = date2 - durée ;
 
           la fonction %DIFF() permet d'obtenir un écart
 
  la représentation des durées est alors réalisée à l'aide des fonctions
   intégrées du RPG :
 
           %DAYS(x)     pour ajouter/retrancher x jours
           %MONTHS(x)   pour ajouter/retrancher x mois
           %YEARS(x)    pour ajouter/retrancher x années
 
           %HOURS(x)    pour ajouter/retrancher x heures
           %MINUTES(x)  pour ajouter/retrancher x minutes
           %SECONDS(x)  pour ajouter/retrancher x secondes
           %MSECONDS(x) pour ajouter/retrancher x micro-secondes
 


|    Changer de couleur
 Exemples:
 
      dat2 = dat1 + 12 mois
     C       DAT1        ADDDUR    12:*M         DAT2
 
      dat2 = dat2 + 45 jours
     C                   eval      nbj = 45
     C                   ADDDUR    nbj:*D        DAT2
 
      dat2 = dat1 - 3 mois
     C       DAT1        SUBDUR    3:*M          DAT2
 
      nbm = nombre de mois d'écart entre dat1 et dat2
     C       DAT1        SUBDUR    DAT2          nbm:*M
ATTENTION !
   Vous ne pouvez pas tester  "IF  nbm > 3",
   le système considère qu'il y a 3 mois d'écart entre 15/07/95 et 31/10/95
   (le nombre de mois est une information qui ne tient pas compte des jours)
 
   Pour tester que dat2 n'est pas > de plus de 3 mois  à dat1, écrivez :
     C       DAT1        ADDDUR    3:*M          DATMAX
     C                   IF        dat2 > datmax


|    Changer de couleur
 Exemples (V5R10) :
      /free
 
       // dat2 = dat1 + 12 mois
             DAT2 = DAT1 + %MONTHS(12) ;
 
       // dat2 = dat2 + 45 jours
             nbj = 45                  ;
             DAT2 += %DAYS(nbj)  ;
 
       // dat2 = dat1 - 3 mois
             DAT2 = DAT1 - %MONTHS(3)   ;
 
       // nbm = nombre de mois d'écart entre dat1 et dat2
             nbm = %DIFF(dat1 : dat2 : *M) ;
 
 // Pour tester que dat2 n'est pas > de plus de 3 mois  à dat1, écrivez :
 
          if    dat2 > dat1 + %MONTHS(3);
 
      /end-free
 


|    Changer de couleur
 
 Il est possible de calculer l'écart (la durée) entre :
 
    une date et un horodatage  , une heure et un horodatage
 
 Une durée peut être négative.
 
     Le résultat d'une différence peut être négatif (si dat1 < à dat2)
 
     Ajouter -90 jours (= soustraire 90 jours, qui l'eut cru ?)
 
 Ajouter un nombre de jours va impacter la partie mois (et peut-être année)
 
 Ajouter un nombre de mois va peut-être modifier l'année, en aucun cas
  le jour. ( sauf fin de mois : 31/01 + 1 mois = 28/02 ou 29/02 )
 
 Modifier la partie heure d'un horodatage, peut impacter la partie date.
 
 
 Il n'y a pas de fonction pour retrouver le dernier jour du mois
  mais le changement de mois lors d'un ajout de jours est cohérent.
 


|    Changer de couleur
 
 Il est enfin possible d'extraire une partie d'une date/heure/horodatage.
 
 avec EXTRCT ou %SUBDT( en V5R10) :
 
 
     C                   EXTRCT    DAT2:*M       mois
 
      Le facteur 2 contient la variable date/heure suivi du code,
       indiquant la partie à extraire (séparé par :)
       (ici mois contient le n° de mois de DAT2)
 
      /free
       // exemple V5R10 :
       // la variable résultat doit être numérique 2 OU 4 chiffres.
       //                      (on retourne toujours l'année sur 4)
        mois = %SUBDT(DAT2 : *M) ;
 
       // fin de mois du 26 Mars = 26 Avril - 26 jours
        findemois = DAT1 + %MONTH(1) - %DAYS( %SUBDT(DAT1+%MONTH(1)):*DAYS))
 
      /end-free


|    Changer de couleur
 
 Quelques nouveautés version 7.2 en ce qui concerne les dates
 
  la précision d'un TimeSTamp peut être indiqué lors de la déclaration
   entre 0 et 12 (en version précédente, c'était forcément 6)
 
     DCL-S tstp timestamp(12);
 
   la fonction %SECONDS, utilisée dans un calcul admet un argument
    avec décimales : %SECONDS(1,5)
 
 
   la fonction %DIFF admet un 4ème argument indiquant les millisecondes
 
     %DIFF(ts1:ts2:*SECONDS:5)
 
   la fonction %SUBDT admet aussi la précision à extraire
 
     %SUBDT(Z'2014-07-21-15.20.26.123456789012':*SECONDS:10:8)
 
      -> extrait 26,12345678
 





©AF400