Java-date enregistrée comme la veille

j'éprouve un comportement très étrange en sauvegardant des dates sur la base de données. Sur mon serveur (Linux centOS 6.2) j'utilise glassfish application server (3.1.1 - build 12) et Java (1.7.0_09), l'application est développée en Java + GWT, et elle utilise PostgreSQL server (9.2.1). À l'intérieur de l'application il y a plusieurs champs de date qui sont enregistrés sur le db. Les champs de date utilisent le curseur de données (http://code.google.com/p/gwt-datepicker, r30).

l'attribut date de la relation db est date type (pas de date). Certaines dates sont sauvegardées un jour avant dans la base de données. Le problème se pose uniquement pour les dates entre les intervalles, par exemple entre le 31.03.1968 et le 27.10.1968, ce qui me fait penser à une sorte de problème de l'heure d'été. Mais comme ce n'est pas le cas pour 1969, par exemple, Je ne peux pas très bien isoler le problème. J'essaie de trouver une autre date à l'intérieur de laquelle le problème se produit. par exemple, si je choisis 19.05.1968 dans l'application, après avoir enregistré dans la base de données la date est enregistrée comme 18.05.1968.

la chose étrange est que j'ai une autre instance de la même application sur un autre serveur, et pour les mêmes dates ils sont enregistrés correctement. Cela me fait penser que le problème pourrait s'appuyer sur:

  • GlassFish configuration;
  • java (java.util.Date de mise en œuvre?);
  • une sorte de configuration de serveur qui me manque

j'ai essayé de mettre en Europe / Rome (mon fuseau horaire) chaque configuration possible de mon serveur, mais rien. Une idée? Comment pourrais-je résoudre ce problème?

mise à jour: 1968 est une année bissextile. Le problème se pose également en 1972, qui est à nouveau une année bissextile. Résumer: le problème" date-saved-one-day-before " se produit dans les années bissextiles pendant l'intervalle de date de l'heure d'été.

la partie du code où la date oject est créée est:

Date d = dateField.getSelectedDate();
if (d != null) {
    txtVal = DateTimeFormat.getFormat("dd/MM/yyyy").format(d);
}

où le champ de données est déclaré comme:

transient private DatePicker dateField;

Le paquet est org.zenika.widget.client.datePicker.DatePicker (gwt-datepicker - R30 mentionné ci-dessus), et DateTimeFormat se réfère à com.google.gwt.i18n.shared.DateTimeFormat

mise à JOUR après l'acceptation de la réponse:

j'ai utilisé cette solution: quand je crée une date, j'utilise le code suivant:

final long hours12 = 12L * 60L * 60L * 1000L;
Date d = new Date(d1.getTime() + hours12);
17
demandé sur Lorenzo Marcon 2012-11-07 13:34:31

3 réponses

il suffit de définir l'Heure de la date à 12:00 (au lieu de 0:00 par défaut) et vous devriez être bien. Le problème est que la bibliothèque GWT time zone n'inclut pas toutes les années bissextiles d'avant 1990, et donc vous obtiendrez un mauvais moment au serveur (puisque la valeur est envoyée sous la forme d'une estampille de temps et est une heure hors).

Par la route: GWT est doté d'un sélecteur de date, voir sa démo à http://gwt.google.com/samples/Showcase/Showcase.html#!CwDatePicker

5
répondu MikeN 2012-11-08 09:46:26

Utilisez-vous java?util.date ou java.SQL. date (la dernière est la bonne)? J'ai eu un problème similaire avec SQL Server, même si C'était régulier et oui, lié à l'heure d'été.

en gros, vous stockez une date Java comme minuit d'un jour particulier. si l'été, la date est déplacée à la veille à 23h00, et l'heure est tronquée! Si vous envoyez la date avec un "hasard" timestamp vous rencontrerez le problème une fois sur 24 au cours de la été.

Je ne me souviens pas exactement de la solution (qui ne vous aidera pas directement car il se réfère à un SGBD différent) mais il y avait un paramètre dans le SGBD pour dire "stocker la date que vous recevez". Vous pouvez tester si c'est le cas en changeant le dbcolumn en timestamp et en regardant comment le temps est stocké.

j'ai fait un peu de recherche, il semble que le gwt-datepicker a beaucoup de questions! 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

je ne serais pas surpris si leur calcul a un bug sur les années bissextiles. En outre, il est tout à fait possible que ce soit juste un décalage entre ce que vous faites et ce que vous pensez faire - travailler avec des Dates est une question étonnamment difficile

Pour le vérifier, essayez:

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

Et voir si ils match pendant l'été sur les années bissextiles. Si c'est une GWT bug, http://code.google.com/p/google-apps-script-issues/ est le bon endroit pour le signaler

0
répondu thedayofcondor 2012-11-08 09:27:20

Face à ce problème en temps réel pour la date de naissance.

j'ai fait la correction ci-dessous, de sorte qu'au lieu de sauvegarder une date à 12 heures, la date sera sauvegardée à 6 heures qui est avant les heures d'ouverture du serveur. Même une heure est déduite, ça n'affectera pas dob.

Calendar now = Calendar.getInstance();
now.setTime(YOUR_DATE);
now.set(Calendar.HOUR_OF_DAY, 6);
YOUR_DATE = now.getTime();

Mikes réponse est très bien. Mais, si nous enregistrons avec 12 heures, il y a une possibilité d'erreur dans la comparaison de date, si l'utilisateur entre la date pendant les heures de travail avant 12 heures.

0
répondu Sreejesh.K.R. 2016-03-11 12:08:02