August 3rd 2006 12:08 am

strtotime() – Pode ajudar?

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:

PHP:
  1. <?
  2. //Pegar a hora agora
  3. echo strtotime("now");
  4.  
  5. //Usando uma data textual
  6. echo strtotime("10 September 2000");
  7.  
  8. //Adicionar um dia
  9. echo strtotime("+1 day");
  10.  
  11. //Adicionar uma semana
  12. echo strtotime("+1 week");
  13.  
  14. //Adicionar uma semana, dois dias, quatro horas e dois segundos
  15. echo strtotime("+1 week 2 days 4 hours 2 seconds");
  16.  
  17. //Buscar por dia da semana, próxima quinta
  18. echo strtotime("next Thursday");
  19.  
  20. //Buscar por dia da semana, última segunda
  21. echo strtotime("last Monday");
  22.  
  23. //Pegar data de hoje e adicionar 10 dias
  24. $now = strtotime("now");
  25. echo strtotime("+10 day",$now);
  26.  
  27. ?>

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:

PHP:
  1. <?
  2. //$data_do_db possui uma data vinda do MySQL
  3. echo date('d/m/Y'.strtotime($data_do_db));
  4. ?>

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:

PHP:
  1. //Com função
  2. $dataInicial = "01/08/2006 08:04:20";
  3. date("d/m/Y H:i:s", dateAdd($dataInicial, +15, "dia"));
  4.  
  5. //Com strtotime
  6. $dataInicial = "01/08/2006 08:04:20";
  7. 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?

1 Star2 Stars3 Stars4 Stars5 Stars (9 votos, média: 4.56 de 5)
Loading ... Loading ...

19 Comments »

19 Responses to “strtotime() – Pode ajudar?”

  1. Leonardo França on 03 Aug 2006 at 14:44 #

    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

  2. Leandro Vieira Pinho on 05 Dec 2006 at 13:42 #

    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.

  3. Rafael Dohms on 05 Dec 2006 at 13:59 #

    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

  4. Leandro Vieira Pinho on 05 Dec 2006 at 14:22 #

    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.

  5. Leandro Vieira Pinho on 05 Dec 2006 at 14:40 #

    Realmente, saiu correto, depois que alterei o valor da variável $dataInicial para 2006-08-01.

    Um abraço.

  6. Rafael Dohms on 05 Dec 2006 at 14:42 #

    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.

  7. Leandro Vieira Pinho´s Blog » Arquivo » Somando dias utéis a uma data específica com PHP on 05 Dec 2006 at 19:33 #

    [...] Nessa recorrida, encontrei um tópico e um post que me inspirou a criar a seguinte função em PHP: Code (php) [...]

  8. andrea cristina on 08 Feb 2007 at 23:10 #

    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.

  9. andrea cristina on 08 Feb 2007 at 23:13 #

    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.

  10. Rafael Dohms on 09 Feb 2007 at 13:54 #

    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

  11. rfilho on 19 Mar 2007 at 15:59 #

    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:

  12. Rafael Dohms on 19 Mar 2007 at 23:23 #

    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

  13. kakaroto on 28 Jun 2007 at 0:12 #

    muito bom seu trabalho quebro um arvore
    ainda bem que o google esta ai pra mostrar pagina com excelente conteudo
    parabens pelo trabalho
    :)
    kakaroto

  14. Duhh on 22 Aug 2007 at 18:41 #

    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”;

    ?>

  15. Duhh on 22 Aug 2007 at 18:42 #

    Ajuda com duas datas !
    Se dataatualdehoje for

  16. Duhh on 22 Aug 2007 at 18:44 #

    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”;

    ?>

  17. Leandro Vieira Pinho´s Blog » Blog Archive » Somando dias utéis a uma data específica com PHP on 25 Sep 2007 at 10:10 #

    [...] recorrida, encontrei um tópico e um post que me inspirou a criar a seguinte função em [...]

  18. andersonls on 25 Dec 2007 at 17:05 #

    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.

  19. Rafael Cambuí » Blog Archive » Somando dias utéis a uma data específica com PHP on 08 Sep 2008 at 16:40 #

    [...] recorrida, encontrei um tópico e um post que me inspirou a criar a seguinte função em [...]

Trackback URI | Comments RSS

Leave a Reply

« AJAX e Acentos | Ranking e novidades »