out 23 2009

PHP: Usando a Classe DateTime para manipular datas

PHP

Quem em algum momento da vida já precisou trabalhar com datas em PHP, seja comparação ou manipulação, sabe que isso é uma grande dor de cabeça. Não que isso seja difícil de fazer, mas o PHP (até a versão 5.2, pelo menos) não tinha suporte a operações com data. Sempre que era necessário fazer uma verificação se uma data era maior que outra, ou adicionar dias, era uma gambiarra sem fim. E gambiarra é ruim, muito ruim.

Eis que a versão 5.2 do PHP trás uma novidade que acalmou os já saturados nervos de quem necessita desse tipo de controle em seus sistemas. Foram adicionadas ao core do PHP, 4 classes para dar o suporte necessário a manipulação de datas:

Como não tem nenhuma necessidade de replicar a documentação do PHP (que já é bem completa), não vou colocar todos os métodos e atributos que cada classe tem, caso tenha curiosidade (e todo desenvolvedor deve ter), clique nos links e leia a doc de cada uma delas.

Vamos então colocar em prática cada uma dessas classes. Show me the code!

Criando e exibindo uma data formatada

Vamos começar então criando um objeto do tipo DateTime e exibindo ele formatado na tela:

Exemplo 1

//Cria o objeto do tipo DateTime, se não passar
// nada no construtor, assume now;
$date_now = new DateTime();
//usando as constantes da classe DateTime
echo $date_now->format(DATE_RSS);
//mostra Fri, 23 Oct 2009 14:27:51 -0200
  • Linha 3: criamos o objeto sem atribuir nada, com isso, ele assume a data atual(now) do sistema.
  • Linha 5: usamos a função format() utilizando as constantes da classe DateTime

Exemplo 2

//Cria o objeto do tipo DateTime, atribuindo uma string
//usando o formato suportado pela funcao strtotime()
$date_build = new DateTime('2009-10-10');
//usando o formato suportado pela funcao date()
echo $date_build->format('d/m/Y');
//mostra 10/10/2009
  • Linha 3: criamos o objeto atribuindo uma string num formato suportado pela função strtotime()
  • Linha 5: usamos a função format(), mas dessa vez, especificamos o formato da data conforme a função date()

Até agora, nenhuma novidade, já podíamos fazer isso antes até com menos esforço(!?), mas o pulo do gato (não me pergunte de onde tirei esse jargão) ainda está por vir…

Comparação entre datas

Uma outra melhoria que essa classe nos trás é a comparação de datas. Antes, tinhamos um trabalho tremendo para fazer comparação de datas:
Exemplo de POG:

$date1 = str_replace('-','','2009-10-10');
$date2 = str_replace('-','','2009-10-12');
if ($date1 > $date2) {
    //faz algo macabro
}

E isso é chato, e deixa seu código horrível.

Veja como ficou simples fazer a comparação de data usando o DateTime()

Exemplo

$date1 = new DateTime('2009-10-10');
$date2 = new DateTime('2009-12-10');
if ($date1 < $date2) {
    //faz algo de uma maneira correta
}

Sim! A comparação é feita direto entre os objetos, como mágica (brincadeira, é lógica pura)! Isso é uma das features que mais me chamaram a atenção, justamente pela simplicidade do uso. Mas a melhor parte ainda está por vir…

Intervalo entre datas

Eu não me lembro de ter feito isso em PHP (ainda bem) mas calcular o intervalo entre datas também foi facilitado:

$date1 = new DateTime('2009-10-10');
$date2 = new DateTime('2010-10-10');

//calcula a diferenca entre as duas datas
$diff = $date1->diff($date2);

//mostra o numero de dias entre as datas
echo $diff->days . ' dias ';
  • Linha 1 e 2: Cria duas datas do tipo DateTime;
  • Linha 5: O metodo diff() da classe DateTime retorna um objeto do tipo DateInterval;
  • Linha 8: Retorna a quantidade de dias entre as datas

Manipulação de datas

Agora o santo graal em se tratando de datas no PHP, a manipulação de datas, ou seja, poder adicionar/subtrair dias, meses, anos, whatever de uma data:

Exemplo 1

$date1 = new DateTime('2009-10-10');
//imprime 10/10/2009
echo $date1->format('d/m/Y');

//adiciona 1 semana na data
$date1->add(new DateInterval('P1W'));
//imprime 17/10/2009
echo $date1->format('d/m/Y');

//remove 2 dias da data
$date1->sub(new DateInterval('P2D'));
//imprime 15/10/2009
echo $date1->format('d/m/Y');

Tanto o método add() quando o método sub() esperam receber um objeto do tipo DateInterval. O DateInterval cria um intervalo de datas e recebe como parametro, que deve sempre iniciar por “P” (sem as aspas, de Período) seguido pelo periodo, por exemplo P1M (periodo de 1 mês). Na documentação do construtor do objeto tem todas as opções aceitas.

Exemplo 2

Também podemos usar o método modify() para fazer essa manipulação da data.

$date1 = new DateTime('2009-10-10');
//imprime 10/10/2009
echo $date1->format('d/m/Y');

//adiciona 1 semana na data
$date1->modify('+1 week');
//imprime 17/10/2009
echo $date1->format('d/m/Y');

//remove 2 dias da data
$date1->modify('-2 days');
//imprime 15/10/2009
echo $date1->format('d/m/Y');

A diferença é que o método modify() recebe qualquer string aceita no método strtotime(), não necessitando instanciar um objeto DateInterval.

Bueno, por hoje é só pessoal, prometo não demorar tanto no próximo artigo, até porque o PHP 5.3 tem várias novidades muito interessantes. Aguardem…


jul 29 2009

PHP: Instalando a extensão SVN no Ubuntu 9.04

PHP

Recentemente estive envolvido em um projeto que necessitava interagir com um repositório SVN (controle de versão? Não tem idéia do que é isso? Dê uma lida neste artigo). Era o básico, checkout e commit de arquivos, nada muito complexo. Para minha surpresa, o PHP não tem nenhuma função nativa de acesso a repositórios SVN, então a busca pela iluminação começou.

Primeiro pensei em usar a função exec() e só passar os comandos para ela. Isso resolve, mas é um tanto quando deselegante, pessoalmente achei até um pouco grosseiro, além de que rodar um exec() no servidor nunca é bem visto. Mas funciona!

Como a idéia é sempre a melhor implementação (ou pelo menos o mais próximo possível disso), continuei minhas buscas pelo oráculo. Acabei me deparando com uma extensão PECL que fazia exatamente o que eu precisava, a PHP SVN.

Dentre a lista de funções existentes, estão as funções básicas que eu precisava, checkout e commit , até mais avançadas, com parâmetros para a autenticação em servidores que requerem tal segurança.

Instalação

A instalação via PECL é bem simples, se não fosse por alguns problemas de dependência  que encontrei pelo caminho. Como não há necessidade alguma de vocês passarem pelos mesmos “apertos” pelos quais eu passei, segue o passo a passo:

1º Passo – As dependências

Existem algumas dependências necessárias para instalar o pacote PECL do SVN, segue o comando para instalar todas:

sudo apt-get update && sudo apt-get install php5-dev libsvn-dev \
libsasl2-dev libsasl2-modules-ldap libneon27-gnutls-dev

2º Passo – O pacote PECL

Depois de as dependências todas estarem instaladas, vamos para a instalação do pacote PECL SN:

sudo pecl install -f svn

3º Passo – Configurando o PHP.ini

Para finalizar, como super usuário, digite o seguinte comando no terminal:

echo extension=svn.so >> /etc/php5/apache2/php.ini

Feito isso, para o apache reconhecer a extensão, ele deve ser reiniciado:

sudo apache2ctl restart

Pronto! Já estão disponíves no servidor as funções da extensão em seus scripts.

Referências: