Précédent   Forum des professionnels en informatique > Bases de données > Oracle > SQL
SQL Forum d'entraide sur le SQL pour Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 05/02/2008, 16h00   #1
Membre du Club
 
Inscription : janvier 2007
Messages : 67
Détails du profil
Informations forums :
Inscription : janvier 2007
Messages : 67
Points : 43
Points : 43
Par défaut interval entre des dates

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 :
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 :
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 :
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 :
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") ?
vpovpo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/02/2008, 16h45   #2
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 927
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Finance

Informations forums :
Inscription : décembre 2005
Messages : 2 927
Points : 4 549
Points : 4 549
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
SQL> SELECT (date '2009-01-01' - sysdate) day (4) TO second FROM dual
 
(DATE'2009-01-01'-SYSDATE)DAY(4)TOSECOND          
--------------------------------------------------
+330 07:14:57.000000                              
 
 
1 row selected.
SQL> SELECT (date '2009-01-01' - current_timestamp) day (4) TO second FROM dual
 
(DATE'2009-01-01'-CURRENT_TIMESTAMP)DAY(4)TOSECOND
--------------------------------------------------
+330 07:14:56.680602
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/02/2008, 16h48   #3
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 927
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Finance

Informations forums :
Inscription : décembre 2005
Messages : 2 927
Points : 4 549
Points : 4 549
Code :
1
2
3
4
5
SQL> SELECT numtodsinterval(.0791435185185185, 'DAY') FROM dual
 
NUMTODSINTERVAL(.0791435185185185,'DAY')          
--------------------------------------------------
+00 01:53:57.999999
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/02/2008, 16h58   #4
Expert Confirmé Sénior


 
Avatar de laurentschneider
 
Homme Laurent Schneider
Administrateur de base de données
Inscription : décembre 2005
Messages : 2 927
Détails du profil
Informations personnelles :
Nom : Homme Laurent Schneider
Localisation : Suisse

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : Finance

Informations forums :
Inscription : décembre 2005
Messages : 2 927
Points : 4 549
Points : 4 549
bien sûr dans unix une ligne suffit
Code :
1
2
3
echo .0791435185185185|
awk '{h=$1*24;m=h%1*60;s=m%1*60+.5;printf("%0d:%02d:%02d\n",h,m,s)}'
1:53:58
__________________
Mon blog : laurentschneider.com
Mon livre : Advanced Oracle SQL Programming
laurentschneider est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 05/02/2008, 19h38   #5
Expert Confirmé
 
Avatar de 7gyY9w1ZY6ySRgPeaefZ
 
Homme
dba
Inscription : juillet 2007
Messages : 2 523
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : Canada

Informations professionnelles :
Activité : dba

Informations forums :
Inscription : juillet 2007
Messages : 2 523
Points : 3 972
Points : 3 972
Citation:
Envoyé par vpovpo Voir le message
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"
Pourquoi ne pas utiliser une fonction stockée en base ?
C'est l'usine à gaz ton truc.
7gyY9w1ZY6ySRgPeaefZ est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 07/02/2008, 14h26   #6
Membre du Club
 
Inscription : janvier 2007
Messages : 67
Détails du profil
Informations forums :
Inscription : janvier 2007
Messages : 67
Points : 43
Points : 43
CA OUI, JE PRENDS - pour les 3 solutions offertes par laurentschneider.

OBS.: awk il faut bien le connaitre, ç'est vrai qu'on peut faire plein de choses avec.

a+
vpovpo est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 18h35.


 
 
 
 
Partenaires

Hébergement Web