JPA TemporalType.Date à date erronée
J'ai une classe qui a un champ de date représentant une "valable à partir de la" date pour un élément de données. Il est défini comme ceci:
@Temporal( TemporalType.DATE )
private Date validFrom;
Tout semble bien fonctionner jusqu'au point où je tire la date à partir de la base de données et l'afficher. Si je sélectionne la date 18-Sep-2003 à l'extrémité avant de l'enregistrer quand je vérifie dans la base de données assez sûr que c'est la date de la tenue (la base de données est MySQL 5.5.9 colonne est de type DATE). Cependant quand j'ai tirer vers le haut une liste des dossiers la date indiquée est le 17 septembre 2003 - un jour plus tôt.
Si je choisis une date de début ou de la fin de l'année comme la 26 Mar 2003 ou 25 Décembre 2003, tout est parfait donc je deviner que c'est quelque chose à voir avec l'heure d'été, mais où est l'erreur rampante? Depuis la base de données semble tenir le bon jour, je devine que ça doit être quand JPA est la conversion de retour en java.util.Date - est de java.util.Date de la meilleure classe à utiliser pour une date? J'ai vu quelques exemples de cas où les gens utilisent le Calendrier, mais qui semble assez lourd de poids et je ne suis pas sûr de savoir comment il va travailler avec un JSF frontal.
Date
résoudre? J'espère java.util.Date
(correct) et pas java.sql.Date
? La simple raison est que, quand vous écrivez des entités, la JPA est d'essayer de mapper les propriétés d'entité de colonnes de base de données (et de genre) et java.sql.Date
est déjà mappé type. Si vous devez utiliser java.util.Date
. Veuillez également noter que, par exemple, p:calendar
(PrimeFaces) exige de la java.util.Date
et pas java.util.Calendar
(je suis tombé sur ça par moi-même). Voir: javabydeveloper.com/temporalOriginalL'auteur wobblycogs | 2011-03-14
Vous devez vous connecter pour publier un commentaire.
Très désolé, mais toutes les réponses sont généralement incorrect.
La réponse est assez simple, mais exige que nous nous séparons de cinq points:
Résumé: l'Utilisation UTC (GMT+0) sur le serveur, dans la base de données, vos objets Java.
DATE et l'HORODATAGE sont différents à partir d'une base de données de point de vue dans ce TIMESTAMP porte supplémentaire fractions de secondes. Les deux utilisent GMT+0 (implicite). JodaTime est un calendrier par défaut cadre pour répondre à tout cela, mais ne sera pas corrigé les questions de dépareillées JVM de base de données temps-paramètres de la zone.
Si les méthodologies d'application de la JVM de la DB ne pas utiliser GMT, en raison de la lumière du jour de l'épargne, de l'horloge réglages et toutes sortes d'autres jeux qui sont joués dans le monde, des horloges ... les délais de transactions et tout le reste sera toujours biaisée, non-référentielle, incohérent, etc.
Une autre bonne réponse similaire sur les types de données: java.util.Date vs java.sql.Date
Également noter que Java 8 a les mises à jour avec le meilleur de la date/heure de la manipulation (enfin), mais cela ne résout pas avoir l'horloge du serveur de la JVM en cours d'exécution sur être dans un fuseau horaire et de la base de données soit dans un autre. À ce stade, il y a toujours de la traduction qui se passe. Dans chaque grande (smart) client avec qui je travaille, la base de données et de la JVM serveur fuseaux horaires sont définis à l'UTC pour cette raison, même si leurs activités se produisent principalement dans certains autres fuseau horaire.
La question des références de la JPA Temporelle de type et associés java.util.Date d'objets, qui comprennent une composante temporelle. Quand il suffit de regarder le Jour du composant par exemple, actuellement, on est le 9 Mai à New York encore 10 Mai en Europe. Donc oui, l'heure et le fuseau horaire sont toujours un facteur important lors de l'évaluation de "quand" quelque chose s'est produite, comme l'ont expérimenté dans le détachement. Il n'est pas spécifique à EclipseLink que cette situation s'est produite et sera, dans tous les implémentations JPA, ou n'importe quel Java + DB de l'environnement depuis leur base de l'horloge de références peuvent être dans différents fuseaux horaires.
Je suis d'accord que le fuseau horaire est un facteur lorsque vous demandez: "quand" quelque chose s'est produite. Par exemple, lors de la journée "10/5/2015" a commencé à l'endroit précis sur la terre. Mais aussi longtemps que je travaille avec de pures valeurs de date, sans heure exacte du composant, la notation "10/5/2015" est la même dans tous les endroits. Bien sûr, il y a une question qu'advient-il lorsque vous appelez
getTime()
à cette date, et c'est là que les choses se compliquent avec les fuseaux horaires.Pour clarifier: Une Chaîne de caractères.equals() appel à la référence ci-dessus retournera true. La Conversion d'une Date (à l'aide de DateFormat par exemple) ne sera cependant PAS le retour de l'égalité pour la même valeur si les valeurs sont différentes. Une date est un point-à-temps comme une mesure de la valeur du nombre de millisecondes écoulées depuis l'Époque. Deux dates ne seront donc constante et égale (et implicite à "minuit" ce jour-là) si les composants sont de zéro et basé dans le (même) heure UTC de la zone. getTime() renvoie toujours zéro (comme il se doit - sens "minuit UTC ce jour-là").
OriginalL'auteur Darrell Teague
Après beaucoup d'expérimentation et de recherche, je suis assez sûr que j'en ai trouvé la cause du problème. La date est tenue en java.util.Date qui est livré avec tous les bagages de l'heure et du fuseau horaire. Il semblerait que JPA est la lecture de la date 18 Sep 2003 à partir de la base de données et le remplissage de la date comme ceci: "Thu Sep 18 00:00:00 BST 2003" - notez l'horaire a été fixé à la BST, probablement parce qu'il n'était pas explicitement défini par la base de données. De toute façon, il est nécessaire de formater la sortie dans le programme JSF page si vous voulez voir la date comme ceci:
Ceci, cependant, suppose que le fuseau horaire est celui qui est actuellement en vigueur sur la machine. Dans mon cas, le fuseau horaire est GMT actuellement (parce que c'est l'hiver) donc, lorsqu'ils sont présentés avec la date de "Jeu Sep 18 00:00:00 BST 2003" il la convertit à l'heure GMT en soustrayant une heure de quitter l'affichage de la 17 sept 2003.
Je suis actuellement à l'aide EclipseLink, je suis sûr que ce n'est pas une partie du problème. Ce qui semble se passer, c'est le convertisseur élément est en supposant qu'il faut afficher la date au format GMT même si c'est prévu dans la STB.
Cela peut ne pas être une bonne correction. Comme l'a dit, "... le fuseau horaire est actuellement GMT (parce que c'est l'hiver..." - donc ce qui se passe en Été dans cette région? Lutte avec bec et ongles pour obtenir les couches synchronisée sur l'heure GMT avec pas de compensations ou de changements et le reste va tomber en place. Sinon, le décalage des fuseaux horaires sur le calque sera toujours provoquer des erreurs à certains (voire inconnus).
Ah, d'accord. Je ne voyais pas cette réponse, lorsque j'ai écrit mon premier commentaire. Veuillez mettre à jour votre question en conséquence, de mentionner que vous avez, en effet, utiliser
java.util.Date
.Vérifiez également BalusC de réponse ici: stackoverflow.com/questions/7490954/...
OriginalL'auteur wobblycogs
Mais en utilisant DATETIME au lieu de la date de conduire à une heure (ou plus en fonction du fuseau horaire) de différence, vous pouvez l'ignorer si vous manipulez un jour, mais pas d'une valeur de temps.
Pour moi, les données provenant de la base de données mysql est la valeur correcte, mais la différence est venu lors de l'utilisation de la f:convertDateTime sans un fuseau horaire paramater, ce qui conduit à un défaut de l'aide GMT!
fonctionne bien, mais je pense que ce sera à ne pas travailler plus quand on passe CEST ....
OriginalL'auteur Michael Glockenstein
J'ai eu le même problème. Ne sais pas la raison, mais ma solution est la suivante:
Dans la base de données, j'ai changé le type de colonne de
DATE
àDATETIME
.Dans la classe d'entité, j'ai changé le
@Temporal
annotation, mais a gardé le type de donnéesDate
:OriginalL'auteur Matt Handy
J'ai été confronté à ce même problème mais j'ai été en utilisant JSF 2 l'extrémité avant. Si vous êtes à l'aide de composants JSF regarder cet autre stackoverflow de discussion et de voir que JSF 2 ne joue pas par le Fuseau horaire règles. Les concepteurs ont mis en œuvre à toujours utiliser GMT. Dans ma situation, cela a causé ma date de 5 ou 6 heures dans la base de données, mais s'affichent correctement.
JSF convertDateTime rend la journée précédente
OriginalL'auteur Revoman
Eu le même problème avec SQL Server. Le problème était un ancien pilote JDBC SQL. A sqljdbc4.jar à partir d'avril 2010, qui a été SQL 2000 compatible et a eu le problème avec les dates de retour d'un ou deux jours.
Ensuite mise à jour pour la dernière version du pilote, ou même à celui de 2012, et le problème a disparu.
OriginalL'auteur Robert Niestroj