"Quantos dias se passaram?" — A pergunta que derruba iniciantes
\n\nMais cedo ou mais tarde, todo desenvolvedor PHP enfrenta a tarefa: descobrir quantos dias se passaram entre duas datas. Parece simples, não? Pegamos duas strings, subtraímos uma da outra — e pronto. Mas é exatamente aí, em terreno aparentemente plano, que os erros mais traiçoeiros acontecem.
\n\nNós vasculhamos o Stack Overflow e encontramos a pergunta real "Finding the number of days between two dates", que acumulou milhares de visualizações. Acontece que até programadores experientes caem em armadilhas relacionadas a fusos horários, timestamps Unix e ao comportamento inesperado do strtotime().
Neste artigo, vamos analisar os cinco erros mais comuns ao calcular a quantidade de dias entre datas em PHP e mostrar como evitá-los. Prepare seu editor — teremos muito código e dicas práticas.
\n\nErro #1: Subtrair timestamps Unix "na cara dura"
\n\nO erro mais popular é tentar obter a diferença entre datas subtraindo timestamps diretamente:
\n\n<?php\n$date1 = strtotime('2024-01-01');\n$date2 = strtotime('2024-01-10');\n$days = ($date2 - $date1) / (60 * 60 * 24);\necho $days; // 9\n?>\n\nÀ primeira vista, funciona. Mas tente mudar o horário de verão. Na transição para o horário de verão, o dia encurta uma hora; na volta, ele se alonga. Resultado: 9.04166 ou 8.95833 dias, em vez de exatamente 9.
\n\nComo corrigir
\nUse objetos DateTime e o método diff(). Eles lidam com todas as variações de horário:
<?php\n$date1 = new DateTime('2024-01-01');\n$date2 = new DateTime('2024-01-10');\n$interval = $date1->diff($date2);\necho $interval->days; // 9 — sempre correto\n?>\n\nTrabalhar com a diferença entre datas em PHP via DateTime::diff é o padrão da indústria. Grave esse padrão na memória.
Erro #2: Ignorar o fuso horário
\n\nImagine: seu servidor está na Europa/Moscou, e um usuário de Nova York insere a data "2024-03-10". Você cria um DateTime sem especificar o fuso horário. O PHP usa o timezone do sistema do servidor. Resultado: a diferença em dias pode "flutuar" em uma unidade.
Isso é especialmente crítico em viradas de mês e transições de horário de verão. O erro aparece raramente, mas quando surge em produção, é muito difícil de detectar.
\n\nSolução: defina o fuso horário explicitamente
\n<?php\n$tz = new DateTimeZone('UTC');\n$date1 = new DateTime('2024-03-10', $tz);\n$date2 = new DateTime('2024-03-20', $tz);\n$interval = $date1->diff($date2);\necho $interval->days; // 10 — honesto\n?>\n\nSempre use UTC para cálculos internos. Se precisar exibir a data para o usuário, converta para o fuso local dele apenas na etapa de saída.
\n\nErro #3: Confundir days com format('%a')
\n\nO objeto DateInterval tem a propriedade days e o método format('%a'). Parece que são a mesma coisa. Mas há uma diferença crucial:
- \n
$interval->days— o número total de dias (considerando todos os meses e anos). O valor é sempre correto. \n $interval->format('%a')— a mesma coisa, mas como string. \n $interval->d— apenas os dias sem considerar os meses. Se a diferença for de 35 dias,dretornará 4 (o resto após subtrair um mês). \n
Iniciantes frequentemente confundem d com days. O resultado: obtêm 4 dias em vez de 35. Isso gera bugs em relatórios, sistemas de cobrança e agendadores de tarefas.
Sempre verifique qual propriedade você está usando
\n<?php\n$date1 = new DateTime('2024-01-01');\n$date2 = new DateTime('2024-02-05');\n$interval = $date1->diff($date2);\n\necho $interval->days; // 35\necho $interval->d; // 4 — NÃO É A MESMA COISA!\n?>\n\nSe você precisa exatamente do número de dias entre duas datas, use