Y-a-t-il un moyen de transformer un réel (qui represente un nombre de jours, par exemple 0,0791435185185185) dans un interval temporel, format HH:MM:SS ?

Je ne suis pas le seul à me poser cette question sans avoir trouvé de réponse.

Pourquoi cette question? Parce que si on veut l'interval entre 2 dates en sql on fait (par exemple):
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
select
to_date('2008-01-22 15:28:08','YYYY-MM-DD HH24:MI:SS') - 
to_date('2008-01-22 13:34:10','YYYY-MM-DD HH24:MI:SS')
from dual
0,0791435185185185
et ça donne exactement le réel mentionné plus haut, ç'est à dire le nombre de jours (avec virgule).

Alors je me suis mis comme défi ce problème, ç'est à dire d'avoir le résultat dans le format HH:MM:SS, et comme j'y ai passé la matinée, autant en faire profiter tout le monde. Voilà donc:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
-- calcule (date1 - date2); format des dates à l'entrée = &3
-- (par exemple &3 = YYYY-MM-DD HH24:MI:SS)
select
TRUNC(24 *             (to_date('&1','&3') - to_date('&2','&3')))||':'||
TRUNC(60 * (24 *       (to_date('&1','&3') - to_date('&2','&3')) -
TRUNC(24 *             (to_date('&1','&3') - to_date('&2','&3')))))||':'||
ROUND(60 * (60 * (24 * (to_date('&1','&3') - to_date('&2','&3')) -
TRUNC(24 *             (to_date('&1','&3') - to_date('&2','&3')))) -
TRUNC(60 * (24 *       (to_date('&1','&3') - to_date('&2','&3')) -
TRUNC(24 *             (to_date('&1','&3') - to_date('&2','&3')))))))
as "HH:MM:SS" from dual
;
Pour utiliser ça au mieux, on peut en faire un fichier "datediff.sql" et si on est sous UNIX faire un autre fichier "datediff.sh" comme suit:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
conexion=$1 ; shift
sql_file=$1 ; shift
date1=$1 ; date2=$2 ; format=$3
#echo "Connexion: $conexion"
  sqlplus -s $conexion << EOF
  set pagesize 0
  set newpage 0
  set heading off
  set verify off
  set feedback off
  @$sql_file "$date1" "$date2" "$format";
EOF
Sous UNIX on peut maintenant faire:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
> CONNEXION="USER@NOM_BASE/PASSWORD"   # (à remplacer fonction de votre site)
> export DIROUTILS="/home/user/outils"   # (à remplacer fonction de votre site)
> alias datediff="$DIROUTILS/datediff.sh $CONNEXION $DIROUTILS/datediff.sql"
>
> d1="2008-01-22 15:28:08"
> d2="2008-01-22 13:34:10"
> f="YYYY-MM-DD HH24:MI:SS"
>
> datediff "$d1" "$d2" "$f"          # (guillimets obligatoires!)
1:53:58
ou
> datediff "2008-01-22 15:28:08" "2008-01-22 13:34:10" "YYYY-MM-DD HH24:MI:SS"
1:53:58
Tout est testé (Oracle9i) et vérifié, ça marche meme si les dates sont inversées ou si on met 2009 à la place de 2008 pour une des dates. Essayez pour voir ce que ça donne! Ca tient meme compte du fait que 2008 est bisextil (février 2008 a 29 jours)(par l'intermède de l'opérateur "-" de sql).

Et alors que j'avais entendu quelcun dire qu'en UNIX il n'y a pas de fonctions pour les dates!!!!(). Sans plaisenter, en fait tout ce qu'on peut faire sous sql on pourra faire sous UNIX, pourvu qu'on a sqlplus sur la station.
a+

sinon, y-a-t-il qq qui connait le format sql pour le millisecondes ? (du genre "YYYY-MM-DD HH24:MI:SS.MS") ?