Calculo de horas entre duas datas/horas

Dúvidas, dicas e truques de SQL, Select, Update, Delete, cláusulas, operações com joins, Funções em SQLs, etc
Marlon Pasquali
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 28
Registrado em: Seg, 20 Mar 2006 3:40 pm
Localização: Erechim - RS

Olá pessoal, preciso da ajuda de voces feras. Tenho 2 colunas em uma tabela que são do tipo Varchar2. não posso alterar isso porque elas fazem parte do aplicativo. Tenho gravado nestas colunas a data e hora que ocorreram uma certa operação e preciso então fazer o calculo de horas entre estas duas colunas. O fato é que não estou conseguindo formatar a coluna como data para poder fazer este calculo. Os dados estao gravados no seguinte exemplo de formato: 13/06/06 06:26:17

alguém pode me ajudar em como fazer o calculo de horas entre estas 2 colunas

obrigado
Avatar do usuário
TBou
Rank: Analista Sênior
Rank: Analista Sênior
Mensagens: 136
Registrado em: Qui, 05 Ago 2004 9:33 am
Localização: Campo Grande - MS
Thiago Bourscheidt
thiago.info@apoiorural.com.br
Analista de Sistemas

neste exemplo estou fazendo apenas uma subtração:

Selecionar tudo

select to_date('02/06/2006 12:30:00','DD/MM/RRRR HH24:MI:SS') - to_date('01/06/2006 11:30:00','DD/MM/RRRR HH24:MI:SS') DIAS
from dual
resultado em Dias:

Selecionar tudo

DIAS
----------
1,04166667
1 linha selecionada.
Isso ajuda?..qualquer coisa informe qual tipo de calculo você precisa executar.
Marlon Pasquali
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 28
Registrado em: Seg, 20 Mar 2006 3:40 pm
Localização: Erechim - RS

beleza TBou, peguei o teu exemplo e multipliquei por 24 e obtive o numero de horas. Disso que eu precisava


valeu, obrigado
Avatar do usuário
TBou
Rank: Analista Sênior
Rank: Analista Sênior
Mensagens: 136
Registrado em: Qui, 05 Ago 2004 9:33 am
Localização: Campo Grande - MS
Thiago Bourscheidt
thiago.info@apoiorural.com.br
Analista de Sistemas

OPas...Para montar uma String com o período em Dias, Horas,Minutos que temos entre as duas podemos fazer uma concatenação assim

Selecionar tudo

select round(to_number(to_date('02/06/2006 11:00','DD/MM/RRRR HH24:MI') - 
                       to_date('01/06/2006 10:30','DD/MM/RRRR HH24:MI')))||' Dia(s) '||
       round(((to_number(to_date('02/06/2006 11:00','DD/MM/RRRR HH24:MI') - 
                         to_date('01/06/2006 10:30','DD/MM/RRRR HH24:MI')) * 1440) -1440)/60)||' Hora(s) '||
       round((to_number(to_date('02/06/2006 11:00','DD/MM/RRRR HH24:MI') - 
                         to_date('01/06/2006 10:30','DD/MM/RRRR HH24:MI')) * 1440) -1440)||' Minuto(s) '
from dual 
Resultado

Selecionar tudo

ROUND(TO_NUMBER(TO_DATE('02/06/200611:00','DD/MM/RRRRHH24:MI')-TO_DATE('01/06/  
--------------------------------------------------------------------------------
1 Dia(s) 0 Hora(s) 30 Minuto(s)                                                 
Avatar do usuário
TBou
Rank: Analista Sênior
Rank: Analista Sênior
Mensagens: 136
Registrado em: Qui, 05 Ago 2004 9:33 am
Localização: Campo Grande - MS
Thiago Bourscheidt
thiago.info@apoiorural.com.br
Analista de Sistemas

Moçada Descuple pelo Equívoco mas esta Select que eu passei só funciona quando é um Dia entre as datas.

eu corrigi a select e simplifiquei ela acho que agora vai ficar mais simples para entender
vejam:

Selecionar tudo

select round(INTERVALO)||' Dia(s) '||
       /* 1440 É O NUMERO DE MINUTOS POR HORA*/                        
       round(((INTERVALO * 1440) -(round(INTERVALO)*1440))/60)||' Hora(s) '||
       round( (INTERVALO * 1440) -(round(INTERVALO)*1440))||' Minuto(s) '
from (select to_number(to_date('02/06/2006 11:00','DD/MM/RRRR HH24:MI') -
                       to_date('01/06/2006 10:30','DD/MM/RRRR HH24:MI')) INTERVALO
        from dual )
valeu Até mais
gersonjr
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 1
Registrado em: Dom, 06 Jun 2004 4:21 am
Localização: Maceió - AL

Cara,

Este teu select está errado ainda. Se voc colocar um intervalo que seja igual ou ultrapasse 60 minutos ele retorna 60 minutos, 75 minutos, onde deveria somar um na hora e a diferença ser colocada nos minutos. vou corrigir e posto aqui...

Abraço.
gokden
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 264
Registrado em: Dom, 19 Ago 2007 8:18 pm
Localização: Ribeirão Preto - SP
Lucas de Souza

OCA Developer
Analista de sistemas

eu tenho mais uma duvida pra piorar o caso das horas...

eu preciso fazer a subtração das datas, mais só posso considerar 10horas por dia...

exemplo:
O cara enviou um e-mail para mim ontem as 03:00 da tarde
e eu respondi para ele hj as 03:00 da tarde...
e eu preciso de saber quanto tempo, em horas uteis, eu demorei para responder.... (horas uteis = 08:00 da manha até 18:00 da noite)

isso parece fácil, mais é qui eu tenho mais de 150 e-mail para fazer isso =D
então se alguém pudesse me ajudar com alguma formula para isso =D

Grato...
Ricardo Carmo
Rank: Estagiário Sênior
Rank: Estagiário Sênior
Mensagens: 9
Registrado em: Seg, 25 Fev 2008 3:56 pm
Localização: Maceió-AL

Lucas, acho que no seu caso, você vai precisar de uma tabela indicando os sábados, domingos e feriados, e uma função que retorne a diferença em horas úteis entre duas datas. A função deverá varrer um loop a partir da primeira data até a última, somando as horas úteis de cada dia no loop.

Ex: considere d1 e d2 as datas inicial e final.

-Se d1 e d2 forem do mesmo dia, o número de horas úteis será a diferença entre d1 e d2, ou 0 se d1 e d2 caírem num feriado, sábado ou domingo. Lembre-se de analisar o que fazer se d1 for menor que 08:00 ou d2 for maior que 18:00. Eu consideraria como 0.

-Se d2 for maior que d1, a diferença será:
O número de horas úteis de d1 até as 18:00+
10*o número de dias entre d1 e d2 (ou 0 se d2-d1 for menor que 24h)+
o número de horas úteis de 08:00 até d2.


Agora, é só criar um pacote e escrever uma função que faça isso!!
rogenaro
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Sex, 30 Mar 2007 7:26 pm
Localização: Londrina - PR
Rafael O. Genaro

Já que eu estava meio sem ter o que fazer.. apenas a título de curiosidade, vai aí uma solução usando somente SQL:

Selecionar tudo

create table tab_email
( id_email        number
, dat_recebimento date
, dat_resposta    date
);

ID_EMAIL  DAT_RECEBIMENTO     DAT_RESPOSTA
1          01/02/2008 13:25:31 09/02/2008 04:19:12
2          07/02/2008 13:25:31 22/02/2008 05:02:24
3          05/02/2008 13:25:31 18/02/2008 11:45:36
4	25/02/2008 08:00:00 26/02/2008 12:00:00

Selecionar tudo

-- Obs.: Estarei assumindo que você possui uma tabela de feriados 
-- chamada tab_feriados, onde estão cadastrados a data
-- truncada de cada feriado
select -- Agora ele serve para algo...
       y.id_email
       -- Calcula o número de horas entre os intervalos inicial e final
       -- Lembrando que, se o e-mail foi enviado ou recebido em um fim 
       -- de semana, feriado, ou fora do expediente normal, estas horas
       -- não serão contabilizadas.
     , trunc(sum(y.intervalo_fim - y.intervalo_ini))||' dias '||
       to_char(to_date('00010101', 'yyyymmdd') + sum(y.intervalo_fim - y.intervalo_ini), 'hh24:mi:ss')
       tempo_total
from
(
  select -- A chave da tabela de e-mails ainda está aqui...
         z.id_email
         -- Intervalo anterior retornado em "z"
       , lag (z.intervalo, 1, z.dat_recebimento) over(partition by z.id_email order by z.intervalo) intervalo_ini
         -- Intervalo retornado em "z", exceto para a última linha.
         -- Neste caso, retornamos a própria data de resposta 
         -- (por isso o intervalo arredondava a hora de resposta para cima
         -- gerando uma linha a mais que é aproveitada aqui)
       , decode( lead(z.intervalo) over(partition by z.id_email order by z.intervalo)
               , null, dat_resposta
               , intervalo
               ) intervalo_fim
  from
  (
    select -- Código do e-mail (chave da tabela) para juntar a bagunça toda...
           e2.id_email                                                  
           -- Cada linha irá retornar uma hora após a data de recebimento
           -- do em-mail até a hora posterior à resposta do e-mail
           -- (não estaremos considerando os minutos e segundos)
         , trunc(e2.dat_recebimento + (incremento / 24), 'hh') intervalo
           -- Para uso futuro =)
         , e2.dat_resposta
         , e2.dat_recebimento
    from   tab_email e2
         , ( -- Esta query irá gerar uma seqüência que será somada à hora de
             -- recebimento do e-mail para separarmos cada linha de tab_email
             -- em intervalos de 1 hora.
             select level-1 incremento
             from   dual
             connect by level <= ( -- Recuperar o maior intervalo de datas na tabela,
                                   -- para somar à data inicial e conseqüentemente
                                   -- quebrarmos a data em intervalos de 1 hora.
                                   select max(dat_resposta-dat_recebimento)
                                   from   tab_email
                                 ) * 24 -- 24 horas em um dia...
           ) d
    -- Não considerar intervalos inferiores à data de recebimento
    where  e2.dat_recebimento <= trunc(e2.dat_recebimento + (incremento     / 24), 'hh')
    -- Não considerar intervalos após a data de resposta (arredondada para cima)
    and    e2.dat_resposta    >= trunc(e2.dat_recebimento + ((incremento-1) / 24), 'hh')
  ) z
) y
where  to_char(y.intervalo_ini, 'D')    not in (1,7)     -- Não contar Sábados e Domingos
and    to_char(y.intervalo_ini, 'hh24') between 8 and 18 -- Apenas das 8:00 às 18:00
/*                                                       -- Não considerar feriados
and    trunc(y.intervalo_ini) not in
       ( select dat_feriado
         from   tab_feriados
       )
*/
and    to_char(y.intervalo_fim, 'D')    not in (1,7)     -- Não contar Sábados e Domingos
and    to_char(y.intervalo_fim, 'hh24') between 8 and 18 -- Apenas das 8:00 às 18:00
/*                                                       -- Não considerar feriados
and    trunc(y.intervalo_fim) not in
       ( select dat_feriado
         from   tab_feriados
       )
*/
group by y.id_email

gokden
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 264
Registrado em: Dom, 19 Ago 2007 8:18 pm
Localização: Ribeirão Preto - SP
Lucas de Souza

OCA Developer
Analista de sistemas

:-o :-o
Oia cara.... essa foi boa eim =D
vou testar esse comando, é qui tem qui arruma o nome dos campo e tals...

mais vlww..

Eu pensei em várias possibilidades também
e a mais simples foi essa:

Selecionar tudo

round(Di - Df) = x;

x * (18 - 8) = y;

Hi - 8   = k;
18 - Hf = j;

y - (k + j) = z;

z = Horas uteis =D
ficaria assim:

Selecionar tudo

round(Di - Df) = 2; -- Diferença de dias

2 * 10:00 = 20:00; -- Total de dias * horas uteis

09:00 - 08:00 = 01:00; -- Horas Não trabalhadas
18:00 - 12:00 = 06:00; -- Horas Não trabalhadas

20:00 - (01:00 + 06:00) => 20:00 - 07:00 = 13:00 -- Horas Trabalhadas

Mais desse jeito so funcionaria se
Hf > Hi e
Hf e Hi estejam entre as 08:00 e 18:00 hrs

hehehehehe
Daniela
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 4
Registrado em: Qui, 13 Mar 2008 10:41 am
Localização: São Paulo
Daniela Nunes
"Entrega teu caminho ao Senhor, confia Nele e Ele tudo fará". Salmo 37:5

Olá,

Sou nova no fórum... rsrs.
Estava com problemas com cáculo entre datas e este tópico me ajudou muito.
Necessito encontrar o intervalo entre o primeiro atendimento urgência (FA) o segundo o de internação, ou seja, quanto tempo o paciente fica em observação até ser internado.
O problema é que tenho dois campos um armazena só a data (dt_atendimento) o outro data e hora (hr_atendimento), meu campo hr_atendimento só traz o horário correto a data geralmente difere da dt_atendimento.
Após ler o tópico consegui desenvolver código que traz o intervalo, porém, em alguns casos ele aparece negativo, devido a virada do dia e realmente não sei como alterar isso.

Alguém saberia?

Grata,
Avatar do usuário
TBou
Rank: Analista Sênior
Rank: Analista Sênior
Mensagens: 136
Registrado em: Qui, 05 Ago 2004 9:33 am
Localização: Campo Grande - MS
Thiago Bourscheidt
thiago.info@apoiorural.com.br
Analista de Sistemas

olá´, você pode postar o seu select aqui para nos vermos no que podemos ajudar..?
Daniela
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 4
Registrado em: Qui, 13 Mar 2008 10:41 am
Localização: São Paulo
Daniela Nunes
"Entrega teu caminho ao Senhor, confia Nele e Ele tudo fará". Salmo 37:5

Estou tentando concatenar o campo dt_atendimento com hr_atendimento pra depois fazer o cáculo para encontrar o intervalo...
Mas, esta dando erro de formato inválido.

Selecionar tudo

Select ds_servico,
round(( (m_intervalo) * 86400 / 3600)) ||':' || 
round(mod( (m_intervalo) * 86400 , 3600 ) / 60 ) || ':'|| 
round(mod ( mod ( (m_intervalo) * 86400, 3600 ), 60 ))Intervalo_1
from (       
select  ds_servico, (intervalo/qtd_paciente)m_intervalo
from(
Select servico.ds_servico
,count (paciente.cd_paciente)qtd_paciente
,sum(to_number(to_date(interna.hr_atendimento,'HH24:MI')- to_date(urgen.hr_atendimento,'HH24:MI')))intervalo  
from  dbamv.atendime,
dbamv.paciente,
dbamv.servico,
( select dt_atendimento, 
     to_char(hr_atendimento,'hh24:mm')hr_atendimento,
        cd_paciente,
        cd_atendimento,
        dt_alta,cd_servico
        from  dbamv.atendime
        where atendime.tp_atendimento='I' 
        and   atendime.dt_atendimento between to_date('&dtini','dd/mm/yyyy')and to_date ('&dtfin','dd/mm/yyyy')) interna,
( select dt_atendimento, 
        to_char(hr_atendimento,'hh24:mm')hr_atendimento,
         cd_paciente,
         cd_atendimento,
         dt_alta,cd_servico
        from dbamv.atendime
        where atendime.dt_atendimento between to_date('&dtini','dd/mm/yyyy')and to_date ('&dtfin','dd/mm/yyyy')
        and  atendime.tp_atendimento='U') urgen
where atendime.cd_paciente=paciente.cd_paciente
and   paciente.cd_paciente=urgen.cd_paciente
and   paciente.cd_paciente=interna.cd_paciente
and   atendime.cd_servico=urgen.cd_servico
and   atendime.cd_servico=interna.cd_servico
and   atendime.cd_servico=servico.cd_servico
group by ds_servico
         )  
          group by ds_servico, (intervalo/qtd_paciente)
)
group by ds_servico,M_INTERVALO
rogenaro
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Sex, 30 Mar 2007 7:26 pm
Localização: Londrina - PR
Rafael O. Genaro

Daniela, pelo que você disse, o problema está no fato de que você está considerando apenas a o campo hr_atendimento.
O campo dt_atendimento é do tipo DATE e guarda a data do atendimento, enquanto que o campo hr_atendimento também é do tipo DATE, mas guarda apenas o horário do atendimento, certo?
Aparentemente tanto as horas no campo dt_atendimento quanto o dia no campo hr_atendimento não são gravados corretamente em 100% dos casos, sendo necessário obter a informação completa pelos dois campos. É isso mesmo?

Caso eu tenha entendido corretamente, tente as alterações abaixo:

Selecionar tudo

select ds_servico
     , round(((m_intervalo) * 86400 / 3600)) || ':' 
     ||round( mod( (m_intervalo) * 86400
                , 3600
                ) / 60
            )
     || ':' 
     ||round(mod( mod( (m_intervalo) * 86400
                     , 3600
                     )
                , 60
                )
            ) intervalo_1
from   
(
  select ds_servico
       , (intervalo / qtd_paciente) m_intervalo
  from   
  (
   select servico.ds_servico
        , count(paciente.cd_paciente)   qtd_paciente
        -- Alteração 1
/*
        , sum(to_number( to_date(interna.hr_atendimento,'HH24:MI') 
                       - to_date(urgen.hr_atendimento  ,'HH24:MI')
                       )
             ) intervalo
*/
        , sum( interna.hr_atendimento 
             - urgen.hr_atendimento
             ) intervalo
        -- Fim da alteração 1
   from   dbamv.atendime
        , dbamv.paciente
        , dbamv.servico
        , (select dt_atendimento
                 -- Alteração 2
/*                , to_char( hr_atendimento
                         , 'hh24:mm'
                         ) hr_atendimento
*/                       
                , to_date( to_char(dt_atendimento, 'yyyymmdd')
                         ||to_char(hr_atendimento, 'hh24miss')
                         , 'yyyymmddhh24miss'
                         )
                -- Fim da alteração 2
                , cd_paciente
                , cd_atendimento
                , dt_alta
                , cd_servico
           from   dbamv.atendime
           where  atendime.tp_atendimento = 'I'
           and    atendime.dt_atendimento between to_date('&dtini','dd/mm/yyyy') 
                                          and     to_date('&dtfin','dd/mm/yyyy')
          ) interna
        , (select dt_atendimento
                 -- Alteração 3
/*                , to_char( hr_atendimento
                         , 'hh24:mm'
                         ) hr_atendimento
*/                       
                , to_date( to_char(dt_atendimento, 'yyyymmdd')
                         ||to_char(hr_atendimento, 'hh24miss')
                         , 'yyyymmddhh24miss'
                         )
                -- Fim da alteração 3
                , cd_paciente
                , cd_atendimento
                , dt_alta
                , cd_servico
           from   dbamv.atendime
           where  atendime.dt_atendimento between to_date('&dtini','dd/mm/yyyy') 
                                          and     to_date('&dtfin','dd/mm/yyyy')
           and    atendime.tp_atendimento = 'U'
          ) urgen
   where  atendime.cd_paciente = paciente.cd_paciente
   and    paciente.cd_paciente = urgen.cd_paciente
   and    paciente.cd_paciente = interna.cd_paciente
   and    atendime.cd_servico = urgen.cd_servico
   and    atendime.cd_servico = interna.cd_servico
   and    atendime.cd_servico = servico.cd_servico
   group by ds_servico
  )
  group by ds_servico
         , (intervalo / qtd_paciente)
)
group by ds_servico
        , m_intervalo

Daniela
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 4
Registrado em: Qui, 13 Mar 2008 10:41 am
Localização: São Paulo
Daniela Nunes
"Entrega teu caminho ao Senhor, confia Nele e Ele tudo fará". Salmo 37:5

Olá Rafael,

Com as alterações, passamos a trabalhar com data e hora, perfeito...
Valeu pela força, não estava conseguindo fazer essa junção.
Porém, algumas linhas ainda me apresentam resultado de horas negativas , e esse é o maior problema. Tentei jogar as regras de sinais e modificar o formato da data , mas, não tive sucesso...
rogenaro
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Sex, 30 Mar 2007 7:26 pm
Localização: Londrina - PR
Rafael O. Genaro

Ops... Imaginei que, considerando também a data no momento de subtrair os resultados, o problema das horas negativas iria sumir (pois poderia, em teoria, ocorrer de um atendimento iniciar às 23:30 e terminar à 00:15 do dia seguinte, por exemplo).

Como não resolveu o problema, é provável que por algum motivo a linha

Selecionar tudo

        , sum( interna.hr_atendimento
             - urgen.hr_atendimento
             ) intervalo
esteja causando o problema devido ao horário de atendimento de "urgen" ser maior do que a data e hora retornada em "interna.hr_atendimento"

Para verificar, tente realizar a consulta mais interna e verifique se existe algum problema (seja nos dados da tabela, seja em algum ponto da consulta) que esteja retornando registros com o campo urgen.hr_atendimento maior do que interna.hr_atendimento.

Qualquer coisa, se for necessário (e possível, claro), coloque a estrutura das tabelas envolvidas com alguns dados e o resultado esperado, para ajudar nos testes.[/u]
Daniela
Rank: Estagiário Pleno
Rank: Estagiário Pleno
Mensagens: 4
Registrado em: Qui, 13 Mar 2008 10:41 am
Localização: São Paulo
Daniela Nunes
"Entrega teu caminho ao Senhor, confia Nele e Ele tudo fará". Salmo 37:5

Olá Rafael,

Bom dia, o problema do resultado negativo era o seguinte:
Um paciente pode ter 1 ou mais atendimentos de urgência antes de uma internação e ainda ter mais de uma internação, as condições da consulta traziam todos as urgências e comparavam com a data e hora da internação.

Aí acrecentei a linha "and urgen.dt_alta=interna.dt_atendimento" na clausula Where fazendo com que apenas o atendimento de urgência antes da internação (caso houvesse) fosse subtraído.

:D

Valeu.... boa semana para você...
ruevers
Rank: DBA Sênior
Rank: DBA Sênior
Mensagens: 324
Registrado em: Sex, 02 Jun 2006 1:48 pm
Localização: sp
Contato:

Gente, para de querer complicar as coisas usando procedure pra tudo....
usem select e funções....

Selecionar tudo

SELECT TO_CHAR(SYSDATE + INTERVAL '10' MINUTE, 'HH:MI:SS')
FROM dual;
Nem li todos os posts...mas parece que todas as soluções estão muito complicadas pra ter a diferença de horas de datas....
esse é um caminho....se fuçarem mais isso pode ser resolvido somente em um select.
mateustads
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 2
Registrado em: Sex, 08 Jan 2010 8:24 am
Localização: MS
Mateus Leonardi

Estava tentando fazer mas estou com um breve problema, está indicando um erro, o select é esse:

Selecionar tudo

SELECT TO_CHAR (datahorainicio + INTERVAL tempo MINUTE, 'HH24:mi:ss')
FROM (SELECT datahorainicio,
     TO_CHAR (ROUND (((datahorafim - datahorainicio) * 1440))) AS tempo
     FROM atendimento);
com esse erro :

Selecionar tudo

 "ORA-00907: missing right parenthesis"
victorhugomuniz
Moderador
Moderador
Mensagens: 1396
Registrado em: Sex, 01 Fev 2008 2:06 pm
Localização: Rio de Janeiro - RJ
Contato:
:D

Selecionar tudo

SELECT TO_CHAR ( (datahorainicio + INTERVAL || ''' ||tempo || ''' || MINUTE), 'HH24:mi:ss')
FROM 
(SELECT datahorainicio,
        TO_CHAR ( ROUND (   (   (datahorafim - datahorainicio) * 1440)  )) AS tempo
FROM atendimento); 
mateustads
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 2
Registrado em: Sex, 08 Jan 2010 8:24 am
Localização: MS
Mateus Leonardi

não deu certo esse seu esquema... =X

no fim das contas acabei bolando uma fuction pra isso... curta e funcional... dêem uma olhada.

Selecionar tudo

CREATE OR REPLACE function SEMASA.f_tempo_media ( day_fraction NUMBER)
return char
is

 Years        NUMBER;
 months       NUMBER;
 days         NUMBER;
 hrs          NUMBER;
 mints        NUMBER;
 sec          NUMBER;

begin

 hrs   :=trunc(day_fraction*24);
 mints :=trunc((((day_fraction)*24)-(hrs))*60);
 sec   :=trunc(mod((day_fraction)*86400,60));

 return(LPAD (hrs, 2, '0') ||':'|| LPAD (mints, 2, '0') ||':'|| LPAD (sec, 2, '0'));

end;
/
huntersc
Rank: Programador Júnior
Rank: Programador Júnior
Mensagens: 15
Registrado em: Sex, 12 Mar 2010 3:11 pm
Localização: FLORIANOPOLIS - SC

Caros,

Estava vendo os selects anteriores e não consegui achar um resultado para o meu.

Estou precisando encontrar um horario vago para agendar atendimento.
Minha aplicação existe uma tabela onde tem os horarios Agendados.
Data/Hora inicio (DHPREVISTA) Data/Hora Fim TEMPPRIVISTO.

Ex: Tenho Agendado horarios:
08:00 - 09:00 11:00 - 12:00
Preciso que o select retorne o horario q tem vago das 10 as 11
Tudo isso levando em consideração horario das 8 as 12 das 13:30 as 18:00 somente durante dia de semana e limite entre horarios de 60 minutos.

Agradeço a colaboração.

Obrigado.
priajf
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 297
Registrado em: Ter, 21 Dez 2010 8:45 am
Localização: Florianopolis
Priscila Fernandes

Ok
Peguei essa código

Selecionar tudo

SELECT TO_CHAR ( (datahorainicio + INTERVAL || ''' ||tempo || ''' || MINUTE), 'HH24:mi:ss')
FROM
(SELECT datahorainicio,
        TO_CHAR ( ROUND (   (   (datahorafim - datahorainicio) * 1440)  )) AS tempo
FROM atendimento); 
POrem agora preciso fazer uma pesquisa com horarios que passaram de 12 min. Como faço. tempo nã oexiste na tabela.
SergioLBJr
Rank: Oracle Guru
Rank: Oracle Guru
Mensagens: 448
Registrado em: Ter, 16 Jun 2009 3:07 pm
Localização: Parobé - RS
Sérgio Luiz Bonemberger Junior
Programador Junior
Parobé RS

[]s

Explica melhor a tua situação.

Tu tem uma tabela com hora inicial e final e quer ver o que passou de 12 min??
Victor_Ni
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 2
Registrado em: Qui, 15 Set 2016 10:51 pm

Saudações. há tempos vejo que existem muitos técnicos com a mesma questão, "como calcular o tempo entre duas datas?", somente para recapitular. não se trata de calcular o tempo entre uma data e a data atual (sysdate), pois seria simples utilizando da função timestamp do Oracle.
Sem saber mais detalhes, muito s perguntam: Pra saber o tempo decorrido entre datas?
existem vários motivos. ainda mais para um DBA, Monitoramento de processos seria a resposta mais adequada para esta questão.

Agora na pratica, aguem conseguiu com exatidão criar um script que funcione 100%?

Isto não e um desafio, eu so não quero ser repetitivo em opções de solução.

abraços.
spernega
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Ter, 19 Jun 2007 2:12 pm
Localização: São Paulo - SP

Bom dia Victor,

Tem uma função que eu criei e que está funcionando bem.
Pelo menos até agora não peguei nenhum erro.

Selecionar tudo

create or replace 
function Fn_Intervalo_Tempo (P_Dt_Inic in date,
                             P_Dt_Fina in date) return varchar2 is
 v_inte  number;
 v_Hora  varchar2(200);
 --
 cursor c is
   SELECT lpad(   extract (day    from numtodsinterval(v_inte, 'day'))    ,5,' ') Qt_Dias,
          lpad(   extract (hour   from numtodsinterval(v_inte, 'day'))    ,2,'0') Qt_Horas,
          lpad(   extract (minute from numtodsinterval(v_inte, 'day' ))   ,2,'0') Qt_Minutos,
          lpad(   extract (second from numtodsinterval(v_inte, 'day'))    ,2,'0') Qt_Segundos
   FROM   dual;
 c_r c%rowtype;
 --
begin
 --
 v_inte := trunc((p_dt_Fina - p_dt_Inic),6);
 dbms_output.put_line('v_inte     '||to_char(v_inte));
 --
 open c;
  fetch c into c_r;
   if c%found then
      --
      dbms_output.put_line('c_r.Qt_Dias     '||c_r.Qt_Dias);
      dbms_output.put_line('c_r.Qt_Horas    '||c_r.Qt_Horas);
      dbms_output.put_line('c_r.Qt_Minutos  '||c_r.Qt_Minutos);
      dbms_output.put_line('c_r.Qt_Segundos '||lpad(trunc(c_r.Qt_Segundos),2,'0'));
      --
      v_hora := c_r.Qt_Dias||' '||c_r.Qt_Horas||':'||c_r.Qt_Minutos||':'||lpad(trunc(c_r.Qt_Segundos),2,'0');
   end if;
 close c;
 return v_hora;
exception
 when others then
  return 'erro';
End;
/
Victor_Ni
Rank: Estagiário Júnior
Rank: Estagiário Júnior
Mensagens: 2
Registrado em: Qui, 15 Set 2016 10:51 pm

Boa tarde, spernega.

Sua função ficou boa. mais simples do que a solução que desenvolvi.

vou fazer mais teste nesta sua função.

Obrigado.
spernega
Rank: DBA Pleno
Rank: DBA Pleno
Mensagens: 232
Registrado em: Ter, 19 Jun 2007 2:12 pm
Localização: São Paulo - SP

Boa noite Victor,

Boa sorte, adapte o retorno do jeito que você precisar.

Em horas ou minutos, é só multiplicar as variáveis.
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 5 visitantes