Marcado: oracle Date time
- Este tópico contém 12 respostas, 3 vozes e foi atualizado pela última vez 4 anos, 9 meses atrás por Maxwell Oliveira.
-
AutorPosts
-
26 de julho de 2019 às 12:16 pm #143487FabíolaParticipante
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:00Preciso 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 dual26 de julho de 2019 às 1:11 pm #143489José Laurindo ChiappaModeradorÉ 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
26 de julho de 2019 às 1:25 pm #143491FabíolaParticipanteChiappa, você salvou minha vida!!!
Muito obrigada!
Agradecimentos, mil….
🙂
26 de julho de 2019 às 1:31 pm #143492FabíolaParticipanteHum.. 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
🙁
26 de julho de 2019 às 2:15 pm #143495José Laurindo ChiappaModeradorPelo jeito, acontece quando o horário final é zero : mete um DECODE ou um CASE aí, então, e veja …
[]s
Chiappa
26 de julho de 2019 às 2:50 pm #143496FabíolaParticipanteEntendi, 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.
🙁
26 de julho de 2019 às 3:09 pm #143497José Laurindo ChiappaModeradorEu 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
26 de julho de 2019 às 3:14 pm #143498José Laurindo ChiappaModeradorOps, de novo : na hora de corrigir a linha dos minutos, copiei errado a linha dos Dias, deixa eu corrigir…
26 de julho de 2019 às 3:17 pm #143499FabíolaParticipanteEu percebi, mas consegui arrumar. rsrs
Muito obrigada!!!
Agora parece estar perfeito….
26 de julho de 2019 às 3:20 pm #143500José Laurindo ChiappaModeradorAgora 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
26 de julho de 2019 às 3:35 pm #143502José Laurindo ChiappaModeradorNã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
26 de julho de 2019 às 3:36 pm #143503FabíolaParticipanteImagina, eu só tenho que agradecer.
Estou testando aqui e aparentemente deu tudo certinho.
Muito obrigada!!!
🙂
12 de fevereiro de 2020 às 12:08 pm #145340Maxwell OliveiraParticipanteBom 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>
-
AutorPosts
- Você deve fazer login para responder a este tópico.