IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

SQL Oracle Discussion :

calcul entre 2 dates


Sujet :

SQL Oracle

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 5
    Par défaut calcul entre 2 dates
    bonjour à tous,

    Nouveau dans ce club,je débute en pl/sql.

    Actuellement,je recherche la façon de calculer(par le biais d une fonction) le nombre de jours ouvrés entre non-ouvrés entre deux dates.
    nb :les jours ouvrés sont LMMJV et non-ouvrés SD et jours fériés.


    Pour le moment je n'en suis qu'a l'algorithme et je tourne en rond...
    Il est possible ,même sur,que je ne maîtrise par encore toutes les fonctions pl/sql(to-char...).

    merci de votre aide.

  2. #2
    Membre Expert Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Par défaut
    C'est plus ou moins possible mais tu vas vite être limité par la définition d'un jour ouvré.

    En effet, selon les pays, les entreprises, les accords, etc. il y a des jours ouvrés différents dans chaque structure. Par exemple le lundi de pentecôte il est ouvré ou pas ?

    Par contre pour l'identification des samedi et dimanche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select TO_CHAR(sysdate,'DAY') from DUAL

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 5
    Par défaut
    Merci pour ta réponse cela me donne une bonne piste .

    Pour les jour fériés ,ce sont les francais : 1-01;1-05;8-05;14-07;15-08;1-11;11-11;25-12.

    dois-je les mettre dans un tableau ou les gérer autrement ?

    merci.

  4. #4
    Membre chevronné
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Décembre 2004
    Messages : 349
    Par défaut
    dans le principe , il vaut mieux les insérer dans une table , s'ils venaient à changer ou s'il fallait en ajouter ou supprimer, il serait + facile de modifier un enregistrement que d'aller chercher quelles fonctions ou procédures sont impactées.

    CDLT

  5. #5
    Membre Expert Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Par défaut
    Je suis d'accord avec taska sauf qu'à partir du moment où tu gère ça avec une table, le jour où elle n'est plus remplie TOUT tombe en rade (on a le problème à mon travail on vient A PEINE de mettre à jour les données pour 2007. Sans ça le 1er janvier les résultats sortaient faux).

    Il y a aussi la solution de la fonction qui contient un code métier mais ça aussi il faut le maintenir.

    De toutes façons le problème est simple : les jours ouvrés sont des données propres à chaque structure, il faut donc les gérer comme tel.

  6. #6
    Membre chevronné
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Décembre 2004
    Messages : 349
    Par défaut
    Sans ça le 1er janvier les résultats sortaient faux
    Pour quelle raison ?

  7. #7
    Membre Expert Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Par défaut
    exemple simple : CA à faire dans le mois = somme ( CA à faire par jour * coefficient du jour) avec un coefficient différent si c'est un jour ouvré ou non.

    Si le 1er janvier (qui est chômé il me semble) n'est pas indiqué comme un jour jour chômé, au pire il n'est même pas pris en compte (et il me manque carrément un jour), au mieux il est pris en compte avec un coefficient de jour ouvré, ce qui fausse les résultats.

    Evidemment on peut toujours mettre une batterie de tests, etc. mais tant que quelqu'un dans la structure ne prend pas à coeur de vérifier des données aussi vitales que le calendrier des jours ouvrés, il y aura des problèmes.

  8. #8
    Membre chevronné
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Décembre 2004
    Messages : 349
    Par défaut
    Evidemment on peut toujours mettre une batterie de tests
    Non seulement l'adaptation de ce petit bout de code dans une procédure ou fonction ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    declare
    /* Author TASKA */ 
    dateDeb date := to_date ('01/11/2006','DD/MM/RRRR');
    dateFin date ;
    nbJours number(2);
    nbJoursOuvres number(2);
    nbJoursFeries number(2) := 0;
    TYPE jour_feries IS TABLE OF date INDEX BY BINARY_INTEGER;
    jf   jour_feries;
    cptJF  number(2); --  nombre de jours féries
    begin
    	 dbms_output.put_line ('Mois de : '||TO_CHAR(dateDeb,'MONTH RRRR'));
     
    	 /* ICI l'idée est de charger la table des jours fériés en mémoire 
    	    pour éviter les accés bases 
     
    		je ne sais pas trop comment faire, je ne suis pas un pro ...
     
    	    Il est à noter pour la suite que nous ferons abstraction à l'année renseignée (pour nuke_y!)
     
    	 */
     
    	 jf(1):= to_date ('01/01/2000','DD/MM/RRRR');
    	 jf(2):= to_date ('01/11/2000','DD/MM/RRRR');
    	 jf(3):= to_date ('11/11/2000','DD/MM/RRRR');
    	 cptJF := 3;
     
    	 /*  Fin du chargement en mémoire ....*/
     
    	 -- Calcul du nombre de jours du mois 
    	 select LAST_DAY( dateDeb)-to_date (dateDeb)+1 into nbJours from dual ;
    	 dbms_output.put_line (nbJours);
    	 nbJoursOuvres := nbJours;
    	 nbJours := nbJours -1;
    	 while nbJours >=0 loop
    	       dbms_output.put_line ('Jours >'||TO_CHAR(dateDeb+nbJours,'DAY DD/MM/RRRR') ||' > nbJoursOuvres OLD '||nbJoursOuvres);
    	 	   -- Recherche dans le tableau mémoire si le jour courrant existe sous la forme DD/MM
    		   for  i in 1..jf.LAST  loop
    		      if TO_CHAR(dateDeb+nbJours,'DD/MM') = to_char (jf(i),'DD/MM') then
    			  	 -- Le jour existe, alors nous aurons 1 jour ouvré de moins
    				 nbJoursOuvres := nbJoursOuvres -1 ;
    				 dbms_output.put_line ('Jours férié '||TO_CHAR(dateDeb+nbJours,'DAY DD/MM/RRRR')||' > nbJoursOuvres FE '||nbJoursOuvres);
    				 goto suite; -- allons vérifier le jour suivant 	
    			 end if;
    	 	   end loop;
    		   -- Si le jour courrant n'est pas un jour férié alors vérifions qu'il ne s'agit 
    		   -- ni d'un SAMEDI ni d'un DIMANCHE !
    		   -- Ne pas omettre le RTRIM sinon ....	( essayez .... )	   
    		   if  rtrim(TO_CHAR(dateDeb+nbJours, 'DAY')) in ('SAMEDI','DIMANCHE')  then  
    	 	   	   nbJoursOuvres := nbJoursOuvres -1 ;
    			   -- encore un jour ouvré en moins 
    			   dbms_output.put_line ('Jours chomé '||TO_CHAR(dateDeb+nbJours,'DAY DD/MM/RRRR')||' > nbJoursOuvres WE '||nbJoursOuvres);
    		   end if;
    		   <<suite>>
    		   nbJours := nbJours -1; --  jour courant = 1er du mois + index 
    	 end loop;
         dbms_output.put_line ( 'Total Jours ouvrés : '|| nbJoursOuvres );
    end;
    CDLT.

  9. #9
    Membre Expert Avatar de nuke_y
    Profil pro
    Indépendant en analyse de données
    Inscrit en
    Mai 2004
    Messages
    2 076
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Indépendant en analyse de données

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 076
    Par défaut
    Tu ne comprends pas le problème : tant que personne ne prend à coeur de maintenir ces données là et de s'assurer de leur pérennité, tu prends le risque que ça tombe en carafe sans qu'on sache pourquoi.

    Ton bout de code caché dans une fonction, tu crois que ton responsable RH va penser à aller le modifier (en aura-t-il seulement le droit ?) si tu ne lui rappelles pas ? Et si la SEULE personne qui sait où et comment il faut faire les modifications tombe malade ? Ou quitte la structure en début d'années ? Qui saura ce qu'il faut faire 11 mois plus tard ?

    Si je dis ça, ce n'est pas pour décourager mais pour prévenir, j'ai le problème en ce moment même alors je sais de quoi je parle.

  10. #10
    Membre chevronné
    Profil pro
    Inscrit en
    Décembre 2004
    Messages
    349
    Détails du profil
    Informations personnelles :
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations forums :
    Inscription : Décembre 2004
    Messages : 349
    Par défaut
    tant que personne ne prend à coeur de maintenir ces données là et de s'assurer de leur pérennité, tu prends le risque que ça tombe en carafe sans qu'on sache pourquoi.
    Je te l'accorde mais cette reflexion remet en cause la destination même de l'outil informatique et des personnes chargées de le rendre cohérant ( responsable de domaine, responsable d'application, etc ... Il faut peut être l'abandonner et reprendre papiers et crayons et réapprendre à calculer sans machine !

    Dans le script que j'ai passé, il n'y a pas lieu de la maintenir ni de le remettre à jour chaque année si les jours fériés ne changent pas(!) . Nous faisons complétement abstraction à l'année renseignée dans la table de référence JOURS_FERIES.

    Si je dis ça, ce n'est pas pour décourager
    Tu ne me décourage pas, je pense simplement que cette méthode ne correspond pas à ton besoin. Je l'ai développé pour aider francky22 dans la résolution de sa problématique.

    A ce propos, le code à été un peu modifié et je le re-post dans l'objectif d'aider un peu francky22

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    create table JOURS_FERIES
    ( XDATE DATE );
     
    insert into JOURS_FERIES ( XDATE ) values (to_date ('01/01/2000','DD/MM/RRRR'));
    insert into JOURS_FERIES ( XDATE ) values (to_date ('01/05/2000','DD/MM/RRRR'));
    insert into JOURS_FERIES ( XDATE ) values (to_date ('08/05/2000','DD/MM/RRRR'));
    insert into JOURS_FERIES ( XDATE ) values (to_date ('14/07/2000','DD/MM/RRRR'));
    insert into JOURS_FERIES ( XDATE ) values (to_date ('15/08/2000','DD/MM/RRRR'));
    insert into JOURS_FERIES ( XDATE ) values (to_date ('01/11/2000','DD/MM/RRRR'));
    insert into JOURS_FERIES ( XDATE ) values (to_date ('11/11/2000','DD/MM/RRRR'));
    insert into JOURS_FERIES ( XDATE ) values (to_date ('25/12/2000','DD/MM/RRRR'));
    commit;
     
    create or replace  function NB_JOURS_OUVRES ( dateDeb date) return number is
    /* Author TASKA */ 
    dateFin date ;
    nbJours number(2);
    nbJoursOuvres number(2);
    nbJoursFeries number(2) := 0;
    TYPE jour_feries IS TABLE OF date INDEX BY BINARY_INTEGER;
    jf   jour_feries;
    -- cptJF  number(2); --  nombre de jours féries
    cpt number(2) := 1;
    begin
     
    	 dbms_output.put_line ('Mois de : '||TO_CHAR(dateDeb,'MONTH RRRR'));
     
    	 /* ICI l'idée est de charger la table des jours fériés en mémoire 
    	    pour éviter les accés bases 
    	    Il est à noter pour la suite que nous ferons abstraction à l'année renseignée (pour nuke_y!)
    	 */
    	 for rec in (Select XDATE from JOURS_FERIES) loop
    	 	 jf(cpt):= rec.XDATE;
    		 cpt := cpt+1 ;
    	 end loop; 
     
    	 -- Calcul du nombre de jours du mois 
    	 select LAST_DAY( dateDeb)-to_date (dateDeb)+1 into nbJours from dual ;
    	 --dbms_output.put_line (nbJours);
    	 nbJoursOuvres := nbJours;
    	 nbJours := nbJours -1;
    	 while nbJours >=0 loop
    	       -- dbms_output.put_line ('Jours >'||TO_CHAR(dateDeb+nbJours,'DAY DD/MM/RRRR') ||' > nbJoursOuvres OLD '||nbJoursOuvres);
    	 	   -- Recherche dans le tableau mémoire si le jour courrant existe sous la forme DD/MM
    		   for  i in 1..jf.LAST  loop
    		      if TO_CHAR(dateDeb+nbJours,'DD/MM') = to_char (jf(i),'DD/MM') then
    			  	 -- Le jour existe, alors nous aurons 1 jour ouvré de moins
    				 nbJoursOuvres := nbJoursOuvres -1 ;
    				 -- dbms_output.put_line ('Jours férié '||TO_CHAR(dateDeb+nbJours,'DAY DD/MM/RRRR')||' > nbJoursOuvres FE '||nbJoursOuvres);
    				 goto suite; -- allons vérifier le jour suivant 	
    			 end if;
    	 	   end loop;
    		   -- Si le jour courrant n'est pas un jour férié alors vérifions qu'il ne s'agit 
    		   -- ni d'un SAMEDI ni d'un DIMANCHE !
    		   -- Ne aps omettre le RTRIM sinon ....	( essayer ! )	   
    		   if  rtrim(TO_CHAR(dateDeb+nbJours, 'DAY')) in ('SAMEDI','DIMANCHE')  then  
    	 	   	   nbJoursOuvres := nbJoursOuvres -1 ;
    			   -- encore un jour ouvré en moins 
    			   -- dbms_output.put_line ('Jours chomé '||TO_CHAR(dateDeb+nbJours,'DAY DD/MM/RRRR')||' > nbJoursOuvres WE '||nbJoursOuvres);
    		   end if;
    		   <<suite>>
    		   nbJours := nbJours -1; --  jour courant = 1er du mois + index 
    	 end loop;
         -- dbms_output.put_line ( 'Total Jours ouvrés : '|| nbJoursOuvres );
    	 return nbJoursOuvres ;
    end;
    ...

    1* select NB_JOURS_OUVRES('01/05/2006') from dual
    SQL> /

    NB_JOURS_OUVRES('01/05/2006')
    -----------------------------
    21

    SQL>

    CDLT.

  11. #11
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2006
    Messages : 5
    Par défaut
    Merci à tous pour votre aide ....
    je m'y colle de suite.
    CDLT

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [Dates] calcul entre deux dates
    Par angeblanc22 dans le forum Langage
    Réponses: 6
    Dernier message: 16/03/2007, 13h42
  2. [Date] Calcul entre deux dates
    Par djodjo dans le forum Collection et Stream
    Réponses: 7
    Dernier message: 14/09/2006, 15h32
  3. [Dates] Calcul entre 2 dates
    Par Smash34 dans le forum Langage
    Réponses: 3
    Dernier message: 19/04/2006, 13h20
  4. [Oracle8] calcul entre 2 dates
    Par bobunny dans le forum Oracle
    Réponses: 7
    Dernier message: 28/10/2005, 13h18
  5. Calcul entre deux dates heures
    Par Isa31 dans le forum Algorithmes et structures de données
    Réponses: 9
    Dernier message: 31/03/2005, 14h17

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo