quarta-feira, 11 de dezembro de 2013

Como Somar Datas no MySQL


Abordaremos neste artigo as seguintes funções nativas do MySQL
  • date_add
    Recomendada para adicionar valores a uma data.
  • date_sub
    Recomendada para reduzir valores a uma data.
Sintaxe

DATE_ADD(date,INTERVAL expr unit)
DATE_SUB(date,INTERVAL expr unit)

Definições da Sintaxe
  1. date (Data)
    Argumento base para o calculo, sendo possível informar datas simples ou completas. (Com ou sem horas, minutos e segundos)¹.
  2. interval (Intervalo)
    Palavra chave da sintaxe.
  3. expr (Expressão)
    Argumento da expressão que será utilizada como intervalo da função, possui tipo de dados do tipo string, que pode começar com menos (-) nos casos de subtração².
  4. unit (Unidade)
    Argumento chave que indica qual unidade de "medida" será usado, anos, dias, meses, horas...
Exemplos (Adição)

1. Adicionando um ano sob a data atual.
 select date_add(now(), interval 1 year)  

2. Adicionando um mês sob a data atual
 select date_add(now(), interval 1 month)  

3. Adicionando um dia sob a data atual
 select date_add(now(), interval 1 day)  

4. Adicionando uma hora sob a data atual
 select date_add(now(), interval 1 hour)  

A lista de possibilidades aceitas pelo argumento unit é extensa, veja:
unit ValorEsperado expr Format
MICROSECONDMicrossegundo
SECONDSegundo
MINUTEMinuto
HOURHora
DAYDia
WEEKSemana
MONTHMês
QUARTERTrimestre
YEARAno
SECOND_MICROSECONDSegundo e Microssegundo
MINUTE_MICROSECONDMinuto e Microssegundo
MINUTE_SECONDMinuto e Segundo
HOUR_MICROSECONDHora e Microssegundo
HOUR_SECONDHora e Segundo
HOUR_MINUTEHora e Minuto
DAY_MICROSECONDDia e Microssegundo
DAY_SECONDDia e Segundo
DAY_MINUTEDia e Minuto
DAY_HOURDia e Hora
YEAR_MONTHAno e Mês

Nos exemplos apresentados nós somamos valores a uma data com o uso do now(), mas o curdate() também pode ser utilizado, bem você passar uma data fixa, neste, não se esqueça de colocar as aspas. Agora, se precisa subtrair valores, usamos a função date_sub, vejamos.
Exemplos (Subtração)

1. Subtraindo um ano e um mês sob a data atual.
 select date_sub(now(), interval 1 year_month)  

2. Subtraindo um mês sob a data atual
 select date_sub(now(), interval 1 month)  

3. Subtraindo um dia e uma hora sob a data atual
 select date_sub(now(), interval 1 day_hour)  

4. Subtraindo uma hora e um minuto sob a data atual
 select date_sub(now(), interval 1 hour_minute)  

Caso seja necessário verificar se a data calculada será um dia útil ou não, podemos contar com o apoio da função para verificar dia útil no MySQL.


Perguntas Frequentes

Posso somar uma data com "select data + tempo"?
Não recomendo, desta forma a especificação do tempo será em segundos, e o tipo de dados resultante será um double que certamente extrapolará o calendário, e você também precisará formatar para um formato amigável, pois o resultado é YYYYMMDDHHMMSS. O mesmo resultado é obtido em casos de subtração.

Existem outras funções semelhante ao date_add ou date_sub?
Sim, o addtime/subtime e o adddate/subdate. Nestes podemos encontrar variações na sintaxe.

Caso tenha ficado alguma dúvida, queira dar uma sugestão ou reclamar também (:d), poste nos comentários, terei o maior prazer em responder, um grande abraço.

¹ Ao se informar somente a hora, minuto e segundo serão adicionados ao resultado, todos sob valores zerados.

² Neste caso, recomendo o uso do date_sub.

Referências/Fonte:
Dev MySQL
Imasters
Michelazzo

7 comentários:

  1. Respostas
    1. Olá Almir,

      Obrigado pelo feedback.

      Grande abraço.

      Excluir
  2. estou tentando fazer um sistema para reservas de quarto e precisava do seguinte:

    exemplo: um cliente reserva um quarto tipo 01 para inicio dia 01/05/14 e saida em 04/05/14 (logo 3 dias)

    precisava que quando ele fizesse a reserva, no banco de dados de reserva fossem inseridos da seguinte maneira:

    id_tipo........id_cliente........data
    .....01..........02.................2014-05-01
    .....01..........02.................2014-05-02
    .....01..........02.................2014-05-03

    (pois necessito fazer uma contagem depois para liberar ou não + reservas)

    tem como usar esse comando DATE_ADD?

    []s

    ResponderExcluir
    Respostas
    1. Olá @ocuca,

      Pra fazer o que desejá você terá que fazer um laço de repetição com um while, veja qual a quantidade de dias, pra cada dia identificado, você insere um registro.

      Não sei qual a sua necessidade, mas, como ficaria no caso do hospede antecipar sua saída?

      Vamos nos falando...abraços.

      Excluir
  3. Bom dia,
    Tem como pegar a data que esta em uma coluna da minha tabela?
    Por exemplo to tentando pegar 10 dias antes da data de vencimento dos pagamentos, esse codigo da certo neh? Tenho uma tabela clientes e nela tem uma coluna data_vencimento..Como faço?

    ResponderExcluir
    Respostas
    1. Olá Rafaella.

      Você pode fazer o seguinte:

      select
      *
      from
      clientes
      where date(now()) = date(date_sub(data_vencimento, interval 10 day));

      Explicando...

      No where estou pegando o dia de hoje (date(now())), ai eu subtraio 10 dias da data de vencimento (date(date_sub(data_vencimento, interval 10 day))) comparo com o hoje.

      Em resumo, eu pego os clientes que irão vencer daqui a 10 dias, por isso o uso do SUB, voltando esse vencimento no tempo, ai comparo com o hoje.

      Faça o teste e veja se é isso mesmo. Precisando, estou por aqui pra te ajudar!

      Excluir
  4. Velho, muito obrigado! Me serviu bastante.

    ResponderExcluir