Datas recursivas com PHP

Em um dos projetos que estou trabalhando eu precisei trabalhar com datas recursivas a partir de uma data inicial e de uma periodicidade. 

Datas no PHP

Não vou abordar a fundo como trabalhar com datas no PHP, apenas como adicionar determinado número de dias em uma data. Se você não tem ideia de como trabalhar com datas no PHP, recomendo começar pelo manual do PHP date() date(). 

Mas o conceito de recursividade é simples e vou explicar abaixo o funcionamento de cada passo para gerar datas repetidas com PHP.

Formatando a data de hoje

Primeiro, o básico de formatação de datas com PHP. Estou trabalhando com MySQL (date), portanto trabalho com a seguinte formatação.

date('Y-m-d');

O código acima vai retornar a data de hoje no formato ano-mes-dia.

Adicionar dias em uma data

Para dar início a recursividade a lógica é: tenho uma data e preciso saber qual será a data daqui X dias, e assim sucessivamente. Para adicionar dias a uma data usamos a função strtotime (veja o manual) do PHP junto com date. 

No exemplo abaixo o resultado deve ser a data formatada para exatamente daqui a 7 dias.

date('Y-m-d', strtotime(date('Y-m-d') . '+7 days'));

Recursividade de datas

Com estes 2 conceitos básicos sobre datas no PHP e um pouco de criatividade você consegue gerar datas recursivas no PHP

No exemplo abaixo, vou pegar as próximas 10 datas a partir de hoje, com uma periodicidade de 15 dias e colocar no array $myDates;

$lastDate = date('Y-m-d');
$myDates = array();
for ($x=0; $x<=10; $x++){
  $myDates[] = $lastDate;
  $lastDate = date('Y-m-d', strtotime($lastDate . ' +15 days'));
}

Recursividade de datas por período

Indo um pouco mais longe, você pode fazer seleções de datas dentro de janela de tempo usando quase a mesma lógica – mas deve tomar cuidado para não gerar loop infinito no seu código.

No exemplo abaixo, quero retornar todas as datas a partir de hoje, contando de 15 em 15 dias, até a data limite de 4 de Dezembro.

$lastDate = date('Y-m-d');
$endDate = '2014-12-04';
$myDates = array();
$finished = false;
while(!$finished){
  $lastDate = date('Y-m-d', strtotime($lastDate . ' +15 days'));
  if(strtotime($lastDate) > strtotime($endDate)){ $finished = true; break; }
  $myDates[] = $lastDate;
}

Usando a mesma verificação do $endDate você pode configurar uma data inicial e uma final, selecionando apenas as datas dentro deste período.

Talvez existe algum método mais eficiente de fazer isso. Quando pesquisei sobre o assunto encontrei a biblioteca When, mas ela não era exatamente o que eu queria. 

Se você precisa saber quando serão as próximas Quarta-Feiras que irão cair em um dia 2 de Fevereiro, é a biblioteca para você, vale conferir. Se você optar pela When tome cuidado com os loops infinitos que ela pode gerar.

Como verificar o número de variáveis passadas em um shellscript?

O que mais me traz satisfação como desenvolvedor é gerar automatização de tarefas. Desenvolver ferramentas e rotinas que possibilitem que minha equipe ou meus clientes trabalhem menos para alcançar determinado objetivo.

Desde gerar backups até configurar um ambiente de desenvolvimento ou produção. Hoje fui implementar umas alterações no shellscript para criar um site no apache e criar as pastas no meu ambiente local, mas para isso precisava verificar o número de variáveis passadas pelo usuário antes de continuar a execução do script. 

Como verificar o número de variáveis passadas no shellscript?

Para ter o número de variáveis que um shelscript recebeu é bem simples:

$#

Sabendo disso basta você fazer uma comparação para validar se o número de variáveis é o que você esperava. No exemplo abaixo o script finaliza a execução se o usuário não passar pelo menos 2 variáveis:

if [ $# -lt 2 ]; then
echo 'Necessário 2 variáveis'
exit 0
fi

Uma dica do Bruno para tornar o código mais legível é fazer a comparação da seguinte forma, e também usar exit 1 para quando der erro, fica assim:

if [[ $# < 2 ]] then
echo 'Necessário 2 variáveis'
exit 1
fi

Usar o exit 1 quando algo der errado no seu script impede que outros scripts sejam executados na sequência se o seu deu errado, por exemplo:

seu_script.sh && seu_segundo_script.sh

Se algum erro acontecer no seu_script o seu_segundo_script não será executado.

Agora consigo validar a execução de qualquer shellscript e evitar erros. Se voc6e tem uma maneira diferente de fazer esta verificação deixe nos comentários!