Eu estou experimentando um comportamento muito estranho ao salvar datas no database. No meu servidor (Linux centOS 6.2) eu uso servidor de aplicativos glassfish (3.1.1 – build 12) e Java (1.7.0_09), o aplicativo é desenvolvido em Java + GWT, e usa o servidor PostgreSQL (9.2.1). Dentro do aplicativo existem vários campos de data que são salvos no database. Os campos de data usam datepicker (http://code.google.com/p/gwt-datepicker, r30).
O atributo date da relação db é o tipo de data (não timestamp). Algumas datas são salvas no dia anterior no database. O problema acontece apenas para datas entre intervalos, por exemplo, entre 31.03.1968 e 27.10.1968, o que me faz pensar em algum tipo de questão de horário de verão. Mas como isso não acontece em 1969, por exemplo, não posso isolar o problema muito bem. Estou tentando encontrar algum outro intervalo de datas dentro do qual o problema acontece. Por exemplo, se eu selecionar 19.05.1968 no aplicativo, depois de salvar no database, a data será salva como 18.05.1968.
O mais estranho é que eu tenho outra instância do mesmo aplicativo em outro servidor, e para as mesmas datas eles são salvos corretamente. Isso me faz pensar que o problema poderia confiar em:
Tentei definir para a Europa / Roma (meu fuso horário) todas as configurações possíveis do meu servidor, mas nada. Qualquer ideia? Como eu poderia resolver ou investigar esse problema?
ATUALIZAÇÃO: 1968 foi um ano bissexto. O problema também acontece em 1972, que é novamente um ano bissexto. Resumindo: o problema “data-salvo-um-dia-antes” acontece em anos bissextos durante o intervalo de data do horário de verão.
A parte do código onde o object de data é criado é:
Date d = dateField.getSelectedDate(); if (d != null) { txtVal = DateTimeFormat.getFormat("dd/MM/yyyy").format(d); }
onde dateField é declarado como:
transient private DatePicker dateField;
O pacote é org.zenika.widget.client.datePicker.DatePicker
(gwt-datepicker-r30 mencionado anteriormente) e DateTimeFormat refere-se a com.google.gwt.i18n.shared.DateTimeFormat
UPDATE depois de aceitar a resposta:
Eu usei esta solução alternativa: quando eu crio uma data, eu uso o seguinte código:
final long hours12 = 12L * 60L * 60L * 1000L; Date d = new Date(d1.getTime() + hours12);
Basta definir a hora da data para 12:00 (em vez do padrão 0:00) e você deve estar bem. A questão é que a biblioteca de fuso horário do GWT não inclui todos os anos bissextos anteriores a 1990 e, assim, você terá um tempo errado no servidor (já que o valor é enviado na forma de um registro de data e hora e tem uma hora de folga).
A propósito: o GWT tem um seletor de datas integrado, veja sua demonstração em http://gwt.google.com/samples/Showcase/Showcase.html#!CwDatePicker
Você está usando java.util.date ou java.sql. data (esta última é a correta)? Eu tive um problema semelhante com o SQL Server, mesmo que fosse regular e sim, relacionado com o horário de verão.
Basicamente, você armazena uma data Java como meia-noite de um dia específico. se, no verão, a data for movida para o dia anterior às 23:00 e, em seguida, a hora ficar truncada! Se você enviar a data com um carimbo de data “random”, você perceberá o problema uma vez em 24 durante o verão.
Não me lembro exatamente da solução (que não vai ajudá-lo diretamente, pois se refere a um DBMS diferente), mas havia uma configuração no dB para dizer “armazenar a data como você a recebe”. Você pode testar se esse é o caso alterando a dbcolumn para timestamp e observando como o tempo é armazenado.
Eu fiz um pouco de pesquisa – parece que o gwt-datepicker tem muitos problemas! http://code.google.com/p/google-apps-script-issues/issues/detail?id=2022 http://code.google.com/p/google-apps-script-issues/issues/detail id = 2001
Eu não ficaria surpreso se o cálculo deles tivesse um bug nos anos bissextos. Além disso, é inteiramente possível que seja apenas um descompasso entre o que você está fazendo e o que você pensa que está fazendo – trabalhar com o Dates é um assunto surpreendentemente difícil.
Para verificar, tente:
final java.util.Date ud = dateField.getSelectedDate();; final java.sql.Date sd = new java.sql.Date(ud.getTime()); System.out.println(ud);// this is what you pick from the DatePicker System.out.println(sd);// this is what will be stored on the database
E veja se eles combinam durante o verão nos anos bissextos. Se for um erro do GWT, http://code.google.com/p/google-apps-script-issues/ é o lugar certo para denunciá-lo
Enfrentou esta questão em tempo real para a data de nascimento.
Eu fiz a correção abaixo, de modo que, em vez de salvar uma data às 12 horas, a data será salva às 6 horas, que é antes do horário comercial do servidor. Até uma hora é deduzida, não afetará o dob.
Calendar now = Calendar.getInstance(); now.setTime(YOUR_DATE); now.set(Calendar.HOUR_OF_DAY, 6); YOUR_DATE = now.getTime();
Resposta Mikes está bem. Mas, se salvarmos às 12 horas, existe a possibilidade de erro na comparação de datas, se o usuário inserir a data durante o horário comercial antes das 12 horas.