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

PL/SQL Oracle Discussion :

Intervalle entre deux dates en secondes


Sujet :

PL/SQL Oracle

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Octobre 2012
    Messages : 43
    Par défaut Intervalle entre deux dates en secondes
    Bonjour, je vous explique :

    J'ai deux dates : par exemple :
    13/06/2012 18:15:00 ET 16/06/2012 09:30

    Je voudrais faire une différence entre ces deux dates.
    Mais je veux que la plage d'horaire entre 19h et 07h ne sois pas prise en compte.
    Je veux avoir le résultat de la différence en secondes.
    Pour l'exemple (en calcul à la main), on arrive à 15h30 de différence, sois 55800 secondes.

    J'ai entendu parler de la fonction Modulo mais je ne comprend pas comment ceci fonctionne.

    Merci pour votre aide.

  2. #2
    Membre Expert Avatar de ojo77
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Décembre 2010
    Messages
    680
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Architecte de base de données
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2010
    Messages : 680
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select (date2-date1)*24*60*60 from dual;

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Octobre 2012
    Messages : 43
    Par défaut
    Citation Envoyé par ojo77 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    select (date2-date1)*24*60*60 from dual;
    C'est un bon début, mais la plage entre 19h et 7h (plage de nuit) ne dois pas être prise en compte...

  4. #4
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 952
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 952
    Par défaut
    Citation Envoyé par lllhuhdklll Voir le message
    Pour l'exemple (en calcul à la main), on arrive à 15h30 de différence, sois 55800 secondes.
    C'est faux, il manque une journée...
    En SQL :
    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
      with t as (
    select to_date('13/06/2012 18:15','dd/mm/yyyy hh24:mi') as d_deb,
           to_date('16/06/2012 09:30','dd/mm/yyyy hh24:mi') as d_fin
      from dual),
           t_07_19 as (
    select case when d_deb >= to_date(to_char(d_deb,'YYYYMMDD')||'19:00','YYYYMMDDhh24:mi')
                then to_date(to_char(d_deb + 1,'YYYYMMDD')||'07:00','YYYYMMDDhh24:mi')
                when d_deb <= to_date(to_char(d_deb,'YYYYMMDD')||'07:00','YYYYMMDDhh24:mi')
                then to_date(to_char(d_deb,'YYYYMMDD')||'07:00','YYYYMMDDhh24:mi')
                else d_deb
            end as d_deb,
           case when d_fin >= to_date(to_char(d_fin,'YYYYMMDD')||'19:00','YYYYMMDDhh24:mi')
                then to_date(to_char(d_fin,'YYYYMMDD')||'19:00','YYYYMMDDhh24:mi')
                when d_fin <= to_date(to_char(d_fin,'YYYYMMDD')||'07:00','YYYYMMDDhh24:mi')
                then to_date(to_char(d_fin - 1,'YYYYMMDD')||'19:00','YYYYMMDDhh24:mi')
                else d_fin
            end as d_fin
       from t
    )
    select   (d_fin - to_date(to_char(d_fin,'YYYYMMDD')||'07:00','YYYYMMDDhh24:mi'))*24*60*60
           + (to_date(to_char(d_deb,'YYYYMMDD')||'19:00','YYYYMMDDhh24:mi') - d_deb)*24*60*60
           + (trunc(d_fin - 1) - trunc(d_deb + 1) +1)*12*60*60
      from t_07_19
    Mais une fonction PL/SQL est plus utile/maintenable (ou sinon créer une vue):
    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
    create or replace function func_DureeSec (
              p_date_deb date, 
              p_date_fin date, 
              p_heure_debut varchar2 default '07:00', 
              p_heure_fin varchar2 default '19:00') 
    return number deterministic as
        l_date_deb date;
        l_date_fin date;
    begin
     
        if (p_date_deb >= to_date(to_char(p_date_deb,'YYYYMMDD')||p_heure_fin,'YYYYMMDDhh24:mi')) then
            l_date_deb := to_date(to_char(p_date_deb + 1,'YYYYMMDD')||p_heure_debut,'YYYYMMDDhh24:mi');
        elsif (p_date_deb <= to_date(to_char(p_date_deb,'YYYYMMDD')||p_heure_debut,'YYYYMMDDhh24:mi')) then
            l_date_deb := to_date(to_char(p_date_deb,'YYYYMMDD')||p_heure_debut,'YYYYMMDDhh24:mi');
        else 
            l_date_deb := p_date_deb;
        end if;
     
        if (p_date_fin >= to_date(to_char(p_date_fin,'YYYYMMDD')||p_heure_fin,'YYYYMMDDhh24:mi')) then
            l_date_fin := to_date(to_char(p_date_fin,'YYYYMMDD')||p_heure_fin,'YYYYMMDDhh24:mi');
        elsif (p_date_fin <= to_date(to_char(p_date_fin,'YYYYMMDD')||p_heure_debut,'YYYYMMDDhh24:mi')) then
            l_date_fin := to_date(to_char(p_date_fin - 1,'YYYYMMDD')||p_heure_fin,'YYYYMMDDhh24:mi');
        else 
            l_date_fin := p_date_fin;
        end if;
     
        return (l_date_fin - to_date(to_char(l_date_fin,'YYYYMMDD')||p_heure_debut,'YYYYMMDDhh24:mi'))*24*60*60
             + (to_date(to_char(l_date_deb,'YYYYMMDD')||p_heure_fin,'YYYYMMDDhh24:mi') - l_date_deb)*24*60*60
             + (trunc(l_date_fin - 1) - trunc(l_date_deb + 1) +1) * ( to_date('19000101'||p_heure_fin,'YYYYMMDDhh24:mi')
                                                                     -to_date('19000101'||p_heure_debut,'YYYYMMDDhh24:mi'))*24*60*60;
     
    end func_DureeSec;
    /
    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
    SQL>   with t as (
      2  select to_date('13/06/2012 18:15','dd/mm/yyyy hh24:mi') as d_deb, to_date('16/06/2012 9:30','dd/mm/yyyy hh24:mi') as d_fin from dual union all
      3  select to_date('13/06/2012 18:15','dd/mm/yyyy hh24:mi') as d_deb, to_date('14/06/2012 02:30','dd/mm/yyyy hh24:mi') as d_fin from dual union all
      4  select to_date('13/06/2012 18:15','dd/mm/yyyy hh24:mi') as d_deb, to_date('13/06/2012 18:30','dd/mm/yyyy hh24:mi') as d_fin from dual union all
      5  select to_date('13/06/2012 22:15','dd/mm/yyyy hh24:mi') as d_deb, to_date('16/06/2012 09:30','dd/mm/yyyy hh24:mi') as d_fin from dual union all
      6  select to_date('13/06/2012 22:15','dd/mm/yyyy hh24:mi') as d_deb, to_date('14/06/2012 05:30','dd/mm/yyyy hh24:mi') as d_fin from dual
      7  )
      8  select d_deb, d_fin,
      9         (select func_DureeSec(d_deb, d_fin) from dual) as dureesec
     10    from t;
     
    D_DEB               D_FIN                 DUREESEC
    ------------------- ------------------- ----------
    13/06/2012 18:15:00 16/06/2012 09:30:00      98100
    13/06/2012 18:15:00 14/06/2012 02:30:00       2700
    13/06/2012 18:15:00 13/06/2012 18:30:00        900
    13/06/2012 22:15:00 16/06/2012 09:30:00      95400
    13/06/2012 22:15:00 14/06/2012 05:30:00          0
     
    SQL>

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2012
    Messages
    43
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : High Tech - Matériel informatique

    Informations forums :
    Inscription : Octobre 2012
    Messages : 43
    Par défaut
    Citation Envoyé par skuatamad Voir le message
    C'est faux, il manque une journée...
    Oups... Exact.

    Citation Envoyé par skuatamad Voir le message
    Mais une fonction PL/SQL est plus utile/maintenable (ou sinon créer une vue):
    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
    create or replace function func_DureeSec (
              p_date_deb date, 
              p_date_fin date, 
              p_heure_debut varchar2 default '07:00', 
              p_heure_fin varchar2 default '19:00') 
    return number deterministic as
        l_date_deb date;
        l_date_fin date;
    begin
     
        if (p_date_deb >= to_date(to_char(p_date_deb,'YYYYMMDD')||p_heure_fin,'YYYYMMDDhh24:mi')) then
            l_date_deb := to_date(to_char(p_date_deb + 1,'YYYYMMDD')||p_heure_debut,'YYYYMMDDhh24:mi');
        elsif (p_date_deb <= to_date(to_char(p_date_deb,'YYYYMMDD')||p_heure_debut,'YYYYMMDDhh24:mi')) then
            l_date_deb := to_date(to_char(p_date_deb,'YYYYMMDD')||p_heure_debut,'YYYYMMDDhh24:mi');
        else 
            l_date_deb := p_date_deb;
        end if;
     
        if (p_date_fin >= to_date(to_char(p_date_fin,'YYYYMMDD')||p_heure_fin,'YYYYMMDDhh24:mi')) then
            l_date_fin := to_date(to_char(p_date_fin,'YYYYMMDD')||p_heure_fin,'YYYYMMDDhh24:mi');
        elsif (p_date_fin <= to_date(to_char(p_date_fin,'YYYYMMDD')||p_heure_debut,'YYYYMMDDhh24:mi')) then
            l_date_fin := to_date(to_char(p_date_fin - 1,'YYYYMMDD')||p_heure_fin,'YYYYMMDDhh24:mi');
        else 
            l_date_fin := p_date_fin;
        end if;
     
        return (l_date_fin - to_date(to_char(l_date_fin,'YYYYMMDD')||p_heure_debut,'YYYYMMDDhh24:mi'))*24*60*60
             + (to_date(to_char(l_date_deb,'YYYYMMDD')||p_heure_fin,'YYYYMMDDhh24:mi') - l_date_deb)*24*60*60
             + (trunc(l_date_fin - 1) - trunc(l_date_deb + 1) +1) * ( to_date('19000101'||p_heure_fin,'YYYYMMDDhh24:mi')
                                                                     -to_date('19000101'||p_heure_debut,'YYYYMMDDhh24:mi'))*24*60*60;
     
    end func_DureeSec;
    /
    Euh, comment dire... Un grand MERCI !!!
    C'est exactement ce qu'il me fallais !!!
    C'est vrai que c'est un peu compliqué quand ça fais seulement 1 mois que je me suis mis au PL/SQL.

  6. #6
    Expert confirmé
    Profil pro
    Inscrit en
    Août 2008
    Messages
    2 952
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 2 952
    Par défaut
    Une version qui tient compte des jours fériés et WE qui s'appuie sur le calendrier proposé par waldar :
    Calendrier avec jours fériés
    [edit] code faux voir message plus bas

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

Discussions similaires

  1. Réponses: 17
    Dernier message: 15/05/2012, 16h22
  2. XUL/js Intervalle entre deux dates :(
    Par kreatik dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 23/03/2009, 13h38
  3. intervalle entre deux dates
    Par amazircool dans le forum Langage
    Réponses: 3
    Dernier message: 29/04/2008, 14h25
  4. Intervale entre deux dates
    Par ecirb dans le forum Collection et Stream
    Réponses: 20
    Dernier message: 26/03/2007, 09h21
  5. Intervalle entre deux dates
    Par ecirb dans le forum InfoPath
    Réponses: 15
    Dernier message: 22/03/2007, 10h39

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