Tenho um programa que salva um cadastro na base, Nome, CPF e DataNascimento.
Ao Salvar, os registros vão corretos.
Confiro na base e está correto (ex: Rebeca, 12345678900 19/12/1989)
Mas, ao fazer a listagem dos dados (buscando na base)
Os registros possuem um dia a menos na dataNascimento.
(Rebeca 12345678900 18/12/1989)
O que pode ser?
Eu utilizo
private DateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy");
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Locale.setDefault(new Locale("pt", "BR"));
MainFrame frame = new MainFrame();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
--------------
public String[][] listagem() throws NegocioException {
int numCols = 6;
String[][] listaRetorno = null;
try {
PessoaDAO pessoaDAO = new PessoaDAO();
List<PessoaDTO> lista = pessoaDAO.listarTodos();
listaRetorno = new String[lista.size()][numCols];
for (int i = 0; i < lista.size(); i++) {
PessoaDTO pessoa = lista.get(i);
listaRetorno[i][0] = pessoa.getIdPessoa().toString();
listaRetorno[i][1] = pessoa.getNome();
listaRetorno[i][2] = pessoa.getCpf().toString();
listaRetorno[i][3] = pessoa.getEndereco();
listaRetorno[i][4] = pessoa.getSexo() == 'M' ? "Masculino" : "Feminino";
listaRetorno[i][5] = dateFormat.format(pessoa.getDtNasc());
}
} catch (Exception exception) {
throw new NegocioException(exception.getMessage());
}
return listaRetorno;
}
Você pode manipular data como String (no banco como varchar), fiz isso e nunca mais tiver dor de cabeça. Simplesmente quando fazer a busca no banco de dados, faça a validação com SimpleDateFormat
Eu entendo que usar strings ao invés de dates possa parecer uma soluçao mais simples, mas acredito que a longo prazo isso traga mais dor de cabeça do que benefícios. Claro que no seu caso está funcionando, mas como conselho geral pode nao se adaptar em todos os casos.
Muitas pessoas confundem o que é um valor de um tipo de dados e o que é o formato aplicado aquele valor, quando se usa strings. Mantendo o tipo de dados correto, você só se preocupa com o valor. Mantendo como string, a pessoa tem que se preocupar com o valor e o formato sempre.
Esse artigo sobre tipos numéricos que mandou é justamente sobre nao usar o tipo incorreto para o problema. Sao dados que apesar de conterem números, nao sao dados numéricos (0 a esquerda é significante em CPF, formato é significante em telefone, etc).
Datas sao valores mais complexos e até por isso possuem um tipo específico para lidar com elas. Mantendo como tipo Date você tem uma garantia extra que as operaçoes efetuadas (comparar datas, números de dias entre duas datas, obter dia da semana, etc) podem ser efetuadas com sucesso sem precisar ficar dando parse a cada momento.
Se a logica da manipulação dos datas estiver no banco de dados, faz sentido você trabalha com esses tipos(Datetime, Timestamp). No mais não vejo como solução trabalha com classes que possui vários métodos deprecated (java.util.Date e java.sql.Date).
No próprio artigo do Alexandre (Caelum) ele fala bem sobre diferença
Manipular datas no Java sempre foi algo trabalhoso. No Java 1.0 havia apenas a classe Date, que era complicada de usar e não funcionava bem com internacionalização. Com o lançamento do Java 1.1, surgiu a classe abstrata Calendar, com muito mais recursos, porém com mutabilidade e decisões de design questionáveis.
O que pode estar acontecendo é que você tem um servidor num fuso horário diferente da máquina que está rodando sua aplicaçao.
Se teu Mysql estiver rodando em UTC, por exemplo, e sua máquina no horário de brasília, as datas ficaram 3 horas antes no seu fuso horário e portanto um dia a menos (já que a data tem horário zero)
Para confirmar se isto está acontecendo contigo, rode a seguinte query diretamente no mysql workbench:
SELECT NOW();
O horário mostrado nao deve ser igual ao da máquina que seu programa está rodando.
Um jeito de corrigir isso é passar um Calendar quando estiver obtendo a data do banco de dados:
É justo, mas geralmente esse tipo de problema é uma configuraçao que você tem uma vez e depois de resolvido, nao acontece mais.
Mas como varchar também tem um “preço” a pagar, pois você força todo mundo que for manipular essa coluna a estar ciente do formato que a data está gravada. Pode nao ser um problema em muitos casos, mas é um conhecimento a mais que as pessoas terao.
Pode acontecer algo como tentar inserir a data atual com a funçao now() mas o formato de data da sessao é diferente do padrao e gravar dados no formato errado. Coisas do gênero.
Mas isso é do lado do java, também nao defendo.
Mesmo antes do java 8, tinha a Joda time que ajudava muito a manter a sanidade.
O que eu nao recomendaria é que ao invés de usar java.util.Date a pessoa usasse String formatada para representar datas.