Como gerar datas automaticamente com PHP
Trabalhar com data e hora e valores monetários é bastante complexo em qualquer linguagem que se venha utilizar. Apesar da grande flexibilidade que o PHP oferece com suas funções pré-definidas, também existe uma grande dificuldade por parte dos programadores, principalmente iniciantes, quando o assunto é data, hora ou valores.
Esta semana me deparei com um bom desafio que não havia encontrado ainda, mas sabia que mais cedo ou mais tarde aconteceria. Tratava-se de montar um script ou função para gerar e calcular automaticamente todas as datas de vencimento de um orçamento parcelado, partindo da data da primeira parcela informada pelo usuário do sistema.
A princípio, parece muito fácil, mas não é assim tão simples. Vamos ao código:
function geraParcelas($numParcelas, $venc_parcelas) {
$meses = array();
$venc_parcelas = implode("-", array_reverse(explode("/",$venc_parcelas)));
$venc_parcelas = strtotime($venc_parcelas);
for ($i = 0; $i < = $numParcelas - 1; $i++) {
$meses[$i] = date('Y-m-d', mktime(0,0,0,date('m',$venc_parcelas) + $i date('d',$venc_parcelas), date('Y',$venc_parcelas)));
}
}
Vamos à explanação do código acima realizando um teste de mesa simples:
Imagine os seguintes valores para os parâmetros:
$venc_parcelas = "10/11/2010"; $numParcelas = 6;
Na linha 2, crio um array ou vetor para guardar todas as datas que serão geradas.
Em seguida (linha 3), coloco a data no formato americano aaaa/dd/mm, pois é nesse formato que o php trabalha.
Com a função stringtotime(), linha 4, converto essa data de string para formato data. Na linha 5, inicio um laço de repetição cujo limite é o número de parcelas que devem ser geradas ($numParcelas).
Na linha 6 é que acontece a grande mágica, onde o vetor meses[] extrai em formato de data cada parte da data inicial (primeiro o mês, depois o dia e o ano). Porém ao mês é acrescentado o valor do contador $i. É com esta soma que se consegue fazer com que o mês seja alterado em cada execução do laço, ficando assim:
$meses[$i] = date('Y-m-d', mktime(0,0,0,date('m',2010-11-10) + $i, date('d',2010-11-10), date('Y',2010-11-10)));
Como 2010-11-10 está em formato data e não string, o próprio php se encarrega de incrementar o ano sempre que o mês corresponder a um valor maior que 12 e também altera o mês 13 para 01 (janeiro), fazendo com que as datas sejam geradas corretamente.
Para testar, basta jogar o código em uma página php e mandar imprimir o vetor:
echo $meses[$i];
É isso ai!! Agora basta gravar o vetor em banco de dados usando um novo laço de repetição… mas isso já é outra história… Em breve colocarei outros tutoriais… Portanto, volte sempre!
Referência: www.php.net
UPDATE
Como solicitado por nosso amigo no comentário, segue explicação de como gravar as datas em banco de dados.
Para isso, pode-se utilizar o mesmo laço de repetição anterior e já ir gravando conforme for gerada a data. Retire a impressão e coloque o código abaixo no lugar:
$sql = "INSERT INTO prestacoes (id, vencimento) VALUES (' ', '$meses[$i]')";
$query = mysql_query($sql);
É isso! Caso queiram mais alguma implementação, peçam nos comentários. Até o próximo post.
No related posts.
21 Comments + Add Comment
Got anything to say? Go ahead and leave a comment!
Categorias
Posts Recentes
- Formas normais e consultas com PHP e MySQL – Parte 02
- Formas normais e consultas com PHP e MySQL – Parte 01
- 3G, 3G+ e 4G: quais as diferenças entre essas tecnologias?
- 10 mitos da incompatibilidade nos navegadores para HTML/CSS/JS
- AgiDC – Metodologias Ágeis na prática
- Hackers x Crackers: Quem são os mocinhos?
- Utilidade pública – reimpressão de boletos bancários
- Criando um menu DropDown dinâmico com CSS3, PHP e MySQL
- Lendo e escrevendo arquivos de texto (.txt) com PHP
- Selecionando itens de registros com Javascript
Tags
Acessibilidade Acessórios apple apps banco de dados blog chefe Complementos Conhecimentos Gerais desenvolvedor web desenvolvimento designer e-mails firefox foco gmail google HTML internet Java Script javascript JQuery MySQL navegadores Novidades On-line Orientação a Objetos php POO profissionais programador Programação recursos segurança sistema Sistemas Operacionais site software Softwares tabela tarefas Tendências Tecnológicas Tutoriais usuário web
WP Cumulus Flash tag cloud by Roy Tanck and Luke Morton requires Flash Player 9 or better.




Posted under:
Muito bom o tópido …Mas..
Não consegui obter resposta com o codigo abaixo , mesmo dando um echo na $meses…
Acho que não esta funcionando..
Olá, Leonardo, tudo bem?
Obrigado pelo comentário…
Para imprimir a resposta é necessário usar a função print_r(), assim: print_r($meses). Você tentou assim?
Abs.
Então Sergio , estou tentando de várias formas, reduzi o codigo para caber.. segue código para análise.. aguardo seu breve retorno, estou precisando muito dessa resposta.. Obrigado a atenção.
function geraParcelas($numParcelas, $venc_parcelas)
{
$venc_parcelas = “2010-11-10″;
$numParcelas = “6″;
$mesPgto = substr($venc_parcelas,5,-3);
$meses = array();
$venc = strtotime($venc_parcelas);
for ($i = 0; $i <= $numParcelas-1; $i++)
{
$mesPgto += 1;
$mth = $mesPgto – 12;
$meses[$i] = date('Y-m-d', mktime(0,0,0,date('m',$venc) + $mth, date('d',$venc), date('Y',$venc)));
print_r($meses);
}
}
Fla, Leonardo, blza?
Então… o código em si está blza… a única coisa que vi errado foi na função substr() que vc colocou 5 para a posição inicial e -3 para a qtde de caracteres… não entendi o por quê.
Uma vez que sua data está no formata americano: 2010-11-10, para pegar o mês apenas, ficaria assim: substr($venc_parcelas,6,2) que resultaria em 11, o mês informado. Verifique se não é isso.
Repare que a posição 5 de 2010-11-10 retorna ‘-’, o que deve estar dando erro na conta, por isso retorna vazio. Não tenho certeza se é esse o problema, mas tenta ai do jeito que te falei e me diz o que aconteceu, blza.
Sergio , testei de tudo que foi forma e nada .. essa questão que vc falou alterei mas nada mudou !!!
Olá, leonardo.
Acho que o que aconteceu foi a questão de caracteres especiais errados quando você copiou do site para seu editor. Pelo menos foi o que aconteceu comigo agora a pouco: o dreamweaver não reconheceu as aspas e o sinal de subtração.
Então fiz alguns ajustes no código e testei novamente o código. Está tudo fungando, conforme pode ver neste exemplo: http://tecinove.com/teste/index.php
Abaixo está o código POO funcionando corretamente:
class Parcelas {
function geraParcelas() {
$venc_parcelas = “2010-11-10″;
$numParcelas = 6;
$mesPgto = substr($venc_parcelas,5,2);
$meses = array();
$venc = strtotime($venc_parcelas);
//print $mesPgto; break;
for ($i = 0; $i <= $numParcelas – 1; $i++) {
$mesPgto += 1;
$mth = (int)$mesPgto – 12;
$meses[$i] = date('Y-m-d', mktime(0,0,0,date('m',$venc) + $mth, date('d',$venc), date('Y',$venc)));
print $meses[$i]."”;
}
}
}
$minhasParcelas = new Parcelas();
//print_r($minhasParcelas->geraParcelas());
$minhasParcelas->geraParcelas();
OBS: Vc pode testar usando o print_r(), basta descomentar esta linha e comentar a de baixo.
Segue o código em programação estruturada:
$venc_parcelas = “2010-11-10″;
$numParcelas = 6;
$mesPgto = substr($venc_parcelas,5,2);
$meses = array();
$venc = strtotime($venc_parcelas);
//print $mesPgto; break;
for ($i = 0; $i <= $numParcelas – 1; $i++) {
$mesPgto += 1;
$mth = (int)$mesPgto – 12;
$meses[$i] = date('Y-m-d', mktime(0,0,0,date('m',$venc) + $mth, date('d',$venc), date('Y',$venc)));
print $meses[$i]."”;
}
Espero que dê certo ai pra vc.
Abs.
Po sergio , por incrível que pareça , copio e colo o código e não vai !!!
Tem como vc me enviar o arquivo dele funcionando ???
Ta dando esse erro aqui : Parse error: syntax error, unexpected T_STRING, expecting ‘;’ in /home/storage/2/4b/50/sistemasfavo/public_html/TESTE/datas.php on line 10
LINHA 10 – for ($i = 0; $i <= $numParcelas–1; $i++) {
VALEU !
Olá Leonardo.
Acho que o problema está exatamente no ctrl+c e ctrl+v…
Ao colar no editor, por incrível que pareça o mesmo não reconhece os sinais de subtração e também as aspas duplas. Verifique se não é esse o seu problema ai…
De qualquer forma, segue o anexo funcionando. (foi no seu e-mail)
At+
Enviado por email pelo leitor Leonardo:
“Fala Sergio …
Baixei e testei …. consegui visualizar as informações mas não tive a resposta correta .
gostaria de saber o seguinte: porque quando coloquei o mes “02″ aparece coisa de 2009 ou seja ano anterior ?
porque sempre aparece a data do mês anterior ao que foi informado ?
PARA ESSES PARAMENTROS:
$venc_parcelas = “2010-02-10″;
$numParcelas = 6;
2009-05-10
2009-06-10
2009-07-10
2009-08-10
2009-09-10
2009-10-10
=======================================
$venc_parcelas = “2010-09-10″;
$numParcelas =10;
2010-07-10
2010-08-10
2010-09-10
2010-10-10
2010-11-10
2010-12-10
2011-01-10
2011-02-10
2011-03-10
2011-04-10
2011-05-10″
Ok, realmente havia um erro de lógica no código. Segue abaixo a correção, mas o post também já está corrigido.
class Parcelas {
function geraParcelas() {
$venc_parcelas = “2010-11-10″;
$numParcelas = 36;
$meses = array();
$venc = strtotime($venc_parcelas);
for ($i = 0; $i < = $numParcelas - 1; $i++) {
$meses[$i] = date('Y-m-d', mktime(0,0,0,date('m',$venc) + $i, date('d',$venc), date('Y',$venc)));
print $meses[$i]."
“;
}
}
}
$minhasParcelas = new Parcelas();
$minhasParcelas->geraParcelas();
Abs.
SERGIO , OBRIGADO PELA AJUDA , FUNCIONOU PERFEITAMENTE.
Sergio , boa noite !
Então consegui colocar pra funcionar o script de datas que você mandou e agora me surgiu uma dúvida …
Como faço para inserir no banco essas informações ???
Valeu aguardo seu retorno.
Olá, Leonardo.
Para inserir no banco de dados… vc tem que percorrer o vetor com as datas geradas. E para cada posição do vetor realizar um INSERT no banco gravando o conteúdo daquela posição. Mais ou menos assim:
class Parcelas {
function geraParcelas() {
$venc_parcelas = “2010-11-10?;
$numParcelas = 36;
$meses = array();
$venc = strtotime($venc_parcelas);
for ($i = 0; $i < = $numParcelas – 1; $i++) {
$meses[$i] = date('Y-m-d', mktime(0,0,0,date('m',$venc) + $i, date('d',$venc), date('Y',$venc)));
//print $meses[$i];
}
$sucesso = 0;
$erro = 0;
for ($j = 0; $j < = sizeof($meses) – 1; $j++) {
$sql = "INSERT INTO parcelas (id_parcela,vencimento) VALUES ('','$meses[$j]')";
$query = mysql_query($sql);
if ($query) { // verifica se o insert foi executado com sucesso
$sucesso += 1; // grava a quantidade de sucessos
} else {
$erro += 1; // grava a quantidade de erros
}
}
// verifica quantas mensagens vezes gravou com sucesso e quantas gravou com erro
echo "Foram salvos ".$sucesso." registros com sucesso!”;
echo $erro.” registros não foram salvos!”;
}
}
Bom dia pessoal,
Uma pergunta, estou precisando de algo similar para um fluxo de caixa, mais dessa maneira tem um BUG. Entrem com o seguinte parametro
vencimento = 30/11/2010;
parcelas = 6;
notem que o mes de fevereiro irá jogar para março e não considerar o ultimo dia util do mês que seria 28 ou 29;
2010-11-30
2010-12-30
2011-01-30
2011-03-02
2011-03-30
2011-04-30
Obrigado
RESOLVIDO
$venc_parcelas = “30/11/2010″;
$numParcelas = 6;
geraParcelas($numParcelas, $venc_parcelas);
function geraParcelas($numParcelas, $venc_parcelas)
{
$meses = array();
$venc_parcelas = implode(“-”, array_reverse(explode(“/”,$venc_parcelas)));
$venc_parcelas = strtotime($venc_parcelas);
for ($i=1;$i<=$numParcelas;$i++)
{
$data= date('Y-m', mktime(0,0,0,(date('m',$venc_parcelas)+$i),'01', date('Y',$venc_parcelas)));
$qtdDias = cal_days_in_month(CAL_GREGORIAN, substr ($data,5,7), substr ($data,0,4));
if(date('d',$venc_parcelas) <= $qtdDias)
{
$meses[$i] = date('Y-m-d', mktime(0,0,0,date('m',$venc_parcelas) + $i, date('d',$venc_parcelas), date('Y',$venc_parcelas)))."”;
}else{
$meses[$i] = date(‘Y-m-d’, mktime(0,0,0,date(‘m’,$venc_parcelas) + $i, $qtdDias , date(‘Y’,$venc_parcelas))).”";
}
}
}
//Quantidade de dias do mes
$qtdDias
//Se o dia do vencimento no ano e no mes corrente forem maiores que o dia do vencimento
então a data de vencimento vai ser o ultimo dia daqueles mes
if(date(‘d’,$venc_parcelas) <= $qtdDias)
Olá, Éder, blza?
Obrigado por compartilhar mais esses detalhes conosco.
Vlew.
Eu q agradeço, tava precisando disso ontem, e o script q achei aqui foi bem util, mas enfrentei o mesmo problema, mas pesquisando consegui acertar os ajustes…
Olá Sergio!!!
Parabéns pelo código!!!
vi funcionando na sua pagina teste, estou enfrentado o mesmo problema de copiar e colar vc poderia enviar o codigo pro meu email obrigado.
Olá Sergio!!!
Parabéns pelo código!!!
Vc poderia enviar o codigo funcionando pro meu email?
Muito obrigado
Olá, Fábio.
Obrigado pelo comentário.
O código acima está funcionando corretamente, basta copiar e adaptar as suas necessidades.
Abs.