%HOURS
Durée en heures
Représente un nombre d'heures, à ajouter à une heure ou à un horodatage, ou à en retrancher.
Syntaxe
heure + %HOURS(nombre)
horodatage - %HOURS(nombre)
nombre- Le nombre d'heures : une constante, une zone numérique ou une expression. Un nombre négatif fait reculer.
- Résultat
- Une durée, à combiner avec une heure ou un horodatage par
+ou-. Sur un horodatage, la date change si besoin ; sur une heure, le résultat reboucle sur 24 heures. Le compilateur refuse la durée avec une date (RNF7584).
À quoi ça sert
Un délai de traitement de 48 heures, une fin de poste huit heures après la prise de service, une expiration à J+1 à la même heure : %HOURS exprime ces calculs sans conversion en minutes ou en secondes.
Exemple 1 : Fin de poste et délai de 48 h
**free
// %HOURS : ajouter ou retirer des heures a une heure ou a un horodatage.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s prise time inz(t'08.00.00');
dcl-s depot timestamp inz(z'2026-09-30-16.30.00.000000');
dcl-s sla int(10) inz(48);
dcl-s livraison timestamp;
// Fin de journee de travail : 8 h apres la prise de poste.
snd-msg 'Fin de poste : [' + %char(prise + %hours(8) : *hms) + ']';
// Delai de traitement de 48 h sur un horodatage : la date change.
livraison = depot + %hours(sla);
snd-msg 'Depot : [' + %char(depot) + ']';
snd-msg 'Echeance 48 h : [' + %char(livraison) + ']';
// Retrancher : 24 h avant le depot.
snd-msg 'Depot - 24 h : [' + %char(depot - %hours(24)) + ']';
// L'ecart retrouve le delai.
snd-msg 'Controle (heures) : [' + %char(%diff(livraison : depot : *hours)) + ']';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Fin de poste : [16:00:00]
Depot : [2026-09-30-16.30.00.000000]
Echeance 48 h : [2026-10-02-16.30.00.000000]
Depot - 24 h : [2026-09-29-16.30.00.000000]
Controle (heures) : [48]
8 h + 8 heures donne 16:00. Sur un horodatage, 48 heures après le 30 septembre à 16:30 : le 2 octobre à 16:30, la date a changé. Le contrôle avec %DIFF retrouve bien 48 heures.
Exemple 2 : Le rebouclage de minuit
**free
// %HOURS : sur une heure seule, le calcul repasse par minuit sans prevenir.
ctl-opt dftactgrp(*no) actgrp(*new);
dcl-s equipe time inz(t'22.00.00');
dcl-s depart timestamp inz(z'2026-09-30-22.00.00.000000');
dcl-s ecart int(10);
// 22 h + 5 h : la zone time donne 03.00.00, sans le jour.
snd-msg 'Heure 22 h + 5 h : [' + %char(equipe + %hours(5) : *hms) + ']';
// L'horodatage, lui, garde la trace du changement de jour.
snd-msg 'Stamp 22 h + 5 h : [' + %char(depart + %hours(5)) + ']';
// Consequence : la difference sur des heures devient negative.
ecart = %diff(equipe + %hours(5) : equipe : *hours);
snd-msg 'Ecart sur heures : [' + %char(ecart) + ']';
ecart = %diff(depart + %hours(5) : depart : *hours);
snd-msg 'Ecart sur stamps : [' + %char(ecart) + ']';
// Plus de 24 h : le total est replie sur 24 h (22 + 30 = 52 h, soit 4 h).
snd-msg '22 h + 30 h : [' + %char(equipe + %hours(30) : *hms) + ']';
*inlr = *on;
Résultat réel, compilé et exécuté sur IBM i 7.5 :
Heure 22 h + 5 h : [03:00:00]
Stamp 22 h + 5 h : [2026-10-01-03.00.00.000000]
Ecart sur heures : [-19]
Ecart sur stamps : [5]
22 h + 30 h : [04:00:00]
22 h + 5 h sur une zone heure donne 03:00:00 sans la date, et l'écart avec l'heure de départ devient -19. Sur un horodatage, le résultat est le lendemain à 3 h et l'écart vaut bien 5. 22 h + 30 h donne 4 h : 52 heures repliées sur 24.
Le piège
Sur une zone de type heure, le calcul reboucle en silence. 22:00 + 5 heures donne 03:00 : la date n'existe pas, donc rien ne signale le changement de jour. Une durée calculée ensuite sur ces heures est fausse (-19 au lieu de 5). Dès qu'un calcul peut dépasser minuit, travailler sur des horodatages.
Et date + %HOURS(24) ne compile pas (RNF7584) : pour avancer d'un jour, on utilise %DAYS(1).