terça-feira, 26 de julho de 2011

Diferença entre Horas no Mysql

Olá papeiros.


Sabe aquele comandinho sql que quando você houve falar pensa, "haa, moleza", ai quando menos espera, precisa dele e bate aquele branco!
Problema não? Pois então, esta semana passei por esta situação, como resolver? Recorrer ao bom e velho Google.

Pesquisei por "Diferença entre horas no MySQL", o primeiro resultado foi do blog do Júlio Cezar Martini, o comando necessário.

Precisava saber a diferença em horas entre duas datas, com o comando DateDiff não me retornava o valor desejado, até retorna, mas teria que adaptar o código. O Júlio exemplificou o comando TimeDiff, e agora vamos aplica-lo em situações reais.

Em sistema de Estacionamento, necessitamos controlar o tempo em que o veículo ficou estacionado, a entrada ocorreu aos 07:53:45 e a saída às 12:14:39, logo, qual o tempo decorrido?

Select TimeDiff('07:53:45','12:14:39')

O tempo decorrido foi de -04:20-54, o menos apresentado é porque o menor resultado foi colocado no primeiro parâmetro.

A função TimeDiff pode receber um parâmetro no formato HH:MM:SS ou YYYY-MM-DD HH:MM:SS.

Esta função é muito útil em sistemas de controle de ponto, estacionamento e em várias outras situações onde necessita-se saber a diferença entre horas.

A documentação completa da função pode ser obtida em: http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_timediff

Abraços e até a próxima papeiros.

13 comentários:

  1. Amigo e para eu trabalhar de forma onde o sistema identifica se em um determinado prazo existe um horario marcado, tipo o seguinte, tenho um cliente agendado para 10/10/2015 as 15h até as 10/10/2015 as 16:40h como poderia montar uma consulta para que ele encontre nesse meio tempo que esse horário já existe marcado? Poderia dar uma força? e-mail: jeferson@techmach.com.br

    ResponderExcluir
    Respostas
    1. Olá Jeferson.

      Você pode criar uma função para verificar a agenda, nesta função você pode passar o horário inicial e final, e com um between você verifica se existem registros no intervalo passado.

      Ex: select * from reserva
      where dt_reserva between '2015-04-08 15:00:00' and '2015-04-08 16:40:00';

      Montei um exemplo mais completo aqui: http://sqlfiddle.com/#!9/c157f/3

      Caso tenha alguma dúvida ainda, estou à sua disposição.

      Excluir
  2. Fabiano perfeito amigão, acabou as dúvidas e foi rapidinho, po me quebrou uma arvore amigo... Obrigado mesmo.

    ResponderExcluir
  3. Cara deixa eu fazer um adendo eu tenho dois campos no banco de dados, um campo de data e hora inicial e outro de data e hora final, uso da mesma forma no exemplo em que você colocou eu vou usar dois between um pra hora inicial e outro para a hora final ?

    ResponderExcluir
    Respostas
    1. Jeferson, você pode concatenar a data com a hora, formando um datetime, ai você tem um único campo de início e fim, ou você pode colocar o between em um or:

      Ex: select * from reserva
      where ((dt_reserva between '2015-04-08 15:00:00' and '2015-04-08 16:40:00')
      or (dt_reserva between '2015-04-08 17:00:00' and '2015-04-08 19:00:00'))

      Com o OR você pode adaptar os campos de data e hora que tem separado também.

      Excluir
    2. Fabiano arrumei uma outra forma de fazer aqui que acredito que de certo também. Vou montar a lógica abaixo e veja se assim também dá certo. Da outra forma está um pouco bagunçado para passar os parâmetros.

      select * from agendar where ag_horaini >= 2015-03-24 15:00:00 ag_horafim <= 2015-03-24 16:00:00

      dessa forma ele pega o que for igual ou maior que a data inicial e pega o que for igual ou menor que a data final. Acho que dessa forma dá certo també não dá não? veja se foi válida...

      Excluir
    3. Jeferson, é a mesma forma de escrita do between, funcionará também. No exemplo só faltou um and entre as verificações:

      select * from agendar where ag_horaini >= '2015-03-24 15:00:00' and ag_horafim <= '2015-03-24 16:00:00'

      Excluir
  4. Realmente havia faltado o and, mas acredito que ainda não vai dar certo assim, fiz um teste aqui e o problema é o seguinte, se eu tenho a seguinte consulta 03/03/2015 as 15:30h até as 16:00h agendado blz agora se na hora de eu marcar eu colocar 15:31h ele não mostra nada no banco assim permitindo com que eu marque esse horário. Preciso na realidade que ele verifique o período entre 15:30h até 16:00 e não me deixe marcar nessa data e nesse espaço de tempo entendeu? rsrsrsrs To achando que complicou um pouco agora...rsrsrsr

    ResponderExcluir
  5. Fabiano nesse exemplo que passou, vou colocar logo abaixo, como eu faria para ele filtrar junto o funcionário da empresa, tipo color para alem de ver a data também checar aquele funcionário.

    Ex: select * from reserva
    where ((dt_reserva between '2015-04-08 15:00:00' and '2015-04-08 16:40:00')
    or (dt_reserva between '2015-04-08 17:00:00' and '2015-04-08 19:00:00'))

    eu teria que colocar depois do Where tipo AG_funcionario and aqui continuar o código? Agora fiquei meio perdido para agregar tudo, ou colocaria o OR e coloco o funcionário?

    ResponderExcluir
  6. Olá Fabiano consegui resolver o problema e vou deixar a solução aqui pro pessoal, lembrando que esse SQL está com parâmetros montado para delphi. Onde estão os :nome você muda isso pela sua variável. Valeu

    select * from agendar
    where ((ag_horaini between :dtini and :dtfim)
    or (ag_horafim between :dtini and :dtfim)) and ag_profid = :func

    ResponderExcluir
  7. Olá Jerferson.

    Fico feliz por saber que você conseguiu resolver o problema.

    Precisando, só falar. Sucesso amigo.

    ResponderExcluir
  8. Prezado,

    Vou repetir a dúvida, acho que deu erro ao postar.

    Tenho os campos hora_inicial e hora_final ; Formato DATE . Agora se eu precisar achar a diferença de tempo de horários que ultrapassem pro dia seguinte, exemplo:

    hora_inicial: 19:00:00
    hora_final: 02:00:00

    Seria melhor mudar o formato do campo ou seria possivel esta subtração?

    Obrigado!!!!!

    ResponderExcluir
    Respostas
    1. Olá Cleber.

      Eu sugiro você alterar o tipo de dado do campo, desta forma, é mais seguro e fácil de se fazer o calculo.

      Excluir