Olá, estou atualizando o post “Calcular Diferença Entre Datas”, usaremos uma função mais simples para calcular diferença entre Anos, Meses, Dias, Horas, Minutos e Segundos.
A função recebe 3 ou 4 parâmetros.
1º Parâmetro é o data inicial
2º Parâmetro é a data final
3º Parâmetro é o que se deseja calcular, ex. Ano, Mes, Dia, Hora, Minuto. Sendo o parâmetro a primeira letra ( ‘A’ = ano, ‘M’ = meses, etc …)
4º Parâmetro é opcional e só precisa ser passado se o separador for diferente de “-” (ex: 2010/04/10 neste caso deve ser passado o separador no parâmetro).
O formato da data deve ser “Ano-Mês-Dia”, ex 2010-12-31, ou seja, $d1 = “2010-12-31″.
<?php
function diffDate($d1, $d2, $type='', $sep='-')
{
$d1 = explode($sep, $d1);
$d2 = explode($sep, $d2);
switch ($type)
{
case 'A':
$X = 31536000;
break;
case 'M':
$X = 2592000;
break;
case 'D':
$X = 86400;
break;
case 'H':
$X = 3600;
break;
case 'MI':
$X = 60;
break;
default:
$X = 1;
}
return floor( ( ( mktime(0, 0, 0, $d2[1], $d2[2], $d2[0]) – mktime(0, 0, 0, $d1[1], $d1[2], $d1[0] ) ) / $X ) );
}
?>
Exemplos de uso:
Calcular diferença entre Dias (3º parâmetro D).
<?php $d1 = "2011-01-01"; $d2 = "2011-01-10"; echo diffDate($d1,$d2,'D'); ?>
Calcular diferença entre Meses (3º parâmetro M).
<?php $d1 = "2011-01-01"; $d2 = "2011-02-01"; echo diffDate($d1,$d2,'M'); ?>
Calcular diferença em Minutos (3º parâmetro MI).
<?php $d1 = "2011-01-01"; $d2 = "2011-02-01"; echo diffDate($d1,$d2,'MI'); ?>
Calcular diferença entre Anos (3º parâmetro A).
<?php $d1 = "2010-01-01"; $d2 = "2011-01-01"; echo diffDate($d1,$d2,'A'); ?>
Calcular diferença em Horas (3º parâmetro H).
<?php $d1 = "2011-01-01"; $d2 = "2011-02-01"; echo diffDate($d1,$d2,'H'); ?>
Calcular diferença em Dias com separador “/” (3º parâmetro D e 4º parâmetro / ).
<?php $d1 = "2011/01/01"; $d2 = "2011/02/01"; echo diffDate($d1,$d2,'D',"/"); ?>
Calcular diferença em Segundos (omitindo o 3º e 4º parâmetro ).
<?php $d1 = "2011-01-01"; $d2 = "2011-02-01"; echo diffDate($d1,$d2); ?>
Boas Rafael,
Que boa função de diferença entre datas ;) tenho de dar uma vista de olhos na que tinha postado aqui á uns tempos .
Mais uma vez um Grande Obrigado pela partilha de conhecimento :)
Aguardo com ansiedade os próximos post PHP + JQuery
Valeu, Bom Ano
Muito bom a função parabéns.
Ótimo função, Rafael!
Não achei função tão boa nem nas “googladas” pelos sites gringos.
Apenas uma colaboração, para manter a sua lógica e a diferença entre as datas não ficar negativa, o return deve ficar assim:
return floor( ( ( mktime(0, 0, 0, $d2[1], $d2[2], $d2[0]) – mktime(0, 0, 0, $d1[1], $d1[2], $d1[0] ) ) / $X ) );
Pois do jeito que você colocou ele está subtraindo a data maior da data menor, então está gerando dias negativos. Nada que tire o brilho da função!
Um abraço!
Márcio, é verdade, muito obrigado pela contribuição, assim fica fácil pra mim hehehehe!
Anteriormente, digo, quando foi escrita a function ao invés de :
diffDate($d1, $d2, $type=”, $sep=’-')
era
diffDate($d2, $d1, $type=”, $sep=’-')
Para mim o correto seria informar primeiro a maior data dia 10 menos dia 05… quando fui postar me apeguei ao fator ordem, achei que confundiria, alterei os params mas não o resto função… que burro dá zero pra ele kas kas kas
Foi mancada minha mesmo…
Valeu,
forte abraço!
Muito bom o post… ajudou bastante.. para simplificar eu já tinha uma função que fazia as conversões para o timestamp
valeu
Show, muito bom…
ÓTIMA A FUNÇÃO
Não sou expert mas presento uma variação que pode ser útil:
Calcula ’2011-05-02 08:00:00′ e ’2011-05-01 09:55:00′
function diffDate($d1, $d2, $type=”, $sep=’-')
{
if(strstr($d1,’:')){
$dh1 = explode(‘ ‘, $d1);
$d1 = explode($sep, $dh1[0]);
$d1_h = explode(‘:’, $dh1[1]);
} else{
$d1 = explode($sep, $d1);
$d1_h[0] = $d1_h[1] = $d1_h[2]= 0;}
if(strstr($d2,’:')){
$dh2 = explode(‘ ‘, $d2);
$d2 = explode($sep, $dh2[0]);
$d2_h = explode(‘:’, $dh2[1]);
} else{
$d2 = explode($sep, $d2);
$d2_h[0] = $d2_h[1] = $d2_h[2]= 0;}
switch ($type)
{
case ‘A’:
$X = 31104000;
break;
case ‘M’:
$X = 2592000;
break;
case ‘D’:
$X = 86400;
break;
case ‘H’:
$X = 3600;
break;
case ‘MI’:
$X = 60;
break;
default:
$X = 1;
}
return (((mktime($d1_h[0],$d1_h[1],$d1_h[2],$d1[1],$d1[2],$d1[0])-mktime($d2_h[0],$d2_h[1],$d2_h[2],$d2[1],$d2[2],$d2[0]))/$X));
}
$d1 = ’2011-05-02 08:00:00′;
$d2 = ’2011-05-01 09:55:00′;
echo diffDate($d1, $d2,’MH’);
Boa Samuel, contribuições são bem-vindas.
Valeu, abraços.
Exclareceu e ao mesmo tempo meu ajudou bastante em um projeto. Parabéns!
Pessoal, tive uma dificuldade e creio que outros também podem ter.
Para somar horas, exemplo: 08:00:00 quero adicionar 01:00:00 hora, podemos usar a seguinte função:
function somaHora($d1, $d2, $sep=’:')
{
$d1_h = explode($sep, $d1);
$d2_h = explode($sep, $d2);
$d1_h[0]+$d2_h[0].’:’.$d1_h[1]+$d2_h[1].’:’.$d1_h[2]+$d2_h[2];
$novo_horario = mktime(((int)$d1_h[0] + (int)$d2_h[0]), ((int)$d1_h[1] + (int)$d2_h[1]), ((int)$d1_h[2] + (int)$d2_h[2]));
return date(“H:i:s”, $novo_horario);
}
Ao somar: echo somaHora(’08:00:00′, ’01:00:00′);
O resultado é: 09:00:00
Ao somar: echo somaHora(’08:00:00′, ’00:35:00′);
O resultado é: 08:35:00
Espero poder ajudar.
Att. Samuel Peixoto
Samuel Peixoto, sensacional, era o que precisava. Fiz um lance de expirar link com isso, perfeito, obrigado.
VALEU GAROTO!
O meu deu o seguinte erro
Parse error: parse error in C:\xampp\…………php on line 27
A linha 27 é bem no return o que pode se ?
Valeuu
Amigo, você postou a linha do erro, é preciso informar o erro para eu poder ajuda-lo.
abs
Olá, Ragael.
Tenho também um problema de erro:
PHP Parse error: syntax error, unexpected T_STRING in testa_data.php on line 28
e a linha 28 do ‘testa_data.php’ é
return floor( ( ( mktime(0, 0, 0, $d2[1], $d2[2], $d2[0]) – mktime(0, 0, 0, $d1[1], $d1[2], $d1[0] ) ) / $X ) );
(copiei e colei seu script em um arquivo que chamei de testa_data.php)
A sintaxe me parece correta. Não vi o erro. Pode me ajudar ?
Desculpe, Rafael.
A pressa sempre é inimiga!!
O que pegou?
Colega Clares pode me elucidar em uma questão?
o sistema cadastra uma data no bd como que eu faço para que 3 dias antes de chegar a essa data cadastrada me exibir uma msg na tela. “Faltam 3 dias para o evento tal” ?
Marcelo tente o seguinte:
if(date(‘d/m/Y’,mktime(0,0,0,date(‘m’),date(‘d’)+3,date(‘Y’))) <= date('d/m/Y'))
{
echo "faltam 3 dias…"
}
onde o +3 é a quantidade de dias (hoje + 3)
outros exemplos
//PARA DESCOBRIR QUAL DATA SERÁ DAQUI A 5 DIAS
echo date('d/m/Y',mktime(0,0,0,date('m'),date('d')+5,date('Y')));
//PARA DESCOBRIR QUAL SERÁ O DIA AMANHÃ
echo date('d/m/Y',mktime(0,0,0,date('m'),date('d')+1,date('Y')));
//PARA MÊS QUE VEM
echo date('d/m/Y',mktime(0,0,0,date('m') + 1,date('d'),date('Y')));
//PARA ANO QUE VEM
echo date('d/m/Y',mktime(0,0,0,date('m'),date('d'),date('Y') + 1));
ERRO NA LINA 27 ???????????????????????????
Que erro?
Ola pessoal. ótima função.
Porem estou com o mesmo problema na linha de return alguém pode ajudar?
Encontrei o erro.
o Sinal de subtração, redigite-o…
vai entender????
Olá Rafael…
Primeiramente, parabéns e obrigado pelo post.
Percebi que esta utilizando:
09 case ‘A’:
10 $X = 31536000;
12 case ‘M’:
13 $X = 2592000;
Portanto, esta supondo que todos os anos que estão sendo comparados possuem 365 dias.
E que todos os meses possuem 30 dias.
O resultado dessa diferença não esta errado, se levarmos em consideração anos bissestos e meses com quantidade de dias diferentes de 30 ?
Estou tentando achar uma função que analíse tudo isso, mas esta difícil de achar.
Abraços.
Pedro, o único mês que tem 1 dia a mais é fevereiro nos anos bisextos, neste caso é preciso verificar se o ano é bisexto antes de definir $X para ano e mês.
Então segue a alteração.
function diffDate($d1, $d2, $type=”, $sep=’-')
{
$d1 = explode($sep, $d1);
$d2 = explode($sep, $d2);
switch ($type)
{
case ‘A’:
$X = 31536000;
if (days_in_month(date(‘D’), date(‘Y’)) == 29)
{
$X = 31536000 + 86400;
}
break;
case ‘M’:
$X = 2592000;
if (days_in_month(date(‘D’), date(‘Y’)) == 29)
{
$X = 2592000 + 86400;
}
break;
case ‘D’:
$X = 86400;
break;
case ‘H’:
$X = 3600;
break;
case ‘MI’:
$X = 60;
break;
default:
$X = 1;
}
return floor(( ( mktime(0, 0, 0, $d2[1], $d2[2], $d2[0]) – mktime(0, 0, 0, $d1[1], $d1[2], $d1[0]) ) / $X));
}
function days_in_month($month, $year)
{
return $month == 2 ? ($year % 4 ? 28 : ($year % 100 ? 29 : ($year % 400 ? 28 : 29))) : (($month – 1) % 7 % 2 ? 30 : 31);
}
?>
Agora você pode testar com:
$d1 = “2012-02-01″;
$d2 = “2012-03-01″;
echo diffDate($d1, $d2, ‘D’);
e
$d1 = “2011-02-01″;
$d2 = “2011-03-01″;
echo diffDate($d1, $d2, ‘D’);
Verá que o resultado de dias será diferente já de 2012 é bisexto.
Abs
Obrigado pelo esclarecimento rafael.
Mais uma ajuda. Eu que não estou entendendo direito, ou estamos assumindo que todos os meses possuem 30 dias? Resolvido no caso de fevereiro. Mas e no caso dos meses com 31 dias?
Abs
Pedro, a idéia é essa que eu te passei, utilizar a function days_in_month() para saber quantos dias tem o mês…
A partir daí acredito que você possa implementar o restante do código.
Por ex: ao receber data_1 e data_2 você pode verificar quantos dias tem nelas utilizando a funcao,… abs
Ok Rafael, obrigado. Abaixo mostro a maneira com que realizarei a comparação entre as datas.
Pessoal, como aprendi conceitos por aqui, deixo o código que finalizei pra que possam aproveitar.
// Aa datas/horas são passadas no formato: “dd/mm/aaaa 00:00:00″ ou apenas “dd/mm/aaaa”
public function getDiferencaEntreDatasHoras( $dataHoraInicial, $dataHoraFinal )
{
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// 1 3 / 0 6 / 1 9 8 6 1 4 : 3 5 : 0 0
$diaI = substr($dataHoraInicial,0,2);
$mesI = substr($dataHoraInicial,3,2);
$anoI = substr($dataHoraInicial,6,4);
$horI = substr($dataHoraInicial,11,8);
$datetime1 = date_create($anoI.”-”.$mesI.”-”.$diaI.$horI);
$diaF = substr($dataHoraFinal,0,2);
$mesF = substr($dataHoraFinal,3,2);
$anoF = substr($dataHoraFinal,6,4);
$horF = substr($dataHoraFinal,11,8);
$datetime2 = date_create($anoF.”-”.$mesF.”-”.$diaF.$horF);
$interval = date_diff($datetime1, $datetime2);
return $interval->format(‘A diferença entre as datas é de: %y anos, %m meses, %d dias, %h horas, %i minutos e %s segundos.’);
}
E reparem que se a data for passada no formato “aaaa-mm-dd” ou “aaaa-mm-dd 00:00:00″, boa parte do código deverá ser inutilizado.
Abs.
A partir da versão 5.3.0 do PHP foi introduzida uma classe para cálculo de datas e tempo, é a DateTime, vale a pena dar uma estudada nela, é bem fácil e tem total suporte a timezone e daylight (horário de verão), como sugestão fica a dica de fazer novo artigo abordando esta classe, seria uma atualização natural deste artigo :-)
Vejam os exemplos de DateTime::diff, talvez ajude
http://www.php.net/manual/en/datetime.diff.php