Aller au contenu

%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).