Aller au contenu

%DATE

Créer une date

Fabrique une valeur de type date à partir d'un texte, d'un nombre ou d'un horodatage, ou renvoie la date du jour quand on ne donne rien.

Syntaxe

%DATE()
%DATE(expression)
%DATE(expression : format)
expression
Ce qu'il faut convertir : un texte ('30.09.2026'), un nombre (20261231) ou un horodatage. Sans expression, on obtient la date du jour.
format
Comment le texte ou le nombre est écrit : *ISO, *EUR, *USA, *DMY, *ISO0… Les séparateurs font partie du format. Sans format, un texte comme '2026-09-30' est lu au format ISO.
Résultat
Une valeur de type date, utilisable dans les comparaisons, les calculs avec %DAYS, %MONTHS, %YEARS et dans %DIFF. Si le texte ou le nombre ne représente pas une date valide, l'erreur RNQ0112 est signalée (statut 112 dans monitor).

À quoi ça sert

Les dates arrivent presque toujours sous forme de texte (un fichier CSV, une zone d'écran) ou de nombre (AAAAMMJJ dans les vieux fichiers). Tant qu'on garde du texte ou du numérique, on ne peut ni ajouter 30 jours ni calculer un écart. %DATE fait la conversion et, au passage, contrôle que la date existe.

C'est donc aussi un outil de validation : une saisie qui passe dans %DATE sans erreur est une vraie date, jours par mois et années bissextiles compris.

Exemple 1 : Texte, nombre, horodatage

**free
// %DATE : fabriquer une date a partir d'un texte, d'un nombre ou d'un horodatage.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-s facture   date;
dcl-s livraison date;
dcl-s echeance  date;
dcl-s texte     varchar(10);
dcl-s numerique packed(8:0) inz(20261231);
dcl-s stamp     timestamp   inz(z'2026-09-30-14.05.30.000000');

// Le format indique comment le texte est ecrit (separateurs compris).
texte = '30.09.2026';
facture = %date(texte : *eur);
snd-msg 'Texte *EUR   : [' + %char(facture : *iso) + ']';

// Un nombre AAAAMMJJ (pas de separateur possible dans un nombre).
livraison = %date(numerique : *iso);
snd-msg 'Nombre *ISO  : [' + %char(livraison : *iso) + ']';

// Extraire la date d'un horodatage.
echeance = %date(stamp);
snd-msg 'Horodatage   : [' + %char(echeance : *iso) + ']';

// Une date se calcule avec des durees.
echeance = facture + %days(30);
snd-msg 'Facture + 30 : [' + %char(echeance : *eur) + ']';

*inlr = *on;

Résultat réel, compilé et exécuté sur IBM i 7.5 :

Texte *EUR   : [2026-09-30]
Nombre *ISO  : [2026-12-31]
Horodatage   : [2026-09-30]
Facture + 30 : [30.10.2026]

Le premier appel lit un texte écrit au format *EUR (jour.mois.année, avec des points). Le deuxième lit le nombre 20261231 au format *ISO. Le troisième extrait la date d'un horodatage. Enfin la date obtenue se calcule directement : facture plus 30 jours.

Exemple 2 : Dates invalides interceptées

**free
// %DATE : dates invalides et saisies mal formees, interceptees par monitor.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-s jour  date;
dcl-s saisie varchar(10);

// Annee bissextile : 2028 a un 29 fevrier, pas 2026.
saisie = '2028-02-29';
monitor;
  jour = %date(saisie : *iso);
  snd-msg saisie + ' : valide, ' + %char(jour : *eur);
on-error;
  snd-msg saisie + ' : refusee, statut ' + %char(%status);
endmon;

saisie = '2026-02-29';
monitor;
  jour = %date(saisie : *iso);
  snd-msg saisie + ' : valide, ' + %char(jour : *eur);
on-error;
  snd-msg saisie + ' : refusee, statut ' + %char(%status);
endmon;

// Mauvais separateur : *EUR attend des points, pas des barres.
saisie = '30/09/2026';
monitor;
  jour = %date(saisie : *eur);
  snd-msg saisie + ' : valide, ' + %char(jour : *iso);
on-error;
  snd-msg saisie + ' : refusee, statut ' + %char(%status);
endmon;

// Texte vide : refuse aussi.
saisie = '';
monitor;
  jour = %date(saisie : *iso);
  snd-msg 'vide : valide';
on-error;
  snd-msg 'texte vide : refuse, statut ' + %char(%status);
endmon;

*inlr = *on;

Résultat réel, compilé et exécuté sur IBM i 7.5 :

2028-02-29 : valide, 29.02.2028
2026-02-29 : refusee, statut 112
30/09/2026 : refusee, statut 112
texte vide : refuse, statut 112

Avec un bloc monitor, on récupère l'erreur au lieu d'arrêter le programme. Le 29 février 2028 existe, pas celui de 2026. Le texte 30/09/2026 est refusé avec *EUR, qui attend des points. Un texte vide est refusé aussi. Dans tous les cas le statut est 112.

Exemple 3 : Sans monitor : l'erreur RNQ0112

**free
// %DATE sans programme de controle : une date invalide arrete le programme.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-s jour   date;
dcl-s saisie varchar(10) inz('2026-02-30');

snd-msg 'Avant la conversion de ' + saisie;
jour = %date(saisie : *iso);
snd-msg 'Apres la conversion';

*inlr = *on;

Résultat réel, compilé et exécuté sur IBM i 7.5 :

Avant la conversion de 2026-02-30
Erreur : RNQ0112 - (C G D F) Une valeur de type date, heure ou horodatage est incorrecte.

Sans monitor, le programme s'arrête sur la ligne de la conversion : le message qui suit ne s'affiche jamais, et l'utilisateur voit l'erreur RNQ0112.

Le piège

Le format doit correspondre exactement au texte, séparateurs compris. %DATE('30/09/2026' : *eur) échoue avec RNQ0112 : le format *EUR attend 30.09.2026. Le texte vide et le nombre 0 échouent de la même façon, ils ne donnent pas une « date à zéro ».

Si la valeur vient d'un utilisateur ou d'un fichier externe, toujours entourer la conversion d'un monitor. Pour le 29 février, le compilateur ne dit rien : c'est à l'exécution que 2026-02-29 est refusée et 2028-02-29 acceptée.