Logo Hardware.com.br
Flavio_vivinho
Flavio_vivin... Geek Registrado
2.5K Mensagens 173 Curtidas

[Resolvido] PHP e MySql: Filtrar data de aniversário.

#1 Por Flavio_vivin... 05/06/2015 - 22:18
Olá, pessoal!
Já pesquisei no Google e não consegui a ajuda que preciso...
Estou precisando fazer um código em PHP e MySql que faça um filtro entre datas, tipo: De 01/02 a 30/03 --- ou ---- de 01/05 a 30/05.

Eu até consegui fazer um código, colocando o campo, no banco, como date... só que o filtro está se baseando pelo ano também, levando a consulta, de uma certa forma, dentro de mesmo ano ou de ano para ano. Sendo que o filtro precisa somente se basear no dia e mês somente.

Pesquisando consegui o seguinte código que até funcionou para filtrar os aniversariantes do dia vigente e do mês vigente diretamente no MySQL, mas com este código não dá para filtrar do dia 01/05 a 10/05; e eu precisava desta flexibilidade.

Filtro somente para o dia vigente - está funcionando
[code=mysql]
$sql2 = $conn->query("SELECT * FROM clientes WHERE DAY(data_aniversario) = DAY(CURDATE()) AND MONTH(data_aniversario) = MONTH(CURDATE())");
[/code]

Filtro somente para o mês vigente - está funcionando
[code=mysql]
$sql2 = $conn->query("SELECT * FROM clientes WHERE MONTH(data_aniversario) = MONTH(CURDATE())");
[/code]

O que eu precisava agora é um código que permita fazer o filtro entre meses ou dia como mencionei acima, tipo:
Primeiro tipo de filtro=> data inicial: 01/03 ||| data final: 30/03
Segundo tipo de filtro=> data inicial: 01/03 ||| data final: 14/03
Terceiro tipo de filtro=> data inicial: 01/03 ||| data final: 30/04

Desde já agradeço a atenção e ajuda de todos.
Até+
DiguinDeveloper
DiguinDevelo... Super Participante Registrado
313 Mensagens 148 Curtidas
#2 Por DiguinDevelo...
06/06/2015 - 09:46
Veja se isso resolve:

[code=PHP]
$diaInicial = '01';
$mesInicial = '05';
$dataInicial = "YEAR(NOW())-$mesInicial-$diaInicial"; // formato yyyy-mm-dd, ou 2015-05-01

$diaFinal = '30';
$mesFinal = '05';
$dataInicial = "YEAR(NOW())-$mesFinal-$diaFinal"; // formato yyyy-mm-dd ou 2015-05-30

$query = "SELECT * FROM clientes WHERE data_aniversario BETWEEN '$dataInicial' AND '$dataFinal' ";
...
[/code]

Óbvio que isso é apenas exemplo, já que você está usando PDO, seria interessante usar prepare statements para filtrar variáveis externas como o dia e o mês que virão de fora.

A lógica é simples, para filtrar datas com maior precisão num banco de dados, é bom usar o ano também, sendo assim o formato universal yyyy-mm-dd costuma funcionar bem nessas ocasiões.

Como os parâmetros dia e mês sempre podem variar, você simplesmente concatena com o ano vigente YEAR(NOW()).

Atenção, não me recordo se a função YEAR() do mysql retorna o ano com quatro dígitos, bom verificar na documentação.
Flavio_vivinho
Flavio_vivin... Geek Registrado
2.5K Mensagens 173 Curtidas
#3 Por Flavio_vivin...
06/06/2015 - 12:27
Obrigado por sua resposta.
No caso, não poderia filtrar somente dentro do mesmo ano, pois os anos de nascimento são diversos. Preciso filtrar somente entre dia e mês e ignorar o ano.

Tentei criar algo com o código que colocou acima mas não consegui resultado.

O código abaixo até filtra da forma que quero, mas somente dentro do mesmo ano, tipo: 01/02/2015 a 10/02/2015. Como o possível cliente nasceu em 1998 a data de aniversário dele não será exibida.

[code=php]
$post_niver1 = $_POST["niver1"];
$post_niver2 = $_POST["niver2"];

$sql2 = $conn->query("SELECT * FROM clientes WHERE data_aniversario BETWEEN '$post_niver1' AND '$post_niver2' ORDER BY nome ASC");
[/code]

O código recebe as datas via post por estar usando ajax na primeira etapa.
"Vinde a Mim, todos os que estais cansados e oprimidos, e Eu vos aliviarei" - Mateus 11,28.
www.flaviosistemas.com.br
Desenvolvendo projetos, facilitando sua vida.
DiguinDeveloper
DiguinDevelo... Super Participante Registrado
313 Mensagens 148 Curtidas
#5 Por DiguinDevelo...
10/06/2015 - 10:55
Qual o formato de data vem nas variáveis $post_niver1 e $post_niver2?

Fica fácil você extrair/quebrar as datas pra montar o sql dessa forma?

[code=PHP]
$post_niver1 = explode('/', $_POST['niver1']);
$dia1 = $post_niver1[0];
$mes1 = $post_niver1[1];

$post_niver2 = explode('/', $_POST['niver2']);
$dia2 = $post_niver2[0];
$mes2 = $post_niver2[1];

$sql = "SELECT * FROM clientes WHERE (DAY(data_aniversario) BETWEEN $dia1 AND $dia2) AND (MONTH(data_aniversario) BETWEEN $mes1 AND $mes2)";
[/code]

Estou tomando como exemplo que as datas via post vêm no formato dd/mm/yyyy ok, por isso usei o explode com barra simples.

Desse jeito que exemplifiquei, pela lógica o ano será totalmente ignorado.

Espero ter ajudado.
Flavio_vivinho
Flavio_vivin... Geek Registrado
2.5K Mensagens 173 Curtidas
#6 Por Flavio_vivin...
10/06/2015 - 17:11
DiguinDeveloper disse:
Qual o formato de data vem nas variáveis $post_niver1 e $post_niver2?

Fica fácil você extrair/quebrar as datas pra montar o sql dessa forma?

[code=PHP]
$post_niver1 = explode('/', $_POST['niver1']);
$dia1 = $post_niver1[0];
$mes1 = $post_niver1[1];

$post_niver2 = explode('/', $_POST['niver2']);
$dia2 = $post_niver2[0];
$mes2 = $post_niver2[1];

$sql = "SELECT * FROM clientes WHERE (DAY(data_aniversario) BETWEEN $dia1 AND $dia2) AND (MONTH(data_aniversario) BETWEEN $mes1 AND $mes2)";
[/code]

Estou tomando como exemplo que as datas via post vêm no formato dd/mm/yyyy ok, por isso usei o explode com barra simples.

Desse jeito que exemplifiquei, pela lógica o ano será totalmente ignorado.

Espero ter ajudado.


Sim, também usei um explode para trocar a data do formato br para o formato padrão.

Este código até que ficou funcional, ignorando o ano ao filtrar. No entanto, o filtro é feito somente dentro do próprio mês, pois ao usar a função MONTH(data_aniversario), delimita-se somente para o mês vigente. Pelo menos aqui nos meus testes achei isto.
Em resumo, o problema do ano ao filtrar foi resolvido, mas agora, com este último código, somente filtra dentro do mês vigente.
Desta forma não pesquisa tipo: 01/08 a 31/08 por estarmos no mês 06.

Estava pensando aqui em fazer uma gambiarra, acrescentando mais um campo na tabela para fazer os filtros. Assim, deixaria o campo data_aniversario para consulta somente e o filtro seria feito em um tipo de clone dos dados que seriam gravados mas com o ano fixo. Ao gravar, desmontaria a data e adicionaria um ano fixo tipo 1900. Desta forma sempre que for filtrar desmonto a data, elimino o ano vigente ou adicionado no filtro e concatenaria com 1900. assim poderia fazer o filtro sem a função MONTH(data_aniversario).
Vou fazer estes teste e posto o resultado.
Obrigado
Até+
"Vinde a Mim, todos os que estais cansados e oprimidos, e Eu vos aliviarei" - Mateus 11,28.
www.flaviosistemas.com.br
Desenvolvendo projetos, facilitando sua vida.
DiguinDeveloper
DiguinDevelo... Super Participante Registrado
313 Mensagens 148 Curtidas
#7 Por DiguinDevelo...
10/06/2015 - 19:57
Um outro jeito de fazer é criar dois campos do tipo int, um para o dia outro para o mes, quando incluir algum registro, você quebra a data de aniversário e preenche esses campos, ao fazer uma consulta basta usar os campos junto com between que funciona normalmente.

A vantagem é que as consultas serão performáticas, já que está usando campos numéricos ao invés de datas, a desvantagem é ter que lembrar de gravar o dia e o mês separadamente na tabela. Dessa forma sim, você fica totalmente independente de ano nas consultas.

Espero ter ajudado.
Flavio_vivinho
Flavio_vivin... Geek Registrado
2.5K Mensagens 173 Curtidas
#8 Por Flavio_vivin...
12/06/2015 - 10:35
DiguinDeveloper disse:
Um outro jeito de fazer é criar dois campos do tipo int, um para o dia outro para o mes, quando incluir algum registro, você quebra a data de aniversário e preenche esses campos, ao fazer uma consulta basta usar os campos junto com between que funciona normalmente.

A vantagem é que as consultas serão performáticas, já que está usando campos numéricos ao invés de datas, a desvantagem é ter que lembrar de gravar o dia e o mês separadamente na tabela. Dessa forma sim, você fica totalmente independente de ano nas consultas.

Espero ter ajudado.



Obrigado DiguinDeveloper, com certeza me ajudou. Não conhecia a instrução MySQL que apresentou. Vai me ajudar a criar agora além do filtro no aniversário, um aviso na página principal dos aniversariantes do dia e mês vigente automaticamente.

Em relação ao filtro, o que mencionei acima de criar outro campo como data mesmo mas manipulando o ano, funcionou legal. Desmontei a data, removi o ano vigente e adicionei o ano 1900 para todos os registros neste novo campo. Assim, sempre vai estar dentro do mesmo ano e poderá sempre usar a data completa para os filtros.
"Vinde a Mim, todos os que estais cansados e oprimidos, e Eu vos aliviarei" - Mateus 11,28.
www.flaviosistemas.com.br
Desenvolvendo projetos, facilitando sua vida.
© 1999-2024 Hardware.com.br. Todos os direitos reservados.
Imagem do Modal