Aller au contenu

%TIME

Créer une heure

Fabrique une valeur de type heure à partir d'un texte, d'un nombre ou d'un horodatage, ou renvoie l'heure courante quand on ne donne rien.

Syntaxe

%TIME()
%TIME(expression)
%TIME(expression : format)
expression
Un texte ('08.30.00'), un nombre hhmmss (83015 pour 08:30:15) ou un horodatage, dont on ne garde que l'heure. Sans expression, on obtient l'heure courante.
format
Le format du texte ou du nombre : *ISO (points), *HMS (deux-points), *EUR, *JIS, *USA… Les séparateurs en font partie.
Résultat
Une valeur de type heure, à la seconde près. Une valeur incorrecte provoque l'erreur RNQ0112 (statut 112 dans monitor).

À quoi ça sert

Une heure lue dans un fichier ou saisie à l'écran est du texte ou un nombre. Pour calculer une durée, comparer deux horaires ou ajouter 45 minutes, il faut une vraie valeur de type heure : %TIME la construit et vérifie qu'elle est valide.

Exemple 1 : Texte, nombre et horodatage

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

dcl-s ouverture time;
dcl-s fermeture time;
dcl-s pointage  time;
dcl-s texte     varchar(8);
dcl-s badge     packed(6:0) inz(83015);
dcl-s stamp     timestamp   inz(z'2026-09-30-17.45.10.250000');

// *ISO ecrit les heures avec des points, *HMS avec des deux-points.
texte = '08.30.00';
ouverture = %time(texte : *iso);
snd-msg 'Texte *ISO : [' + %char(ouverture : *hms) + ']';

texte = '18:15:00';
fermeture = %time(texte : *hms);
snd-msg 'Texte *HMS : [' + %char(fermeture : *hms) + ']';

// Un nombre hhmmss : 83015 = 08:30:15 (le zero de tete n'est pas saisi).
pointage = %time(badge : *hms);
snd-msg 'Nombre     : [' + %char(pointage : *hms) + ']';

// Extraire l'heure d'un horodatage : les fractions de seconde disparaissent.
pointage = %time(stamp);
snd-msg 'Horodatage : [' + %char(pointage : *hms) + ']';

// Presentation americaine.
snd-msg 'Format USA : [' + %char(fermeture : *usa) + ']';

*inlr = *on;

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

Texte *ISO : [08:30:00]
Texte *HMS : [18:15:00]
Nombre     : [08:30:15]
Horodatage : [17:45:10]
Format USA : [06:15 PM]

Le format dit comment lire la valeur : *ISO pour 08.30.00 (points), *HMS pour 18:15:00 (deux-points). Le nombre 83015 devient 08:30:15 : le zéro de tête n'est pas saisi. Depuis un horodatage, les fractions de seconde disparaissent.

Exemple 2 : Séparateurs et valeurs refusées

**free
// %TIME : separateurs, heure invalide et minuit.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-s heure  time;
dcl-s saisie varchar(8);

// Les deux-points ne conviennent pas au format *ISO.
saisie = '14:05:30';
monitor;
  heure = %time(saisie : *iso);
  snd-msg saisie + ' en *ISO : acceptee';
on-error;
  snd-msg saisie + ' en *ISO : refusee, statut ' + %char(%status);
endmon;

// Avec *HMS, ce sont les deux-points qui sont attendus.
monitor;
  heure = %time(saisie : *hms);
  snd-msg saisie + ' en *HMS : acceptee';
on-error;
  snd-msg saisie + ' en *HMS : refusee, statut ' + %char(%status);
endmon;

// 25 heures n'existent pas.
saisie = '25.00.00';
monitor;
  heure = %time(saisie : *iso);
  snd-msg saisie + ' : acceptee';
on-error;
  snd-msg saisie + ' : refusee, statut ' + %char(%status);
endmon;

// 24.00.00 est acceptee : c'est minuit de fin de journee.
saisie = '24.00.00';
monitor;
  heure = %time(saisie : *iso);
  snd-msg saisie + ' : acceptee, lue comme ' + %char(heure);
on-error;
  snd-msg saisie + ' : refusee, statut ' + %char(%status);
endmon;

// Format americain : 12:00 AM est lu comme 24.00.00, pas comme 00.00.00.
saisie = '12:00 AM';
monitor;
  heure = %time(saisie : *usa);
  snd-msg saisie + ' en *USA : lue comme ' + %char(heure);
on-error;
  snd-msg saisie + ' en *USA : refusee, statut ' + %char(%status);
endmon;

*inlr = *on;

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

14:05:30 en *ISO : refusee, statut 112
14:05:30 en *HMS : acceptee
25.00.00 : refusee, statut 112
24.00.00 : acceptee, lue comme 24.00.00
12:00 AM en *USA : lue comme 24.00.00

Les deux-points sont refusés par *ISO et acceptés par *HMS. 25 heures n'existent pas (statut 112). Deux surprises : 24.00.00 est acceptée, et en format *USA, 12:00 AM est lue comme 24.00.00 et non comme 00.00.00.

Exemple 3 : Minuit et horloge

**free
// %TIME : une heure ne connait pas la date, elle repasse a zero apres minuit.
ctl-opt dftactgrp(*no) actgrp(*new);

dcl-s debut time inz(t'22.00.00');
dcl-s fin   time inz(t'06.00.00');
dcl-s duree int(10);
dcl-s maintenant time;

// Equipe de nuit de 22 h a 6 h : la difference brute est negative.
duree = %diff(fin : debut : *hours);
snd-msg 'Nuit, difference brute : [' + %char(duree) + '] h';

// Il faut ajouter 24 h pour retrouver la duree reelle.
duree = %diff(fin : debut : *minutes) + 24 * 60;
snd-msg 'Nuit, corrigee : [' + %char(duree) + '] minutes = ' + %char(%div(duree : 60)) + ' h';

// Une heure + une duree repasse par minuit sans erreur.
fin = t'23.59.59' + %seconds(1);
snd-msg '23:59:59 + 1 s : [' + %char(fin) + ']';

// %TIME() sans parametre lit l'horloge : 8 caracteres, au format de la zone.
maintenant = %time();
snd-msg 'Longueur de l''heure courante : ' + %char(%len(%char(maintenant)));

*inlr = *on;

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

Nuit, difference brute : [-16] h
Nuit, corrigee : [480] minutes = 8 h
23:59:59 + 1 s : [00.00.00]
Longueur de l'heure courante : 8

Une zone heure n'a pas de date : une équipe de nuit de 22 h à 6 h donne -16 heures avec %DIFF. Il faut ajouter 24 heures soi-même. Ajouter une seconde à 23:59:59 donne 00:00:00 sans erreur. %TIME() lit l'horloge (ici on n'affiche que sa longueur, 8 caractères, pour que la sortie ne change pas d'un jour à l'autre).

Le piège

Une heure ne connaît pas la date. Elle reboucle sur 24 heures : 23:59:59 plus une seconde donne 00:00:00, et la différence entre 6 h et 22 h est négative (-16 heures). Pour mesurer une durée qui peut passer minuit, utiliser un horodatage, ou ajouter 24 heures quand le résultat est négatif.

Autre piège : le format impose les séparateurs. 14:05:30 est refusée en *ISO (points) mais acceptée en *HMS (deux-points).