Pular para o conteúdo
  • Este tópico contém 12 respostas, 3 vozes e foi atualizado pela última vez 4 anos, 2 meses atrás por Avatar de Maxwell OliveiraMaxwell Oliveira.
Visualizando 13 posts - 1 até 13 (de 13 do total)
  • Autor
    Posts
  • #143487
    Avatar de FabíolaFabíola
    Participante

      Pessoal, bom dia.

      Preciso calcular em horas e minutos a diferença entre datas com horas e minutos.

      Exemplo:

      Data Inicial: 01/06/2006 10:30
      Data Final:   02/06/2006 14:00

      Preciso que o retorno seja: 27:30

       

      Tentei o código abaixo, porem o retorno dele é:  24:-30

      select trunc(((to_number(to_date(’02/06/2006 10:30′,’DD/MM/yyyy HH24:MI’) –
      to_date(’01/06/2006 11:00′,’DD/MM/yyyy HH24:MI’)) * 1440))/60)||’:’||

      trunc((to_number(to_date(’02/06/2006 10:30′,’DD/MM/RRRR HH24:MI’) –
      to_date(’01/06/2006 11:00′,’DD/MM/RRRR HH24:MI’)) * 1440) -1440)
      from dual

      #143489
      Avatar de José Laurindo ChiappaJosé Laurindo Chiappa
      Moderador

        É super-bico : o que vc TEM que saber é que quando vc faz a Subtração de duas datas, o Oracle te retorna um NÚMERO cuja parte Inteira é a quantidade de dias E a fração é o quanto de um dia sobrou….
        Como o dia tem 24 horas, o cálculo de HORAS é simplesmente pegar a parte INTEIRA desse cálculo e multiplicar por 24, que são as 24 horas do dia…
        Já o cálculo de MINUTOS é repetir o cálculo de Horas (com a variação de que PODE ou não haver a porção inteira) e multiplicar por 60, a quantidade de horas vezes 60 dá os minutos….

        Como Exemplo, vamos ter uma massa de dados onde há intervalos com menos de um dia, com mais de um dias, com mais de dois dias, com minutos fracionados e sem minutos fracionados :

        scott@DESENV:SQL>create table T(start_date date, end_date date);
        
        Tabela criada.
        
        scott@DESENV:SQL>insert into T values(to_date('01/06/2006 11:00','DD/MM/yyyy HH24:MI'), to_date('02/06/2006 10:30','DD/MM/yyyy HH24:MI') );
        
        1 linha criada.
        
        scott@DESENV:SQL>insert into T values(to_date('01/06/2006 10:30','DD/MM/yyyy HH24:MI'), to_date('02/06/2006 14:00','DD/MM/yyyy HH24:MI') );
        
        1 linha criada.
        
        scott@DESENV:SQL>insert into T values(to_date('01/06/2006 10:10','DD/MM/yyyy HH24:MI'), to_date('02/06/2006 13:50','DD/MM/yyyy HH24:MI') );
        
        1 linha criada.
        
        scott@DESENV:SQL>insert into T values(to_date('03/06/2006 10:00','DD/MM/yyyy HH24:MI'), to_date('03/06/2006 13:00','DD/MM/yyyy HH24:MI') );
        
        1 linha criada.
        
        scott@DESENV:SQL>insert into T values(to_date('04/06/2006 10:10','DD/MM/yyyy HH24:MI'), to_date('07/06/2006 13:50','DD/MM/yyyy HH24:MI') );
        
        1 linha criada.
        
        scott@DESENV:SQL>insert into T values(to_date('05/06/2006 08:00','DD/MM/yyyy HH24:MI'), to_date('06/06/2006 08:00','DD/MM/yyyy HH24:MI') );
        
        1 linha criada.
        
        scott@DESENV:SQL>insert into T values(to_date('05/06/2006 08:10','DD/MM/yyyy HH24:MI'), to_date('05/06/2006 08:12','DD/MM/yyyy HH24:MI') );
        
        1 linha criada.
        
        scott@DESENV:SQL>insert into T values(to_date('06/06/2006 08:00','DD/MM/yyyy HH24:MI'), to_date('09/06/2006 09:12','DD/MM/yyyy HH24:MI') );
        
        1 linha criada.

        => Eis a consulta implementando a lógica que indiquei :

        scott@DESENV:SQL>select start_date, end_date,
        2   trunc( 24* (end_date - start_date))                as HORAS,
        3   trunc( mod(mod(end_date - start_date,1)*24,1)*60 ) as MINUTOS
        4  from T;
        
        START_DATE          END_DATE            HORAS     MINUTOS
        ------------------- ------------------- --------- ---------
        01/06/2006 11:00:00 02/06/2006 10:30:00 23        30
        01/06/2006 10:30:00 02/06/2006 14:00:00 27        29
        01/06/2006 10:10:00 02/06/2006 13:50:00 27        40
        03/06/2006 10:00:00 03/06/2006 13:00:00 3         0
        04/06/2006 10:10:00 07/06/2006 13:50:00 75        40
        05/06/2006 08:00:00 06/06/2006 08:00:00 24        0
        05/06/2006 08:10:00 05/06/2006 08:12:00 0         2
        06/06/2006 08:00:00 09/06/2006 09:12:00 73        12
        
        8 linhas selecionadas.

        Blz ???

        Abraços,

        Chiappa

        #143491
        Avatar de FabíolaFabíola
        Participante

          Chiappa, você salvou minha vida!!!

          Muito obrigada!

          Agradecimentos, mil….

          🙂

          #143492
          Avatar de FabíolaFabíola
          Participante

            Hum.. perai que encontrei um problema, exemplo nessa linha…

            01/06/2006 10:30:00    01/06/2006 11:00:00    00:29

             

            O retorno deveria dar 00:30 e não 00:29

             

            01/06/2006 10:30:00    02/06/2006 11:00:00    24 29

            O retorno deveria dar 24:30 e não 24:29

             

            🙁

            #143495
            Avatar de José Laurindo ChiappaJosé Laurindo Chiappa
            Moderador

              Pelo jeito, acontece quando o horário final é zero : mete um DECODE ou um CASE aí, então, e veja …

              []s

              Chiappa

              #143496
              Avatar de FabíolaFabíola
              Participante

                Entendi, mas acho que não funciona para o caso abaixo…

                ex:

                05/06/2006 08:00:00     06/06/2006 08:00:00      24 00

                poderia colocar um decode para quando fosse 0 somar 1… mas nesse caso acima daria errado.

                🙁

                #143497
                Avatar de José Laurindo ChiappaJosé Laurindo Chiappa
                Moderador

                  Eu fui dar uma olhada melhor, e a Causa era um Arredondamnento, o cálculo tava dando 29,999995, aí o TRUNC que eu usei antes dava 29 …. A solução acredito que é só pedir mais um MOD, assim :

                  scott@DESENV:SQL>insert into T values(TO_DATE('01/06/2006 10:30:00', 'dd/mm/yyyy hh24:mi:ss'), TO_DATE('02/06/2006 11:00:00', 'dd/mm/yyyy hh24:mi:ss'));
                  
                  1 linha criada.
                  
                  scott@DESENV:SQL>insert into T values (TO_DATE('01/06/2006 11:00:00', 'dd/mm/yyyy hh24:mi:ss'),  TO_DATE('01/06/2006 11:30:00', 'dd/mm/yyyy hh24:mi:ss') ) ;
                  
                  1 linha criada.

                  ==> Agora a query alterada :

                  scott@DESENV:SQL>select start_date, end_date,
                    2    trunc(    24*mod(end_date - start_date,1))           as HORAS,
                    3         (   mod(mod(end_date - start_date,1)*24,1)*60 ) as MINUTOS
                    4   from T;
                  
                  START_DATE          END_DATE                HORAS   MINUTOS
                  ------------------- ------------------- --------- ---------
                  01/06/2006 11:00:00 02/06/2006 10:30:00        23        30
                  01/06/2006 10:30:00 02/06/2006 14:00:00         3        30
                  01/06/2006 10:10:00 02/06/2006 13:50:00         3        40
                  03/06/2006 10:00:00 03/06/2006 13:00:00         3         0
                  04/06/2006 10:10:00 07/06/2006 13:50:00         3        40
                  05/06/2006 08:00:00 06/06/2006 08:00:00         0         0
                  05/06/2006 08:10:00 05/06/2006 08:12:00         0         2
                  06/06/2006 08:00:00 09/06/2006 09:12:00         1        12
                  01/06/2006 10:30:00 02/06/2006 11:00:00         0        30
                  01/06/2006 11:00:00 01/06/2006 11:30:00         0        30
                  
                  10 linhas selecionadas.
                  
                  scott@DESENV:SQL>

                  ==> faz uns testes mais, mas Acredito que é isso aí….

                  []s

                  Chiappa

                  #143498
                  Avatar de José Laurindo ChiappaJosé Laurindo Chiappa
                  Moderador

                    Ops, de novo : na hora de corrigir a linha dos minutos, copiei errado a linha dos Dias, deixa eu corrigir…

                    #143499
                    Avatar de FabíolaFabíola
                    Participante

                      Eu percebi, mas consegui arrumar. rsrs

                      Muito obrigada!!!

                      Agora parece estar perfeito….

                      #143500
                      Avatar de José Laurindo ChiappaJosé Laurindo Chiappa
                      Moderador

                        Agora sim :

                        scott@DESENV:SQL>select start_date, end_date,
                          2         trunc( 24* (end_date - start_date))             as HORAS,
                          3         (   mod(mod(end_date - start_date,1)*24,1)*60 ) as MINUTOS
                          4*  from T;
                        
                        START_DATE          END_DATE                HORAS   MINUTOS
                        ------------------- ------------------- --------- ---------
                        01/06/2006 11:00:00 02/06/2006 10:30:00        23        30
                        01/06/2006 10:30:00 02/06/2006 14:00:00        27        30
                        01/06/2006 10:10:00 02/06/2006 13:50:00        27        40
                        03/06/2006 10:00:00 03/06/2006 13:00:00         3         0
                        04/06/2006 10:10:00 07/06/2006 13:50:00        75        40
                        05/06/2006 08:00:00 06/06/2006 08:00:00        24         0
                        05/06/2006 08:10:00 05/06/2006 08:12:00         0         2
                        06/06/2006 08:00:00 09/06/2006 09:12:00        73        12
                        01/06/2006 10:30:00 02/06/2006 11:00:00        24        30
                        01/06/2006 11:00:00 01/06/2006 11:30:00         0        30
                        
                        10 linhas selecionadas.
                        
                        scott@DESENV:SQL>

                        Sorry pela escapadela, é que na hora de fazer o copy/paste ás vezes o cerebrozinho buga….

                        []s

                        Chiappa

                        #143502
                        Avatar de José Laurindo ChiappaJosé Laurindo Chiappa
                        Moderador

                          Não deixe ** mesmo ** de fazer uns bons testes mais, simulando mais situações possíveis, mas Acredito que o caminho é este aqui… E mais importante que receber a resposta, é vc ter Entendido como se aplica uma lógica em pseudocódigo num código PL/SQL, como se DEBUGA código… No meu caso eu não mostrei, mas como eu disse simplesmente alterei a query para mostrar a subtração SEM nenhuma alteração, aí fiz na mão a multiplicacão por 24 , só Assim que fui descobrir que o prob era Arredondamento….

                          []s

                          Chiappa

                          #143503
                          Avatar de FabíolaFabíola
                          Participante

                            Imagina, eu só tenho que agradecer.

                            Estou testando aqui e aparentemente deu tudo certinho.

                            Muito obrigada!!!

                            🙂

                            #145340
                            Avatar de Maxwell OliveiraMaxwell Oliveira
                            Participante

                              Bom dia,

                              Fiz uma alteração no seu código agora esta retornando hora, Minuto e Segundo.
                              <div class=”bbp-reply-content”>

                              
                              SELECT trunc(24 * (end_date - start_date)) AS horas,
                              abs(trunc((MOD(MOD(end_date - start_date, 1) * 24, 1) * 60))) AS minutos,
                              abs(trunc((MOD((MOD(MOD(end_date - start_date, 1) * 24, 1) * 60), 1) * 60))) AS segundos
                              FROM t;
                              
                              

                              </div>

                            Visualizando 13 posts - 1 até 13 (de 13 do total)
                            • Você deve fazer login para responder a este tópico.
                            plugins premium WordPress