- Oracle : différence entre 2 dates
Autant il est facile sous Oracle de calculer la différence entre 2 dates en nombre de jours en faisant une simple soustraction :
-- nombre de jours entre la date du jour et le 01/01/2012 select trunc(sysdate) - to_date('01/01/2012', 'dd/mm/yyyy') NB_JOURS from dual;
- Durée en Heure/minute seconde à partir de 2 dates
Autant on se retrouve confronté au néant quand on doit calculer une durée en heure/minute/seconde, ce qui peut être particulièrement pratique notamment lorsqu’on stocke, par exemple, des dates de début et des dates de fin de traitement.
Après quelques recherches infructueuses sur Internet, voici ma propre requête :
-- Calcul de durée en heure/minute/seconde With REQ_NB_SECOND as ( select trunc(sysdate) DATE_DEB, sysdate DATE_FIN, ((sysdate - trunc(sysdate))*24*3600) NB_SECONDES from dual ) select DATE_DEB, DATE_FIN, case when (DATE_DEB is NULL OR DATE_FIN is NULL) then NULL else to_char( to_date( to_char(Trunc(NB_SECONDES/3600), '00') || ':' || to_char(Trunc(NB_SECONDES/60) - Trunc(NB_SECONDES/3600)*60, '00') || ':' || to_char(trunc(NB_SECONDES - (Trunc(NB_SECONDES/60)*60)), '00'), 'hh24:mi:ss'), 'hh:mi:ss') end DUREE from REQ_NB_SECOND
J’ai pris ici date fin = date du jour à l’heure actuelle (sysdate), date de début=date du jour à 0h00. On peut remplacer ces 2 champs par les noms de colonnes qui correspondent à la date de début et de fin et mettre à la place du dual le nom de la table appropriée…
- Utilisation de la requête dans Business Objects
J’ai utilisé un With surtout pour que la requête soit plus claire (utilisation du NB_SECONDES dans la 2ème partie), mais cette requête étant destinée à être utilisée dans un objet Business Objects, j’ai du la réécrire pour avoir un format Select/From/Where, ce qui donne :
select trunc(sysdate) DATE_DEB, sysdate DATE_FIN, case when (trunc(sysdate) is NULL OR sysdate is NULL) then NULL else to_date( to_char(Trunc(((sysdate - trunc(sysdate))*24*3600)/3600), '00') || ':' || to_char(Trunc(((sysdate - trunc(sysdate))*24*3600)/60) - Trunc(((sysdate - trunc(sysdate))*24*3600)/3600)*60, '00') || ':' || to_char(trunc(((sysdate - trunc(sysdate))*24*3600) - (Trunc(((sysdate - trunc(sysdate))*24*3600)/60)*60)), '00'), 'hh24:mi:ss') end DUREE from dual;
- Formatage dans Business Objects :
Dernière étape sur laquelle on peut encore rencontrer quelques soucis, dans Business Objects, on créer un indicateur BO de type date avec un format date/heure HH:MM:SS.
Bref, une requête bien compliquée pour un simple calcul de durée !
Voir aussi :
Transformer un Timestamp UNIX en date Oracle
TOAD : quelques raccourcis utiles et peu connus de l’éditeur SQL
[wysija_form id= »2″]
Bonjour,
Avec to_timestamp on peut faire mieux !!!
exemple: to_timestamp(date_fin) – to_timestamp(date_debut) = resultat en années mois jours heures minutes et secondes
;-)
Merci pour l’astuce.
Par contre pourquoi mettre :
» ‘hh:mi:ss’)
end
DUREE
from REQ_NB_SECOND »
et pas :
» ‘hh24:mi:ss’)
end
DUREE
from REQ_NB_SECOND » ?
Sans hh24 cela affiche 12 dans le cas de 0 heure !?
(Ps : dans mon cas to_timestamp ne fonctionne pas).
Oui en effet c’est plus clair de mettre le format hh24 pour les heures. J’ai oublié de le mettre dans le format final.
La fonction Oracle to_timestamp() fonctionne normalement même sur des formats dates.
ex :
select to_timestamp(sysdate) from dual;
Mais sur les bases sur lesquelles je travaille Date/heure/seconde sont tronquées.
Aujourd’hui, par exemple, ça me ramène :
=>
26/12/2013 00:00:00
Quel que soit le moment où je passe la requête.