Diferença de Data com horas e minutos

Home Fóruns SQL e PL/SQL Diferença de Data com horas e minutos

Visualizando 13 posts - 1 até 13 (de 13 do total)
  • Autor
    Posts
  • #143487
    Fabí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

    É 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
    Fabíola
    Participante

    Chiappa, você salvou minha vida!!!

    Muito obrigada!

    Agradecimentos, mil….

    🙂

    #143492
    Fabí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

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

    []s

    Chiappa

    #143496
    Fabí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

    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

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

    #143499
    Fabíola
    Participante

    Eu percebi, mas consegui arrumar. rsrs

    Muito obrigada!!!

    Agora parece estar perfeito….

    #143500

    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

    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
    Fabíola
    Participante

    Imagina, eu só tenho que agradecer.

    Estou testando aqui e aparentemente deu tudo certinho.

    Muito obrigada!!!

    🙂

    #145340
    Maxwell 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.
Ads Blocker Image Powered by Code Help Pro

Ads Blocker Detectado !

Verificamos que está usando alguma extensão para bloquear os anúncios. O GPO (Grupo de Profissionais Oracle) obtém a sua renda através dos anúncios, para assim manter toda a estrutura dedicada a universalização do conhecimento.

Se você gosta de nosso trabalho, pedimos por gentileza que desabilite o ads blocker. Trabalhamos somente com o Google Adsense e tentamos ao máximo exibir apenas o necessário.

Agradecemos de antemão ! :)

Powered By
Best Wordpress Adblock Detecting Plugin | CHP Adblock