Acho que retornar um número negativo de dias fornece informações relevantes. E você deve estar usando $your_date-$now, se desejar que uma data futura retorne um número inteiro positivo.
Tim
23
E quanto aos segundos bissextos? Nem todos os dias têm exatamente 24 * 60 * 60 segundos. Esse código pode ser suficiente para fins práticos, mas não é exato em alguns casos extremos extremamente raros.
Benjamin Brizzi
49
Esqueça os segundos bissextos (não, considere-os também), mas isso NÃO leva em consideração as alterações do horário de verão! Pode ser desligado por um dia inteiro acima desses limites todos os anos. Você precisa usar as classes DateTime.
Levi
6
@billynoah Desculpe, eu nunca voltei para atualizar meu comentário. Você precisa ter cuidado com o fuso horário de verão. Se você comparar uma data com o horário de verão novamente com uma data sem ela, em vez de, por exemplo, retornar 7 dias, retornará 6,9 dias. Com a palavra retorna 6 em vez de 7.
Alex Angelico
4
Não só o strtotime () falha em 20 anos, é inutilizável no momento. O OP especificou Datas, não Hora. As datas podem ser bastante antigas. Aqui está uma resposta mais simples: $ NumberDays = gregoriantojd ($ EndM, $ EndD, $ EndY) - gregoriantojd ($ StartM, $ StartD, $ StartY); (para um intervalo inclusivo). Diferente da classe Datetime, de Gregoriano a Juliano está disponível na v4 up. O intervalo válido é de 4714 aC a 9999 dC Cuidado com a ordem dos parâmetros do funky (como você precisa desse aviso para php).
Guy Gordon
524
Se você estiver usando PHP 5.3 >, esta é de longe a maneira mais precisa de calcular a diferença:
Observe que, como estamos falando de intervalos de tempo e não de pontos específicos no tempo, a sintaxe do formato é diferente da sintaxe date () e strftime (). A sintaxe do intervalo de tempo pode ser encontrada aqui: php.net/manual/en/dateinterval.format.php
Andrew
1
ou, no meu caso, o número de dias entre é $ date2-> diff ($ date1) -> formato ("% a") - 1
xeo
13
Lembre-se de que, se você tiver horários em suas datas, isso não funcionará conforme o esperado. Por exemplo, se você tem um intervalo de 23:30 horas ... e eles são em dias diferentes, a diferença será 0.
Layke
20
Se você precisar de um número relativo de dias (negativo quando $date1for anterior a $date2), use-o $diff = $date2->diff($date1)->format("%r%a");.
Socce
1
Qual é o formato da data em DateTime("2010-07-06")?, É Y-m-dou Y-d-m?, Qual é o formato do DateTimeparâmetro. qual é o dia?
Sim, isso parece melhor do que a resposta aceita, o que não funciona em alguns casos. Como: $ from = '2014-03-01'; $ to = '31-03-2014';
MBozic 30/05
1
Eu concordo, tão fácil de seguir e funciona muito bem !!! Apenas não se esqueça de usar a função date_default_timezone_set () ou ela fornecerá resultados estranhos com base no horário UTC.
Zeckdude 23/04
2
Esta função falhou em 0 dos 14603 testes entre 1980 e 2020. #
LSerni
128
Converta suas datas em timestamps unix e subtraia uma da outra. Isso fornecerá a diferença em segundos, dividida por 86400 (quantidade de segundos em um dia) para fornecer uma quantidade aproximada de dias nesse intervalo.
Se as datas estão no formato 25.1.2010, 01/25/2010ou 2010-01-25, você pode usar a strtotimefunção:
O uso ceilarredonda a quantidade de dias até o próximo dia inteiro. Use em floorvez disso, se desejar obter a quantidade de dias completos entre essas duas datas.
Se suas datas já estiverem no formato de carimbo de data e hora unix, você pode pular a conversão e apenas fazer a $days_betweenparte. Para formatos de data mais exóticos, talvez você precise fazer uma análise personalizada para fazer a correção.
Deixe-me elaborar: digamos que nesta manhã às 3 da manhã, quase toda a Europa atrasou o relógio uma hora. Isso significa que hoje tem 3600 segundos extras e isso deve ser refletido nos registros de data e hora do UNIX. Se for, isso significa que hoje contará dois dias com a maneira acima de calcular o número de dias. E eu nem estou começando alguns segundos depois que nem o PHP nem o UNIX parecem dar conta deles (o que é realmente IMO compreensível). TL; DR: nem todos os dias têm 86.400 segundos de duração .
precisa saber é o seguinte
2
@ toon81 NÃO existem mais 3600 segundos para essa data. Nada acontece com o registro de data e hora do UNIX ao ir para ou a partir do horário de verão.
nickdnk
1
Se nada acontecer com o registro de data e hora do UNIX, você concorda comigo: a diferença entre o registro de data e hora do UNIX às 13:00 $daye o registro de data e hora do UNIX às 13:00 $day+1nem sempre é de 86400 segundos nos fusos horários que observam o horário de verão. Pode ser de 23 ou 25 horas em segundos, em vez de 24 horas.
toon81
112
TL; DR que não usar timestamps UNIX. Não usetime() . Se o fizer, esteja preparado caso sua confiabilidade de 98,0825% falhe. Use DateTime (ou carbono).
A resposta correta é a dada por Saksham Gupta (outras respostas também estão corretas):
/**
* Number of days between two dates.
*
* @param date $dt1 First date
* @param date $dt2 Second date
* @return int
*/function daysBetween($dt1, $dt2){return date_diff(
date_create($dt2),
date_create($dt1))->format('%a');}
Com uma ressalva: o '% a' parece indicar o número absoluto de dias. Se você deseja que ele seja um número inteiro assinado, ou seja, negativo quando a segunda data for anterior à primeira, será necessário usar o prefixo '% r' (ou seja format('%r%a')).
Se você realmente precisar usar os carimbos de data e hora do UNIX, defina o fuso horário como GMT para evitar a maioria das armadilhas detalhadas abaixo.
Resposta longa: por que dividir por 24 * 60 * 60 (aka 86400) é inseguro
A maioria das respostas que usam registros de data e hora do UNIX (e 86400 para convertê-los em dias) faz duas suposições que, juntas, podem levar a cenários com resultados incorretos e bugs sutis que podem ser difíceis de rastrear e podem surgir mesmo dias, semanas ou meses após uma implantação bem-sucedida. Não é que a solução não funcione - ela funciona. Hoje. Mas pode parar de funcionar amanhã.
O primeiro erro é não considerar que, quando perguntado "Quantos dias se passaram desde ontem?", Um computador pode responder com zero a verdade se entre o presente e o instante indicado por "ontem" tiver passado menos de um dia inteiro .
Normalmente, ao converter um "dia" em um registro de data e hora do UNIX, o que é obtido é o registro de data e hora da meia - noite desse dia específico.
Assim, entre a meia-noite de 1º e 15 de outubro, quinze dias se passaram. Porém, entre as 13:00 de 1º de outubro e as 14:55 de 15 de outubro, quinze dias menos 5 minutos se passaram e a maioria das soluções que usam floor()ou realizam conversão implícita de número inteiro relatará um dia menos do que o esperado .
Então, "há quantos dias Ymd H: i: s"? produzirá a resposta errada .
O segundo erro é equiparar um dia a 86400 segundos. Isso quase sempre é verdade - acontece com frequência suficiente para ignorar os momentos em que não acontece. Mas a distância em segundos entre duas noites consecutivas certamente não é 86400 pelo menos duas vezes por ano, quando o horário de verão entra em jogo. A comparação de duas datas em um limite do horário de verão produzirá a resposta errada.
Portanto, mesmo se você usar o "hack" de forçar todos os registros de data e hora para uma hora fixa, diga meia-noite (isso também é feito implicitamente por vários idiomas e estruturas quando você especifica apenas dia-mês-ano e não também hora-minuto-segundo; O mesmo acontece com o tipo DATE em bancos de dados como o MySQL), a fórmula amplamente usada
retornará, digamos, 17 quando DATE1 e DATE2 estiverem no mesmo segmento de horário de verão do ano; mas pode retornar 17.042 e, pior ainda, 16.958. O uso de floor () ou qualquer truncamento implícito em número inteiro converterá o que deveria ter sido um 17 em um 16. Em outras circunstâncias, expressões como "$ days> 17" retornarão truepara 17.042, mesmo que isso indique que a contagem de dias decorridos tem 18 anos
E as coisas ficam ainda mais feias, pois esse código não é portátil entre plataformas, porque algumas delas podem aplicar segundos bissextos e outras não . Pelos plataformas que fazer , a diferença entre duas datas não será 86400, mas 86401, ou talvez 86399. Assim código que trabalhou em maio e realmente passou todos os testes vai quebrar em Junho próximo, quando 12.99999 dias são considerados 12 dias em vez de 13. Duas datas que trabalhou em 2015 não funcionará em 2017 - nas mesmas datas e nenhum ano é bissexto. Mas entre 01/03/2018 e 01/03/2017, nessas plataformas que se importam, 366 dias terão passado em vez de 365, tornando 2018 um ano bissexto (o que não é).
Portanto, se você realmente deseja usar registros de data e hora do UNIX:
use a round()função sabiamente, não floor().
Como alternativa, não calcule as diferenças entre D1-M1-AAAA1 e D2-M2-AAAA2. Essas datas serão realmente consideradas como D1-M1-AAA1 00:00:00 e D2-M2-AAA2 00:00:00. Em vez disso, converta entre D1-M1-AAAA1 22:30:00 e D2-M2-AAA2 04:30:00. Você sempre terá um restante de cerca de vinte horas. Isso pode se tornar vinte e uma horas ou dezenove e talvez dezoito horas, cinquenta e nove minutos e trinta e seis segundos. Não importa. É uma grande margem que permanecerá lá e permanecerá positiva no futuro próximo. Agora você pode truncá-lo com floor()segurança.
A solução correta , porém, para evitar constantes mágicas, arredondar kludges e uma dívida de manutenção, é
use uma biblioteca de tempo (Datetime, Carbon, qualquer que seja); não role sozinho
escreva casos de teste abrangentes usando opções de datas realmente ruins - através dos limites do horário de verão, nos anos bissextos, nos segundos bissextos e assim por diante, além de datas comuns. Idealmente (as chamadas para data e hora são rápidas !) Geram quatro anos inteiros (e um dia) de datas, montando-os a partir de seqüências de caracteres, sequencialmente, e assegurando que a diferença entre o primeiro dia e o dia sendo testado aumente constantemente em um. Isso garantirá que, se alguma coisa mudar nas rotinas de baixo nível e nas correções de segundos bissextos, tentar causar estragos, pelo menos você saberá .
execute esses testes regularmente junto com o restante do conjunto de testes. São uma questão de milissegundos e podem economizar literalmente horas de coçar a cabeça.
Seja qual for a sua solução, teste-a!
A função funcdiffabaixo implementa uma das soluções (por acaso, a aceita) em um cenário do mundo real.
<?php
$tz ='Europe/Rome';
$yearFrom =1980;
$yearTo =2020;
$verbose =false;function funcdiff($date2, $date1){
$now = strtotime($date2);
$your_date = strtotime($date1);
$datediff = $now - $your_date;return floor($datediff /(60*60*24));}########################################
date_default_timezone_set($tz);
$failures =0;
$tests =0;
$dom = array (0,31,28,31,30,31,30,31,31,30,31,30,31);(array_sum($dom)===365)||die("Thirty days hath September...");
$last = array();for($year = $yearFrom; $year < $yearTo; $year++){
$dom[2]=28;// Apply leap year rules.if($year %4===0){ $dom[2]=29;}if($year %100===0){ $dom[2]=28;}if($year %400===0){ $dom[2]=29;}for($month =1; $month <=12; $month ++){for($day =1; $day <= $dom[$month]; $day++){
$date = sprintf("%04d-%02d-%02d", $year, $month, $day);if(count($last)===7){
$tests ++;
$diff = funcdiff($date, $test = array_shift($last));if((double)$diff !==(double)7){
$failures ++;if($verbose){print"There seem to be {$diff} days between {$date} and {$test}\n";}}}
$last[]= $date;}}}print"This function failed {$failures} of its {$tests} tests between {$yearFrom} and {$yearTo}.\n";
O resultado é,
Thisfunction failed 280of its 14603 tests
Horror Story: o custo de "economizar tempo"
Isso realmente aconteceu alguns meses atrás. Um programador engenhoso decidiu economizar vários microssegundos em um cálculo que demorava cerca de trinta segundos, inserindo o código infame "(MidnightOfDateB-MidnightOfDateA) / 86400" em vários lugares. Era uma otimização tão óbvia que ele nem sequer a documentou, e a otimização passou nos testes de integração e se escondeu no código por vários meses, tudo despercebido.
Isso aconteceu em um programa que calcula os salários de vários vendedores mais vendidos, o menor dos quais tem muito mais influência do que uma humilde equipe de programadores, composta por cinco pessoas. Um dia, alguns meses atrás, por razões que pouco importam, o bug ocorreu - e alguns desses caras foram enganados por um dia inteiro de comissões gordas. Eles definitivamente não eram divertiram.
Infinitamente pior, eles perderam a (já muito pouca) fé que tinham no programa, não sendo projetados para fustigá-los clandestinamente e fingiram - e obtiveram - uma revisão completa e detalhada do código com casos de teste executados e comentados em termos de leigos (mais muito tratamento com tapete vermelho nas semanas seguintes).
O que posso dizer: do lado positivo, nos livramos de muitas dívidas técnicas e fomos capazes de reescrever e refatorar várias partes de uma bagunça de espaguete que causou uma infestação de COBOL nos anos 90. Sem dúvida, o programa roda melhor agora, e há muito mais informações de depuração para se concentrar rapidamente quando algo parece suspeito. Estimo que apenas essa última coisa poupará talvez um ou dois homens-dia por mês no futuro próximo.
No lado negativo, todo o dinheiro custou à empresa cerca de € 200.000 na frente - mais a face, além de indubitavelmente algum poder de barganha (e, portanto, ainda mais dinheiro).
O responsável pela "otimização" havia mudado de emprego há um ano, antes do desastre, mas ainda havia conversas para processá-lo por danos. E não foi bem com os escalões superiores o fato de ter sido "a culpa do último cara" - parecia uma armação para resolvermos o problema e, no final, ainda estamos na casa de cachorro e uma equipe está planejando sair.
Noventa e nove vezes em cem, o "86400 hack" funcionará perfeitamente. (Por exemplo, em PHP, strtotime()ignorará o horário de verão e informará que entre a meia-noite do último sábado de outubro e a segunda-feira seguinte, exatamente 2 * 24 * 60 * 60 segundos se passaram, mesmo que isso não seja verdade. ... e dois erros alegremente farão um certo).
Senhoras e Senhores Deputados, este foi um caso em que não aconteceu. Como nos airbags e cintos de segurança, talvez você nunca precise realmente da complexidade (e facilidade de uso) de DateTimeou Carbon. Mas o dia em que você poderá (ou o dia em que terá que provar que pensou sobre isso) virá como um ladrão durante a noite. Esteja preparado.
Quando vi essas respostas, pensei que sou estúpido e louco porque sempre uso o DateTime, mas você me fez entender que usar o DateTime é o caminho certo. Obrigado
Syncro
Ei, todo mundo aqui, no SO, chegou aqui pesquisando no google days between two days in phpou similar, só porque a vida é muito curta para escrever tudo sozinho.
Denis Matafonov 28/12/19
1
explicação detalhada. + 1
Anant Singh --- Alive to Die
1
Às vezes eu gostaria que pudéssemos favoritar as respostas em vez da pergunta.
Essa é uma boa maneira processual de fazer isso usando a classe DateTime. Falta apenas um uso claro do objeto de intervalo ( $diffvariável neste caso). Algo como if ($diff->days > 30) { [doyourstuff]; }
Comentário muito antigo acima, mas está incorreto. O StackOverflow permite que você responda sua própria pergunta (mesmo quando você faz sua pergunta). Responder a você mesmo depois que alguém já postou a mesma solução é, no entanto, considerado rude.
Maarten Bodewes
Esta função falhou 560 de seus testes 14603 entre 1980 e 2020. #
LSerni
10
Bem, a resposta selecionada não é a mais correta porque falhará fora do UTC. Dependendo do fuso horário ( lista ), pode haver ajustes de tempo criando dias "sem" 24 horas, e isso fará com que o cálculo (60 * 60 * 24) falhe.
Aqui está um exemplo disso:
date_default_timezone_set('europe/lisbon');
$time1 = strtotime('2016-03-27');
$time2 = strtotime('2016-03-29');
echo floor(($time2-$time1)/(60*60*24));^-- the output will be **1**
Portanto, a solução correta estará usando DateTime
date_default_timezone_set('europe/lisbon');
$date1 =newDateTime("2016-03-27");
$date2 =newDateTime("2016-03-29");
echo $date2->diff($date1)->format("%a");^-- the output will be **2**
function dateDiff($date1, $date2)//days find function{
$diff = strtotime($date2)- strtotime($date1);return abs(round($diff /86400));}//start day
$date1 ="11-10-2018";// end day
$date2 ="31-10-2018";// call the days find fun store to variable
$dateDiff = dateDiff($date1, $date2);
echo "Difference between two dates: ". $dateDiff ." Days ";
Com perguntas mais antigas que têm respostas existentes, é útil explicar que novo aspecto sua resposta traz para a pergunta. Se relevante, também é útil reconhecer quaisquer alterações que possam ter ocorrido desde que a pergunta foi feita.
// Change this to the day in the future
$day =15;// Change this to the month in the future
$month =11;// Change this to the year in the future
$year =2012;// $days is the number of days between now and the date in the future
$days =(int)((mktime (0,0,0,$month,$day,$year)- time(void))/86400);
echo "There are $days days until $day/$month/$year";
Bem-vindo ao SO! Quando você responder a uma postagem com apenas código, explique-a um pouco. O código que você traz é calculado entre 2019-11-10 e 2019-11-25. Portanto, não está respondendo à pergunta. É por isso que é bom explicar melhor o seu POV do que receber votos negativos.
David García Bodego 25/11/19
0
Se você estiver usando o MySql
function daysSince($date, $date2){
$q ="SELECT DATEDIFF('$date','$date2') AS days;";
$result = execQ($q);
$row = mysql_fetch_array($result,MYSQL_BOTH);return($row[0]);
Em geral, eu uso 'DateTime' para encontrar dias entre 2 datas. Mas se, por algum motivo, alguma configuração do servidor não tiver o 'DateTime' ativado, ele usará um cálculo simples (mas não seguro) com o 'strtotime ()'.
(new DateTime("2010-01-11"))->diff(new DateTime("2019-08-19"))->days;
Respostas:
fonte
$your_date-$now
, se desejar que uma data futura retorne um número inteiro positivo.Se você estiver usando
PHP 5.3 >
, esta é de longe a maneira mais precisa de calcular a diferença:fonte
$date1
for anterior a$date2
), use-o$diff = $date2->diff($date1)->format("%r%a");
.DateTime("2010-07-06")
?, ÉY-m-d
ouY-d-m
?, Qual é o formato doDateTime
parâmetro. qual é o dia?A partir da versão 5.3 do PHP, novas funções de data / hora foram adicionadas para obter a diferença:
Resultado como abaixo:
Espero que ajude !
fonte
Converta suas datas em timestamps unix e subtraia uma da outra. Isso fornecerá a diferença em segundos, dividida por 86400 (quantidade de segundos em um dia) para fornecer uma quantidade aproximada de dias nesse intervalo.
Se as datas estão no formato
25.1.2010
,01/25/2010
ou2010-01-25
, você pode usar astrtotime
função:O uso
ceil
arredonda a quantidade de dias até o próximo dia inteiro. Use emfloor
vez disso, se desejar obter a quantidade de dias completos entre essas duas datas.Se suas datas já estiverem no formato de carimbo de data e hora unix, você pode pular a conversão e apenas fazer a
$days_between
parte. Para formatos de data mais exóticos, talvez você precise fazer uma análise personalizada para fazer a correção.fonte
$day
e o registro de data e hora do UNIX às 13:00$day+1
nem sempre é de 86400 segundos nos fusos horários que observam o horário de verão. Pode ser de 23 ou 25 horas em segundos, em vez de 24 horas.TL; DR que não usar timestamps UNIX. Não use
time()
. Se o fizer, esteja preparado caso sua confiabilidade de 98,0825% falhe. Use DateTime (ou carbono).A resposta correta é a dada por Saksham Gupta (outras respostas também estão corretas):
Ou processualmente como uma linha:
Com uma ressalva: o '% a' parece indicar o número absoluto de dias. Se você deseja que ele seja um número inteiro assinado, ou seja, negativo quando a segunda data for anterior à primeira, será necessário usar o prefixo '% r' (ou seja
format('%r%a')
).Se você realmente precisar usar os carimbos de data e hora do UNIX, defina o fuso horário como GMT para evitar a maioria das armadilhas detalhadas abaixo.
Resposta longa: por que dividir por 24 * 60 * 60 (aka 86400) é inseguro
A maioria das respostas que usam registros de data e hora do UNIX (e 86400 para convertê-los em dias) faz duas suposições que, juntas, podem levar a cenários com resultados incorretos e bugs sutis que podem ser difíceis de rastrear e podem surgir mesmo dias, semanas ou meses após uma implantação bem-sucedida. Não é que a solução não funcione - ela funciona. Hoje. Mas pode parar de funcionar amanhã.
O primeiro erro é não considerar que, quando perguntado "Quantos dias se passaram desde ontem?", Um computador pode responder com zero a verdade se entre o presente e o instante indicado por "ontem" tiver passado menos de um dia inteiro .
Normalmente, ao converter um "dia" em um registro de data e hora do UNIX, o que é obtido é o registro de data e hora da meia - noite desse dia específico.
Assim, entre a meia-noite de 1º e 15 de outubro, quinze dias se passaram. Porém, entre as 13:00 de 1º de outubro e as 14:55 de 15 de outubro, quinze dias menos 5 minutos se passaram e a maioria das soluções que usam
floor()
ou realizam conversão implícita de número inteiro relatará um dia menos do que o esperado .Então, "há quantos dias Ymd H: i: s"? produzirá a resposta errada .
O segundo erro é equiparar um dia a 86400 segundos. Isso quase sempre é verdade - acontece com frequência suficiente para ignorar os momentos em que não acontece. Mas a distância em segundos entre duas noites consecutivas certamente não é 86400 pelo menos duas vezes por ano, quando o horário de verão entra em jogo. A comparação de duas datas em um limite do horário de verão produzirá a resposta errada.
Portanto, mesmo se você usar o "hack" de forçar todos os registros de data e hora para uma hora fixa, diga meia-noite (isso também é feito implicitamente por vários idiomas e estruturas quando você especifica apenas dia-mês-ano e não também hora-minuto-segundo; O mesmo acontece com o tipo DATE em bancos de dados como o MySQL), a fórmula amplamente usada
ou
retornará, digamos, 17 quando DATE1 e DATE2 estiverem no mesmo segmento de horário de verão do ano; mas pode retornar 17.042 e, pior ainda, 16.958. O uso de floor () ou qualquer truncamento implícito em número inteiro converterá o que deveria ter sido um 17 em um 16. Em outras circunstâncias, expressões como "$ days> 17" retornarão
true
para 17.042, mesmo que isso indique que a contagem de dias decorridos tem 18 anosE as coisas ficam ainda mais feias, pois esse código não é portátil entre plataformas, porque algumas delas podem aplicar segundos bissextos e outras não . Pelos plataformas que fazer , a diferença entre duas datas não será 86400, mas 86401, ou talvez 86399. Assim código que trabalhou em maio e realmente passou todos os testes vai quebrar em Junho próximo, quando 12.99999 dias são considerados 12 dias em vez de 13. Duas datas que trabalhou em 2015 não funcionará em 2017 - nas mesmas datas e nenhum ano é bissexto. Mas entre 01/03/2018 e 01/03/2017, nessas plataformas que se importam, 366 dias terão passado em vez de 365, tornando 2018 um ano bissexto (o que não é).
Portanto, se você realmente deseja usar registros de data e hora do UNIX:
use a
round()
função sabiamente, nãofloor()
.Como alternativa, não calcule as diferenças entre D1-M1-AAAA1 e D2-M2-AAAA2. Essas datas serão realmente consideradas como D1-M1-AAA1 00:00:00 e D2-M2-AAA2 00:00:00. Em vez disso, converta entre D1-M1-AAAA1 22:30:00 e D2-M2-AAA2 04:30:00. Você sempre terá um restante de cerca de vinte horas. Isso pode se tornar vinte e uma horas ou dezenove e talvez dezoito horas, cinquenta e nove minutos e trinta e seis segundos. Não importa. É uma grande margem que permanecerá lá e permanecerá positiva no futuro próximo. Agora você pode truncá-lo com
floor()
segurança.A solução correta , porém, para evitar constantes mágicas, arredondar kludges e uma dívida de manutenção, é
use uma biblioteca de tempo (Datetime, Carbon, qualquer que seja); não role sozinho
escreva casos de teste abrangentes usando opções de datas realmente ruins - através dos limites do horário de verão, nos anos bissextos, nos segundos bissextos e assim por diante, além de datas comuns. Idealmente (as chamadas para data e hora são rápidas !) Geram quatro anos inteiros (e um dia) de datas, montando-os a partir de seqüências de caracteres, sequencialmente, e assegurando que a diferença entre o primeiro dia e o dia sendo testado aumente constantemente em um. Isso garantirá que, se alguma coisa mudar nas rotinas de baixo nível e nas correções de segundos bissextos, tentar causar estragos, pelo menos você saberá .
execute esses testes regularmente junto com o restante do conjunto de testes. São uma questão de milissegundos e podem economizar literalmente horas de coçar a cabeça.
Seja qual for a sua solução, teste-a!
A função
funcdiff
abaixo implementa uma das soluções (por acaso, a aceita) em um cenário do mundo real.O resultado é,
Horror Story: o custo de "economizar tempo"
Isso realmente aconteceu alguns meses atrás. Um programador engenhoso decidiu economizar vários microssegundos em um cálculo que demorava cerca de trinta segundos, inserindo o código infame "(MidnightOfDateB-MidnightOfDateA) / 86400" em vários lugares. Era uma otimização tão óbvia que ele nem sequer a documentou, e a otimização passou nos testes de integração e se escondeu no código por vários meses, tudo despercebido.
Isso aconteceu em um programa que calcula os salários de vários vendedores mais vendidos, o menor dos quais tem muito mais influência do que uma humilde equipe de programadores, composta por cinco pessoas. Um dia, alguns meses atrás, por razões que pouco importam, o bug ocorreu - e alguns desses caras foram enganados por um dia inteiro de comissões gordas. Eles definitivamente não eram divertiram.
Infinitamente pior, eles perderam a (já muito pouca) fé que tinham no programa, não sendo projetados para fustigá-los clandestinamente e fingiram - e obtiveram - uma revisão completa e detalhada do código com casos de teste executados e comentados em termos de leigos (mais muito tratamento com tapete vermelho nas semanas seguintes).
O que posso dizer: do lado positivo, nos livramos de muitas dívidas técnicas e fomos capazes de reescrever e refatorar várias partes de uma bagunça de espaguete que causou uma infestação de COBOL nos anos 90. Sem dúvida, o programa roda melhor agora, e há muito mais informações de depuração para se concentrar rapidamente quando algo parece suspeito. Estimo que apenas essa última coisa poupará talvez um ou dois homens-dia por mês no futuro próximo.
No lado negativo, todo o dinheiro custou à empresa cerca de € 200.000 na frente - mais a face, além de indubitavelmente algum poder de barganha (e, portanto, ainda mais dinheiro).
O responsável pela "otimização" havia mudado de emprego há um ano, antes do desastre, mas ainda havia conversas para processá-lo por danos. E não foi bem com os escalões superiores o fato de ter sido "a culpa do último cara" - parecia uma armação para resolvermos o problema e, no final, ainda estamos na casa de cachorro e uma equipe está planejando sair.
Noventa e nove vezes em cem, o "86400 hack" funcionará perfeitamente. (Por exemplo, em PHP,
strtotime()
ignorará o horário de verão e informará que entre a meia-noite do último sábado de outubro e a segunda-feira seguinte, exatamente 2 * 24 * 60 * 60 segundos se passaram, mesmo que isso não seja verdade. ... e dois erros alegremente farão um certo).Senhoras e Senhores Deputados, este foi um caso em que não aconteceu. Como nos airbags e cintos de segurança, talvez você nunca precise realmente da complexidade (e facilidade de uso) de
DateTime
ouCarbon
. Mas o dia em que você poderá (ou o dia em que terá que provar que pensou sobre isso) virá como um ladrão durante a noite. Esteja preparado.fonte
days between two days in php
ou similar, só porque a vida é muito curta para escrever tudo sozinho.Fácil de usar date_diff
fonte
$diff
variável neste caso). Algo comoif ($diff->days > 30) { [doyourstuff]; }
Estilo orientado a objetos:
Estilo processual:
fonte
Usou isso :)
Agora funciona
fonte
Bem, a resposta selecionada não é a mais correta porque falhará fora do UTC. Dependendo do fuso horário ( lista ), pode haver ajustes de tempo criando dias "sem" 24 horas, e isso fará com que o cálculo (60 * 60 * 24) falhe.
Aqui está um exemplo disso:
Portanto, a solução correta estará usando DateTime
fonte
Calcule a diferença entre duas datas:
Saída: +272 dias
A função date_diff () retorna a diferença entre dois objetos DateTime.
fonte
fonte
Estou usando o Carbon nos meus projetos de compositor para esse e outros propósitos semelhantes.
Seria tão fácil assim:
fonte
Você pode encontrar datas simplesmente
fonte
e, se necessário:
fonte
Se você tiver os tempos em segundos (registro de data e hora do IE unix), poderá subtrair os tempos e dividir por 86400 (segundos por dia)
fonte
fonte
Você pode tentar o código abaixo:
fonte
fonte
Se você deseja ecoar todos os dias entre a data de início e término, eu vim com isso:
fonte
A maneira mais fácil de encontrar a diferença de dias entre duas datas
fonte
fonte
Aqui está minha versão aprimorada, que mostra 1 ano (s) 2 meses (s) 25 dias (s) se o segundo parâmetro for passado.
fonte
fonte
usou o código acima muito simples. Obrigado.
fonte
fonte
Usando esta função simples. Declarar função
e chame essa função assim onde quiser
fonte
fonte
Se você estiver usando o MySql
}
}
fonte
Tente usar o Carbon
Você também pode usar
para criar um objeto de data de carbono usando a sequência de carimbo de data / hora especificada.
fonte
Procurando todas as respostas, componho a função universal que funciona em todas as versões do PHP.
Em geral, eu uso 'DateTime' para encontrar dias entre 2 datas. Mas se, por algum motivo, alguma configuração do servidor não tiver o 'DateTime' ativado, ele usará um cálculo simples (mas não seguro) com o 'strtotime ()'.
fonte