Mémo Dates 

 

Comparatifs des ordres de manipulation de dates

Fonctions liées aux dates

SQL Retourne Exemple SQL RPG Exemple RPG
DATE(x)
X doit être une chaîne au format SQL ou *ISO

 Aussi sous QUERY !
CAST décimal en une date DATE(
substr(digits(dat8), 7, 2)
 concat '/' concat
substr(digits(dat8), 5, 2)
 concat '/' concat
substr(digits(dat8), 3, 2) )
%DATE(x:*FMTs)


s = séparateur
& = l'espace
0 pas de séparateur

wdate =%DATE(
datchar:*ISO0) ;

//*ISO = YYYYmmDD,
//0 = sans séparateur


CAST une date en décimal   %dec(d) datnum =%DEC(date) ;
datjul = %dec(date:*JUL);
DAY(D)
DAYOFMONTH(D)
 la partie jour de D DAY(DATCDE) %SUBDT(d:*D) jj = %SUBDT(
 DATCDE:*D) ;
MONTH(D) la partie mois de D 

MONTH(current date)

%SUBDT(d:*M) mm = %SUBDT(
%date():*M) ;
YEAR(D)  la partie année  de D  YEAR(current date -                    DATCDE) %SUBDT(d:*Y) mm = %SUBDT(
DATCE:*M) ;
DAYOFYEAR(D) le n° de jour dans l'année (julien) DAYOFYEAR(datdep)
DAYOFWEEK(D) le N° de jour dans la semaine
(1 = Dimanche, 2=Lundi, ...)
DAYOFWEEK(ENTRELE)
DAYOFWEEK_ISO(D) retourne le N° de jour dans la semaine
(1 = Lundi)
DAYOFWEEK_ISO(ENTRELE)
DAYNAME(D) retourne le nom du jour de D (Lundi, Mardi, ...)
DAYNAME(datcde)
MONTHNAME(D) * retourne le nom du mois de D (Janvier, Février, ...)
MONTHNAME(datcde)
EXTRACT(day from D) Extrait la partie jour de D (aussi Month et Year)
EXTRACT(MONTH from datcde)
cf %SUBDT( )
DAYS(D) retourne le nbr de jours depuis 0001-01-01 DAYS(datcde)- DAYS(datliv)

jours = %DIFF(datcde :
D'0001-01-01 : *DAYS) + 1 ;

QUARTER(D) retourne le n° du trimestre(1-4) QUARTER(DATEFIN)
WEEK(D) retourne le n° de semaine
(Attention le 1er Janvier est semaine 1)
WHERE
WEEK(DATLIV)= WEEK(DATCDE)
WEEK_ISO(D) retourne le n° de semaine
(la semaine 1 est celle qui possède un JEUDI dans l'année.)
WHERE
WEEK_ISO(DATLIV)= 1
CURDATE() retourne la date en cours, comme CURRENT DATE WHERE
DATLIV = CURDATE()-1 DAY
%DATE() if datcde > %date();
CURTIME() retourne l'heure en cours, comme CURRENT TIME   %TIME()
NOW() retourne le timestamp en cours   %TIMESTP() avec seulement 3 chiffres après la virgule
JULIAN_DAY(D) retourne le nbr de jours qui sépare une date du 1er Janv. 4712 av JC.
JULIAN_DAY(datcde)
ADD_MONTHS(D, nbr) ajoute un nbr de mois à une date ,
si la date est au dernier jour du mois, la date calculée est aussi au dernier jour du mois
ADD_MONTHS('2006-04-30' , 1)
= 2006-05-31
LAST_DAY(D) retourne la fin de mois d'une date
LAST_DAY('2006-04-20') 
= ' 2006-04-30'
NEXT_DAY(d, 'day' ) retourne la prochaine date ayant le jour demandé
NEXT_DAY('2006-12-31' , 'DIM') 
= ' 2007-01-07'
MONTHS_BETWWEN
(d1, d2)
retourne l'écart en mois (avec des décimales) entre 2 dates
months_between('25/09/08' , '31/08/08')
= 0,806451612903225
Test de la validité d'une zone caractère ou numérique contenant une date. TEST(DE) TEST(de) datchar;
if %error ;
  .....
endif;

Fonctions liées aux heures

Fonction(x) Retourne  Exemple RPG
TIME(T) une heure TIME(
substr(digits(h6), 1, 2)
 concat ':' concat
substr(digits(h6), 3, 2)
 concat ':' concat
substr(digits(h6), 5, 2) )
%TIME()
HOUR(T)
retourne la partie heure de T HOUR(Pointage) %SUBDT(T:*H)
MINUTE(D) retourne la partie minute de T

 

%SUBDT(T:*Mn)
SECOND(T) Retourne la partie secondes de T   %SUBDT(T:*S)
EXTRACT(hour from t)  la partie heure de T (aussi MINUTE et SECOND)
EXTRACT(SECOND from pointage)

Fonctions liées aux Timestamp

Fonction(x) Retourne  Exemple RPG
TIMESTAMP(T) un timestamp (date - heure - microsecondes) TIMESTAMP('
1999-10-06.15.45.00.000001 ')
%TIMESTP()
TIMESTAMP
(D T)
un timestamp (microsecondes à 0) TIMESTAMP(datcde heure)
TIMESTAMP_ISO(x) 

un timestamp à partier de x
 Si x est une date, l'heure est à 00:00:00
 Si x est une heure, la date est à aujourd'hui.
TIMESTAMP_ISO(heure_pointage)
TIMESTAMPDIFF
(c 'DIFFERENCE')
C indique l'unité de mesure de l'écart que vous souhaitez obtenir
1 = fractions de s. 16 = jours
2 = secondes 32 = semaines
4 = minutes 64 = mois
8 = heures 128 = trimestres
  256 = Année

'DIFFERENCE' est la représentation caractères [ CHAR(22) ]
d'un écart entre deux timestamp.

TIMLESTAMPDIFF(32 ,
CAST(
CURRENT_TIMESTAMP
- CAST(DATLIV AS TIMESTAMP)
AS CHAR(22) )
)

indique l'écart en semaines
entre DATLIV et aujourd'hui
MIDNIGHT_SECONDS retourne le nbr de secondes qui sépare un timestamp de minuit
MIDNIGHT_SECONDS(pointage)
TIMESTAMP_FORMAT
(c, 'un-format)

Transforme une chaine c en timestamp suivant le format

format ouvant contenir :

  •  -  .  /  ,  '  :  ; et (espace)
  • DD (jours) MM (mois) YY (années sur 2) YYYY (sur 4)
  • RR année ajustée (00 à 49>2000, 50 à 99>1900)
  • HH24 l'heure (format 24h)
  • SS (secondes)
  • NNNNNN (micro-secondes)
TIMESTAMP_FORMAT('99/02/05' , 
'RR/MM/DD')
=1999-02-05-00.00.00.000000

le format YY/MM/DD aurait donné 2099
GENERATE-UNIQUE() genère une valeur unique de type CHAR(13) basée sur le timestamp en cours.
insert GENERATE_UNIQUE() ....


Quelques fonctions utiles EN RPG

 * calcul de la fin de mois
* astuce : pour le 17 Janvier, se positionner au 17 Février et enlever 17 jours

Dfindemois PI          D   
D Datein                      D   CONST

P Findemois       B               EXPORT
D                 PI          D
D Datein                      D   CONST

D Wdate S D

/free
wdate = Datein + %months(1);
wdate = wdate - %days( %subdt(wdate : *DAYS) ); 
return wdate;
/end-free
P Findemois E
 * calcul du N° de semaine
* astuce : on part d'un dimanche connu (6 Janvier 80)
* on divise l'écart en jours, le reste EST le N° de jour dans la semaine
* sauf dimanche (= 0) ou on retourne 7.

Djoursemaine PI         1 0   
D Datein                      D   CONST

P joursemaine     B               EXPORT
D                 PI         1 0 
D Datein                      D   CONST

D Wdate S D

/free
nbdejours = %DIFF(wdate : D'1980-01-06' : *DAYS) ;
reste = %REM(nbdejours : 7);
if reste < 1; 
return reste + 7;
else;
return reste;
endif;
/end-free
P joursemaine     E
 dsemaine          PR             2P 0
 d datein        D const

 psemaine     B                   export
 d                 pi             2P 0
 d datein                          D   const
 d janvier4        S               D   INZ(D'0001-01-04')         
 d Lundi           S               D                              
  /free                                                            
    // calcul du 4 janvier de l'année traitée                     
    janvier4 += %years(%SUBDT(DateIn : *Y) -1 );   
                          
    // calcul du Lundi précédent le 4 janvier                     
    Lundi = janvier4 - %DAYS(dayofweek(janvier4)-1) ;                                                                                
    // si date recue < au lundi ==> premier lundi,année précédente 
    if DateIn < Lundi;                                            
       ANjanvier4 -= 1;                                           
       Lundi = janvier4 - %DAYS(dayofweek(janvier4)+1);           
    endif;                                                        
    // nombre de semaine entières                                  
   return %DIV( %DIFF(DateIn:Lundi:*DAYS) : 7) +1;                
  /end-free 
Psemaine E                                                      
 dsemaineSQL       PR             2P 0
 d datein        D const

 psemaineSQL     B                   export
 d                 pi             2P 0
 d datein                          D   const d numsemaine s 2P 0
  /free                                                           
   
EXEC SQL values WEEK_ISO(:datein) into :num_semaine;                           
   return numsemaine;                
  /end-free   
PsemaineSQL E                                                    



Quelques astuces SQL

les commandes passées cette année Select * from commandes where YEAR(datcmd) = YEAR(current date)
les commandes passées ce trimestre Select * from commandes where YEAR(datcmd) = YEAR(current date) AND QUARTER(datcmd) = QUARTER(current date)
les commandes de l'année écoulée Select * from commandes where datcmd between
current date - 1 year + 1 day AND current date



Dates ET DSPF

Les mots-clé DATFMT [éventuellement DATSEP] sont admis sur les écrans (depuis la V4R2)


A LA SAISIE :

- les séparateurs ne sont PAS obligatoires !
- les zéros [à gauche] non plus
     pour le 1er Février 2006 on admet avec DATFMT(*DMY) :  01/02/06
                                                010206
                                                10206
                                                1/2/06

-   on admet aussi DATFMT(*JOB) qui affiche (et accepte) une date au
    format du job en cours(*DMY en France), mais transmet TOUJOURS en *ISO

Enfin, un nouveau mot-clé MAPVAL est implémenté afin d'établir des conversions
     entre valeur affichée et valeur transmise au pgm.

     MAPVAL( (valeur-pgm1 valeur-écran1)
             (valeur-pgm2 valeur-écran2) ...)  jusqu'à 100 correspondances

     avec comme valeurs particulières :

          *BLANK on affiche que des blancs           *CUR   valeur en cours (date en cours ou heure en cours)

exemple :        MAPVAL(('01/01/40' *BLANK))

                  si le pgm contient 01/01/40 j'affiche des blancs
             ET   si l'utilisateur entre des blancs j'envoi 01/01/40