Lembrete de Aniversariantes

15 respostas
rolipam

Olá pessoal, estou desenvolvendo um aplicativo onde o cadastro de clientes salva a data de nascimento (no formato String dd/MM/aaaa) e em outro campo idade ele pega o valor do campo contendo a data de nascimento e compara com a data atual.

Date hoje = new Date();
            Date aniversario;
            try {
                aniversario = df.parse(con_aniversario.rs.getString("data_nascimento"));
                Long idade = (hoje.getTime() - aniversario.getTime()) / (31536000000L);
                tfIdade.setText(""+idade);
            
            } catch (ParseException ex) {
                ex.printStackTrace();
            }

O cliente me pediu para colocar um lembrete de aniversariante quando abrir o sistema. Minha dúvida agora é como realizar essa consulta no banco de dados e como comparar as datas. Pra não ficar parado, só pensando, e sem colocar as idéias no papel, cheguei até o código abaixo, que sei que não vai funcionar, mas a partir daí é que agente vai se batendo até chegar a uma solução plausível.

SimpleDateFormat dfs = new SimpleDateFormat("dd/MM"); // Não sei se esse código será aceito (ainda não compilei, pois no momento não estou na minha máquina de desenvolvimento)

        con_aniversario = new ConexaoBD();
        con_aniversario.conecta();
        
        String sql_aniversario = "select * from clientes where data_nascimento >= "+dfs.format(dataAtual);
        con_aniversario.executeSQL(sql_aniversario);
        try {
            con_aniversario.rs.first();
            mostraAniversariantes();
        } catch (Exception e) {
            e.printStackTrace();
            //JOptionPane.showMessageDialog(null, "");
        }

Do modo como está não vai funcionar porque a condição imposta (data_nascimento >= dataAtual) nunca será satisfeita.
Cheguei a pensar na possibilidade de realizar uma consulta antes dessa para armazenar os valores do dia e do mês de cada cliente em variáveis (utilizando os métidos getDay e getMonth) e depois fazer as comparações, mas também estou em dúvida de como fazer isso. Alguém tem uma solução que não seja tão complicada ou alguma forma de aproveitar o que já está sendo desenvolvido?
Agradeço a colaboração de todos.

15 Respostas

E

Você tem a data de nascimento, certo? Como ela é cadastrada no banco?

a) Com uma coluna do tipo TIMESTAMP ou DATE
b) Com uma coluna do tipo VARCHAR

Digamos que hoje seja 14/08/2012 e haja clientes cuja data de nascimento esteja cadastrada como “1956-08-14” ou coisa parecida.

O dia e mês pode ser obtido dessa coluna usando alguma função do banco - isso não é padrão ANSI e você precisa consultar a documentação do seu banco. Por exemplo, no Oracle, veja esta página:

E

Mais uma coisinha - acho que é interessante, se seu sistema não vai ser acessado todos os dias (por exemplo, é um sistema que é acessado só de segunda até sexta) você verificar se o dia do aniversário já não passou .

Por exemplo, digamos que a pessoa se logue no dia 13/08/2012 e o aniversário dela foi no dia 12/08 (que neste ano caiu no domingo). Você poderia ter cumprimentado a pessoa pelo aniversário na sexta-feira, ou devido a uma superstição que diz que não se deve cumprimentar antecipadamente pelo aniversário, fazer o cumprimento na segunda-feira (dia em que a pessoa se logou).

rolipam

entanglement, Valeu pelas dicas. Na verdade utilizo o PostgreSQL e a data é salva no banco de dados como varchar no formato (dd/MM/aaaa), pois para esse campo utilizo uma máscara (##/##/####). Então é possível obter apenas o dia e o mês da data de nascimento! era isso que eu precisava. Vou consultar a documentação do PostgreSQL. Mais uma coisa, como se trata de uma função do próprio banco, vou poder utilizar essa função na composição da minha query no Java? Mais uma vez obrigado.

davidbuzatto

Se você está usando um varchar vc vai ter que convertê-lo para um DATE (o postgree deve ter alguma função que faz isso) ou então usar o operador LIKE para comprarar os valores da String.

drsmachado

Primeiro que acho uma ofensa usar campo varchar para salvar date.
Segundo que sim, existem formas de converter uma String mascarada para Date.
Trabalhar com datas seria bem mais simples que usar um monte de gambiarra para fazer uma coisa simples.
Considere mudar a estrutura do banco.

rolipam

davidbuzatto, Obrigado pelo “toque”. Realmente, eu estava pesquisando algumas funções internas do postgreSQL e achei uma que provavelmente irá atender as minhas necessidades (Select toDate(…)) e depois utilizar a função extract, que extrai parte da data (ano, mês, dia, …) para somente depois fazer a comparação. Mas acho melhor mesmo mudar o tipo de dado da coluna data_nascimento para DATE e evitar tanta conversão de tipos e funções “Extras” para atender o meu objetivo. Valeu Mesmo!

rolipam

drsmachado, Você leu meu pensamento! Enquanto estava editando a resposta para davidbuzatto (ainda não havia lido a sua) já havia levantado a possibilidade de realizar essa mudança. Na verdade o Campo data_nascimento era pra ter sido criado como data, mas devido a uma “preguiça” minha, que quis aproveitar a estrutura de uma tela de cadastro de clientes antiga, onde utilizo o campo aniversario para colocar por extenso a data (tipo: 14 de agosto) sem ano ou sem a necessidade de fazer nenhum tipo de cálculo. Mas agora a coisa mudou um pouco de figura, e apesar do cálculo da idade não ter me apresentado maiores problemas, esse lembrete fez aparecer um “problemão”. Valeu pela dica!

E

Aimeudeus, dia/mês/ano?
Nem dá para ordenar por data (não dá para ordenar por idade, por exemplo. Parece uma coisa boba, mas costuma ser interessante fazer uma análise demográfica dos seus clientes (por exemplo, clientes com mais de 60 anos costumam dar menos calotes, ou coisas parecidas).

Só tem uma vantagem nesse ponto: para achar todo mundo que faz aniversário em 14/08, você pode fazer uma consulta do tipo "DATA_ANIVERSARIO LIKE “14/08%”.

E

Que tosqueira :slight_smile: - depois o problema que você vai ter é o de limpar (normalizar) a tabela.

rolipam

Galera, Já corrigi a “toqueira” que havia feito. O campo data_nascimento já está no formato “DATE” (yyyy-MM-dd). O que preciso agora é comparar o dia e o mês dos registros desse campo com o dia e mês atuais (now()) para ordenar os aniversariantes por mês e dentro do mês por dias, a partir da data atual. Alguém tem alguma idéia ou dica para me ajudar? Não custa lembrar que estou utilizando o banco de dados PostgreSQL 9.1.2, e que na minha query de consulta ao banco de dados, além da data (MM/dd) também preciso capturar o nome do aniversariante para setá-los nos respectivos campos. Para o cálculo da idade mantenho o mesmo código que já está funcionando.

rolipam

como faço para converter a data de nascimento cadastrada no banco de dados em uma data do ano corrente, nos mesmos dia e mês. Por exemplo: Cadastrei um cliente com a data de aniversário 2001-08-14 e após a consulta ao BD armazeno esse valor em uma variável e somo tantos anos quantos forem necessários (de forma dinâmica) para obter, no caso desse ano 2012-08-14 como sendo a data do aniversário. Obrigado

rolipam

Olá pessoal,

Será que não tem como somar a idade que o cliente vai fazer naquele ano ao ano da data de nascimento no java? Descobri um função no postgreSQL que faz isso, mas não sei como aplicar ao meu caso, já que a quantidade de anos ‘34 year’ é variável. O código abaixo faz isso.

Select date'1978-10-04' + interval '34 year'

e meu retorno é

2012-10-04

Estava pensando em utilizar uma query mais ou menos assim, para a minha finalidade:

Select nome as nome, aniversario as nascimento, aniversario+interval 'x year' as data_aniversario from clientes order data_aniversario.

Onde X é a idade em anos que o cliente vai fazer naquele ano. Mas mesmo assim ainda não sei se vai atender as minhas necessidades, e nem se vai ser aceita (aniversario + interval ‘x year’) pois ainda não pude testar a consulta acima.
Já tentei até converter a data de nascimento em um tipo long (aniversario.getTime()) e somar com a idade ((hoje.getTime() - aniversario.getTime() / 31536000000L)+1, também um tipo long e depois converter em um tipo date (new Date(nascimento + idade)), mas a data de retorno foi 10 dias inferior a data do aniversario.
Alguém pode clarear minhas idéias e me dar um Help? Obrigado!

E

Espera um pouquinho. Digamos que você queira pegar os clientes que fazem aniversário em 16/08. Suponha agora que a coluna seja “data_nascimento” e seja do tipo DATE.

Não seria algo como

SELECT ___ FROM _____ WHERE DATE_PART (‘day’, data_nascimento) = 16 AND DATE_PART(‘month’, data_nascimento) = 08

Para pegar os clientes que fazem aniversário hoje, provavelmente você teria algo como

DATE_PART (‘day’, data_nascimento) = DATE_PART (‘day’, CURRENT_DATE) AND … (deixo o resto por sua conta)

http://www.postgresql.org/docs/8.1/static/functions-datetime.html

(Eu não tenho um PostgreSQL instalado aqui para testar :slight_smile: )

rolipam

Olá entanglement, realmente essa seria uma solução parcial para o meu problema. Na verdade eu precisaria de algo um pouco mais complexo, já que a consulta ao BD é feita quando a tela principal do sistema abre e já é mostrado todos os clientes que ainda vão fazer aniversário a partir da data atual, ou seja, eu não quero ter que ficar consultando manualmente esses registros. Na tela principal do meu sistema eu já consegui implementar lembretes de reuniões agendadas e de contas com vencimentos próximos, todos organizados por data a partir da data atual, então, se eu conseguisse transformar a data de nascimento no ano corrente, era só ordenar por ordem crescente de data e pronto. Por isso a solução de somar ‘x year’ à coluna data_nascimento seria perfeita para o meu propósito, mas como ainda não testei, não sei se vou conseguir dessa forma. Se eu conseguir, eu posto a solução completa no Fórum! Mas de qualquer forma valeu pela dica!

rolipam

É possível, pelo menos, agora que a data de nascimento está sendo salva como tipo date (yyyy-MM-dd) ordenar essas datas por mês seguida pelo dia (tipo: 21/01/1967 - 02/02/1972 - 13/03/1947 - 17/03/1990 - etc), ignorando o ano (seja no SQL ou no Java)? Isso já ajudaria bastante. Aguardo qualquer solução que atenda a minha necessidade. Valeu Galega e mais uma vez obrigado!

Criado 14 de agosto de 2012
Ultima resposta 17 de ago. de 2012
Respostas 15
Participantes 4