Comparer objet Date avec un TimeStamp en Java
Quand je l'ai tester ce code:
java.util.Date date = new java.util.Date();
java.util.Date stamp = new java.sql.Timestamp(date.getTime());
assertTrue(date.equals(stamp));
assertTrue(date.compareTo(stamp) == 0);
assertTrue(stamp.compareTo(date) == 0);
assertTrue(stamp.equals(date));
Mal-être attendre un vrai, vrai, vrai, faux. De ce fait:
Dans la javadoc de java.sql.Timestamp, il indique:
Remarque: Ce type est un composite de java.util.Date et un autre
nanosecondes valeur. Seulement partie intégrante secondes sont stockés dans le
java.util.Composant de Date. Les fractions de secondes - les nanos - sont
séparé. L'Horodatage.equals(Object) méthode ne retourne vrai lorsque
passé d'une valeur de type java.util.Date parce que les nanos composant d'un
la date est inconnue. En conséquence, l'Horodatage.equals(Object) la méthode est
pas symétrique par rapport à la java.util.Date.equals(Object)
la méthode. Aussi, la méthode hashcode utilise le sous-jacent de java.util.Date
la mise en œuvre et n'inclut donc pas les nanos dans son
le calcul.En raison des différences entre le Timestamp de la classe et de l'
java.util.Classe Date mentionnée ci-dessus, il est recommandé que le code n'
affichage des valeurs d'Horodatage génériquement comme une instance de java.util.Date.
La relation d'héritage entre l'Horodatage et la java.util.Date
vraiment désigne la mise en œuvre de l'héritage, et non pas le type d'héritage.
Mais plutôt Mauvais obtenir un true, false, true, false. Des idées?
EDIT: Ce problème apparaît lorsque je vérifiais les deux Dates avec la méthode equals, mais celui de l'objet Date viennent de Hibernate classe et de débogage je vois que l'objet contient un Horodatage. Donc, la méthode equals à false, alors j'ai trouvé ceci: http://mattfleming.com/node/141
Mais quand j'ai essayer le code que j'obtiens des résultats différents...si je ne peux utiliser ni d'égal à égal et compareTo, ce que je doit utiliser pour vérifier si les 2 Dates sont les mêmes?!?!
- En gros: si vous voulez comparer deux homogène des objets (soit la Date ou Timestamp), il n'y a pas de problème; il ne faut pas comparer deux objets hétéroclites. Nous pouvons essayer de résoudre le problème à la source, le sens: pourquoi avez-vous comparer?
- Im la comparaison de deux objets Date, mais l'objet implicite dans l'un d'eux est un TimeStamp est un type de Date. Si l'héritage fonctionne dans un autre objet, pourquoi pas ici?
- Parce que la mise en œuvre de
Timestamp
est stupide; vous devez traiter ces deux classes comme n'étant pas liés, tout comme l'intention de celui qui l'a écrit.
Vous devez vous connecter pour publier un commentaire.
tl;dr
Utiliser le moderne java.temps classes à la place de ceux gênants héritage de date-heure classes.
Vieille Date-Heure Classes Mal Conçu
Mettre plus crûment, la java.sql.Horodatage/.Date/.Du temps des classes est un hack, un mauvais hack. Comme java.util.Date/.Calendrier, ils sont le résultat d'un mauvais choix de conception.
La java.les types sql doit être utilisé, aussi brièvement que possible, utilisé seulement pour le transfert de données de la base de données. Ne pas utiliser pour la logique métier et la poursuite des travaux.
java.temps
La vieille date-heure classes ont été remplacés par les java.le temps cadre intégré dans Java 8 et les versions ultérieures. Ces nouvelles classes sont définies par la JSR 310, inspiré par la très réussie Joda-Time library, et prolongée par le ThreeTen-projet Extra.
Finalement, nous devrions voir des pilotes JDBC mis à jour à travailler directement avec ces java.les types d'heures. Mais jusqu'à ce jour nous avons besoin de les convertir vers/à partir de java.les types sql. Pour de telles conversions, appel de nouvelles méthodes ajoutées aux anciennes classes.
Un
Instantané
est un moment dans le scénario de l'UTC à une résolution de nanosecondes.Aller dans l'autre direction:
Appliquer une zone de temps pour obtenir horloge murale.
La java.les classes de temps propre a sagement choisi de conception de classe. Ainsi, vous pouvez utiliser le
equals
etcompareTo
comme prévu. Notez que les classes avec un décalage de l'UTC ou de fuseau horaire offrent égalementisEqual
,isBefore
, etisAfter
méthodes. Ces méthodes de comparer en considérant les moments sur la timeline, leur ordre chronologique. Leequals
etcompareTo
méthodes de considérer également le décalage de temps ou de zone.La réduction de l'utilisation de java.sql, tout en maximisant l'utilisation de java.temps, rend la Question de questions hypothétiques.
En veille prolongée, utiliser des convertisseurs pour java.temps.
JDBC 4.2
De JDBC 4.2 et versions ultérieures, vous ne devez pas utiliser l'héritage des classes à tous. Vous pouvez échanger directement des java.temps objets avec votre base de données via le
getObject
&setObject
méthodes.Et de la récupération.
Noter que de nombreuses bases de données ne peut pas stocker un moment avec une résolution aussi fine que les nanosecondes utilisé dans java.temps. Vous pouvez tronquer explicitement plutôt que de laisser votre Pilote JDBC faire implicitement.
Sur java.temps
La java.temps cadre est intégré dans Java 8 et les versions ultérieures. Ces classes permettent d'éviter la pénible vieux héritage date du temps des classes comme
java.util.Date
,Agenda
, &SimpleDateFormat
.La Joda-Time projet, maintenant dans le mode de maintenance, conseille la migration vers le java.le temps classes.
Pour en savoir plus, consultez les Oracle Tutoriel. Et de recherche de Débordement de Pile pour de nombreux exemples et des explications. La spécification est JSR 310.
Vous pouvez échanger java.temps objets directement avec votre base de données. Utiliser un Pilote JDBC compatible avec JDBC 4.2 ou plus tard. Pas besoin de chaînes, pas besoin de
java.sql.*
classes.Où obtenir le java.les classes de temps?
La ThreeTen-Extra projet s'étend java.temps avec d'autres classes. Ce projet est un terrain d'essai pour de possibles futurs ajouts à java.temps. Vous pouvez trouver quelques classes utiles ici comme
Intervalle
,YearWeek
,YearQuarter
, et plus.Nican expliqué le
equals
partie, surcompareTo
:Timestamp
a uncompareTo(Date)
méthode qui convertitTimestamp
en interneDate
la comparaison par passer (depuisTimestamp
est une sous-classe de celle-ci); mais comme la javadoc unis: "La relation d'héritage entre l'Horodatage et la java.util.Date vraiment désigne la mise en œuvre de l'héritage, et pas d'héritage de type"Qui bien sûr est une idée horrible, à mon avis.
J'ai eu le même problème dans un essai où j'ai voulu comparer
java.util.Date
etjava.sql.Timestamp
objets.Je les ai converti en
LocalDate
et ça a fonctionné:où
toLocalDate
est:date.est égal à(timbre) return true ET de timbre égal à(date) renvoie la valeur false. RAISON :Date néglige l'ordre de la nanoseconde partie de l'horodatage et depuis les autres parties arriver à être l'égal de sorte que le résultat est à la hauteur. Les fractions de secondes - les nanos - sont distinctes.L'Horodatage.equals(Object) méthode ne retourne vrai lorsqu'il est passé d'une valeur de type java.util.Date parce que les nanos composant d'une date est inconnue. Voir ici pour plus de détails
Timestamp
's nanos valeur n'est PAS le nombre de nanosecondes - c'est un ordre de la nanoseconde résolution numéro de millis (c'est à dire les fractions de secondes). Ainsi, dans leTimestamp
constructeur, il est le réglage de l'heure sur le super sans millisecondes. Par conséquent, laTimestamp
aura toujours une valeur plus faible pour le membrefastTime
(utilisé en Date ducompareTo()
) que le correspondant deDate
(à moins, bien sûr, il n'a pas de fractions de secondes).Vérifier la source de Timestamp à la ligne 110.
Essayer de recréer l'objet de la date à l'aide de "Cordes" comme ce
J'ai résolu la conversion à la fois la Date et l'Horodatage dans un Calendrier de l'objet, puis j'ai comparé le seul Calendrier propriétés:
Espère que cette aide.
Prendre un coup d'oeil au code source de la méthode de comparaison pour l'Horodatage:
http://www.docjar.com/html/api/java/sql/Timestamp.java.html
Il ne retourne true si la comparaison de l'objet est un timestamp.
Aussi, ici, est la Date à laquelle le code source: http://www.docjar.com/html/api/java/util/Date.java.html , et depuis Timestamp hérite Date, il est possible de le comparer.
compareTo()
, pasequals()
.Malheureusement, la
Timestamp
classe ne surcharge leequals(Object)
méthode avecequals(Timestamp)
donc des comparaisons sur les Horodateurs sont difficiles à faire.Dans le
equals(Object)
javadocs dit:Ma règle d'or est de ne jamais comparer les horodatages pour l'égalité (qui est à peu près inutile de toute façon), mais si vous avez à vérifier l'égalité, de les comparer en utilisant le résultat de
getTime()
(le nombre de millisecondes depuis le 1er janvier 1970, 00:00).equals()
mise en œuvre, de ne pas utiliser celui par défaut qui est ignorant de la valeur de données réelles.compareTo(String)
, comme ne Entier et ainsi de suite.Object
's est égal à la mise en œuvre. Timestamp remplaceDate
's est égal à la mise en œuvre.equals()
toutefois surcharger avez des problèmes décrits précédemment. LeComparable<T>
interface est encore plus strictes sur la mathématique des contraintes sur leurs éléments de la norme des collections triées de fonctionner correctement (comme le représentant de l'élément dans un ordre déterminé, et d'être compatible avec equals(), maisequals()
n'est même pas symétrique).Timestamp.equals(Date)
est une mauvaise idée (du moins tel qu'il est mis en œuvre), mais la réponse se réfère àTimestamp.equals(Timestamp)
.Une Petite note sur Implementaion de succession et d'héritage de Type..
"Un objet de la classe définit la manière dont l'objet est mis en œuvre. En revanche, un type de l'objet ne se réfère qu'à son interface. L'héritage de classe(mise en Œuvre de l'héritage) définit un objet de la mise en œuvre en termes d'un autre objet de la mise en œuvre. Type de l'héritage décrit lorsqu'un objet peut être utilisé à la place de l'autre."
L'horodatage et la Date de classes de mise en œuvre de l'héritage comme JAVADOC dit.