Volta e meia recebo emails onde vejo perguntas de “Como somar X dias a uma data?”, “Como descubro quando é a próxima quinta?”, e muitas outras assim. Me assuto ao ver respostas enormes com códigos que fazem de tudo, até calcular dias levando em conta um algoritmo maluco q determina ano bisexto… não entendo porque complicar tanto.
A função strtotime() esta ai para isso, nesse posto vou apresentar ela e mostrar casos simples de uso onde ela é muito eficaz. Além de verificar a performance da função utilizando um benchmark simples.
Qual é o segredo da função strtotime? É simples, a função aceita uma string, no formato “US English date”, e realiza um parse nela transformando em um timestamp. Esta capacidade amplia o horizonte de funcionalidade da strtotime() tornando possivel a soma de datas, obtenção de dias específicos e inumeras outras funcionalidades.
Ela recebe dois parametros, time e now:
time – String de acordo com o padrão de datas GNU
now – timestamp de referencia
Como usar?
A função pode ser usada somente com o parametro time, mas a presença do parametro now faz com que este data seja o marco de referência da função, vou exemplificar com alguns exemplos:
< ? //Pegar a hora agora echo strtotime("now"); //Usando uma data textual echo strtotime("10 September 2000"); //Adicionar um dia echo strtotime("+1 day"); //Adicionar uma semana echo strtotime("+1 week"); //Adicionar uma semana, dois dias, quatro horas e dois segundos echo strtotime("+1 week 2 days 4 hours 2 seconds"); //Buscar por dia da semana, próxima quinta echo strtotime("next Thursday"); //Buscar por dia da semana, última segunda echo strtotime("last Monday"); //Pegar data de hoje e adicionar 10 dias $now = strtotime("now"); echo strtotime("+10 day",$now); ?>
Vale notar a sintaxe “+3 day” onde o sinal “+” e o número devem estar colados e o “day” (dia) no singular. Isto pode causar alguns transtornos como já apreceram na lista php-pt que participo.
Não sei se isso ajuda muitos, mas realmente é melhor que se entregar a funções que são de certa forma “engessadas” em relação ao formato de entrada da data, ou classes complexas que adicionam dezenas de linhas de codigo.
Vale também resaltar a utilidade desta função na interpretação de data vindas do MySQL Como sabemos, datas do MySQL estão no formato “YYYY-MM-DD”, e para formatar esta data com a função date, strftime ou mktime precisamos fazer um trabalho extensivo de substrings para ajeitar a data. Alás que com esta função podemos fazer isso rapidamente, obeserve:
< ? //$data_do_db possui uma data vinda do MySQL echo date('d/m/Y'.strtotime($data_do_db)); ?>
Na minha cabeça a essa altura só me restava uma reflexão sobre a performance desta função em relação a outras soluções. Por isso primeiro fiz um benchmark eu mesmo e o resultado foi este:
Código:
//Com função $dataInicial = "01/08/2006 08:04:20"; date("d/m/Y H:i:s", dateAdd($dataInicial, +15, "dia")); //Com strtotime $dataInicial = "01/08/2006 08:04:20"; date("d/m/Y H:i:s", strtotime("+15 day",strtotime($dataInicial)));
Executando 100 vezes
Benchmark função: 0.000267641544342
Benchmark strtotime(): 0.000428168773651
Confesso que não era o que eu esperava, uma diferença de 0.0002 a mais em relação a uma função “custom”, por isso fui procurar algo fora do lugar. Me dei conta que partindo da data acima é necessário rodar a função strtotime duas vezes, por isso decidi repetir o teste com um timestamp no lugar da data. Desta vez ficou clara a performance melhor da função strtotime(), pois para transformar o timestamp no formato usado pela função temos que executar a função date primeiro.
Usando Data textual
Executando 100 vezes
Benchmark função: 0.000275664329529
Benchmark strtotime(): 0.000425822734833
Usando timestamp
Executando 100 vezes
Benchmark função: 0.000400955677032
Benchmark strtotime(): 0.000323491096497
Código do benchmark: aqui
Runtime do benchmark: aqui
Bem, mesmo com a performance mais baixa no caso da data textual, que se deve ao processo de parse da string, a facilidade no uso da função é claramente superior, simplificando o código e diminuindo o numero de linhas de código.
Fica entao para vocês a decisão, simplicidade e flexibilidade ou formato engessado e performance?
This post is also available in: Inglês
Realmente essa função facilitou muito minha vida, precisei usa-la recentemente para implementar um sistema de historico de artigos de um blog.
parabens pelo artigo
Leonardo França
Olá Rafael,
Primeiramente, parabéns pelos seus posts, são de grande valia todos eles.
Bom, cheguei até aqui através do Google, gostei do assunto (strtotime), mas percebi o seguinte:
Se dou um echo aqui:
echo date(“d/m/Y H:i:s”, strtotime(“+15 day”,strtotime($dataInicial)));
Eu terei como resultado: 18/01/2006 08:04:20 mas o certo não seria: 16/08/2006 08:04:20 ? Uma vez que estamos somando 15 dias a data 01/08/2006.
Quemei a cuca aqui, mas sem sucesso.
Qual sua opinião a respeito?
Um abraço.
PS. Assinei seus feeds, acompanharei o seu blog.
Leandro,
Isso depende, voce não mostrou qual o conteudo inicial da variavel $daraInicial, por isso não tenho como te dar certeza de nada. Mas lembre que esta função recebe datas no formato “US English date”, com isso se o valor de $dataInicial for 01/08/2006 você terá um erro na interpretação, procure passar as datas no formato 2006-08-01 (YYYY-MM-DD) que o cálculo deve sair certinho.
Qualquer coisa me mande o código pra eu testar.
Obrigado pelos elogios, continue ligado,
abraço
Cara, o código foi o que você apresentou no post:
#
//Com strtotime
#
$dataInicial = “01/08/2006 08:04:20”;
#
date(“d/m/Y H:i:s”, strtotime(“+15 day”,strtotime($dataInicial)));
então, só fiz isto:
echo date(“d/m/Y H:i:s”, strtotime(“+15 day”,strtotime($dataInicial)));
ou seja, acrescentei o echo para ver o resultado.
Realmente, saiu correto, depois que alterei o valor da variável $dataInicial para 2006-08-01.
Um abraço.
Leandro,
Realmente, desculpe a falha, o formato esta errado, ele deve ser convertido para YYYY-MM-DD primeiro. Vou corrigir este problema no tópico.
Oi, estava dando uma olhada no seu código e gostaria de saber se com a função strto time() ou com outra função poderíamos encontrar a quantidade de dias decorrido entre duas datas informadas.
De já agradeço.
Estou precisando saber a quantidade de dias entre duas datas informadas. Gostaria de saber se posso fazer isso com a função strtotime() ou outra função…
Espero o retorno.
Andrea,
Não vejo uma forma de fazer este calculo com a função, porém para fazer isso de uma forma simples, use mktime nas duas datas, subtraia, e converta de novo para dias.
Abraço
Rafael, andei testando o script utilizando tanto o função dateAdd quanto com strtotime e no resultado só vejo algo assim 1174330426.
Será que você poderia me ajudar, segue o script abaixo:
rfilho,
Esse numero simboliza o numero de segundos da data desde o dia “zero”. PAra tornar legígel use um date neste valor, exemplo:
$var = 1174330426;
echo date(‘d/m/Y’,$var);
Abraço
muito bom seu trabalho quebro um arvore
ainda bem que o google esta ai pra mostrar pagina com excelente conteudo
parabens pelo trabalho
🙂
kakaroto
Ajuda com duas datas !
Se dataatualdehoje for
Rafael, vi sua matéria sobre datas e tentei fazer isso aqui, mais não estou conseguindo, exibir esse resultado você pode me dar uma dica.
Se dataatualdehoje for = 21) {
$data_inicial = date(‘Y/m/21′,strtotime($data_final.’ -1 month’));
$data_final = date(‘Y/m/20’);
}
print “$data_inicial & $data_final”;
?>
Não consegui postar aqui… ;/
$dia = date(“d”);
if ( $dia = 21) {
$data_inicial = date(‘Y/m/21′,strtotime($data_final.’ -1 month’));
$data_final = date(‘Y/m/20’);
}
print “$data_inicial & $data_final”;
?>
Olá amigo Rafael!
Muito obrigado peles dicas anteriores.
Estou como uma nova duvida o script esta abaixo:
“…
data:
…”
eu gostaria que ele me mostrasse a data do servidor no campo de texto como eu faço isso?
e gostaria de saber também como pegar uma data no passado subtrair com a data atual para que ele me mostre a idade.
Muito Obrigado e Feliz Natal!
AndersonLS.
Muito bom o post Rafael. Só uma correção (echo date(‘d/m/Y’, strtotime($data_do_db));) => (echo date(‘d/m/Y’, strtotime($data_do_db));)
🙂
@andrea cristina
http://www.php.net/manual/en/datetime.diff.php