Question

Je travaille avec des services Web, en insérant des enregistrements, qui renvoient une valeur d'horodatage de type XMLGregorianCalendar.Je dois le transformer en valeur java.sql.Timestamp, j'utilise donc une fonction comme celle-ci.

public static java.sql.Timestamp getSqlTimeStamp(XMLGregorianCalendar xgc) {
    if (xgc == null) {
        return null;
    } else {
        return new Timestamp(xgc.toGregorianCalendar().getTime().getTime());
    }
}
Timestamp timestamp=getSqlTimeStamp(ExitInXMLGregor.getTimestamp());

Mon problème est que sur le serveur, la valeur d'horodatage lorsque j'insère un enregistrement ressemble à ceci :10/03/2012 19:23:22

Mais lorsque j'effectue ma conversion de type, j'obtiens la valeur d'horodatage comme ceci :10/03/2012 17:23:22

L'heure sur le serveur (où se trouve le service Web) est de 2 heures supérieure à celle de mes paramètres régionaux, et pour une raison quelconque, j'obtiens mon heure d'insertion de paramètres régionaux, après l'avoir transformée.Le problème est que j'ai vraiment besoin d'obtenir l'heure du serveur, car dans la base de données, la valeur d'horodatage correspond à celle du serveur, et j'ai des problèmes lors de l'opération de mise à jour, en raison des différentes valeurs d'horodatage.

S'il vous plaît, j'apprécierais toute sorte d'aide.merci!

Modifier:Je trouve en quelque sorte une solution, mais ce n'est pas exactement ce dont j'ai besoin.Lorsque je convertis mon horodatage au format java.sql.Timestamp en XMLGregorian, je définis le timeZone du serveur (setTimeZone(TimeZone.getTimeZone("GMT+02:00"))).Cela fonctionne réellement, mais est loin d'être la solution idéale (Il pourrait arriver que le fuseau horaire ou même le serveur change) Ce serait bien de connaître à ce stade le fuseau horaire du serveur de manière dynamique, mais je ne sais pas comment.. .

public static XMLGregorianCalendar getXMLGregorianCalendar(Timestamp timestamp)
        throws BaseException {
    try {
        GregorianCalendar gc = new GregorianCalendar();
        gc.setTimeZone(TimeZone.getTimeZone("GMT+02:00"));
        gc.setTimeInMillis(timestamp.getTime());
        return DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
    } catch (DatatypeConfigurationException ex) {
        throw new BaseException(ex);
    }
}
Était-ce utile?

La solution

Je soupçonne que l'horodatage spécifie la bonne heure, ne s'affiche pas avec le bon fuseau horaire. 2012-10-03T17: 23: 22.342 est la même que 2012-10-03T19: 23: 22.342 + 02: 00, en supposant que le fuseau horaire (caché) de l'ancien est de +00: 00.

Autres conseils

tl;dr

  • Les deux chaînes représentent le même moment, simplement ajusté à un fuseau horaire sans noter le décalage par rapport à UTC.
  • Évitez une telle confusion en incluant toujours les informations de décalage et de zone dans ces chaînes.
  • Utiliser le moderne java.time des classes qui supplantent les classes héritées gênantes.(Instant, pas Timestamp)

Exemple de code.

myPreparedStatement.setObject( 
    … , 
    myXMLGregorianCalendar  // If forced to work with a `javax.xml.datatype.XMLGregorianCalendar` object rather than a modern java.time class…
    .toGregorianCalendar()  // …convert to a `java.util.GregorianCalendar`, and then…
    .toZonedDateTime()      // …convert to modern `java.time.ZonedDateTime` class.
    .toInstant()            // Adjust to UTC by extracting an `Instant` object.
)

Récupération à partir d'une base de données, à partir de JDBC 4.2 et versions ultérieures.

Instant instant = myResultSet.getObject( … , Instant.class ) ;

java.time

Comme le correcte acceptée Réponse de Robert Tupelo-Schneck dit, il semble que tout va bien dans la mesure où les deux chaînes représentent le même moment mais ajustées dans un fuseau horaire différent avec un décalage par rapport à UTC différent.Le problème est qu'il manque à l'une de ces deux chaînes un indicateur de son décalage par rapport à UTC.

Une telle omission est une mauvaise pratique car elle crée cette confusion.Incluez toujours le décalage par rapport à UTC, sauf si vous êtes absolument certain que le contexte rend le décalage/zone clair.

Travailler en UTC

Travailler en UTC évite ce genre de confusion.Il est généralement préférable de travailler, de stocker et d'échanger des valeurs date-heure en UTC.Ajustez de UTC à un fuseau horaire uniquement pour la présentation à l'utilisateur ou lorsque la logique métier l'exige.

De plus, vous utilisez d'anciennes classes terriblement gênantes qui sont maintenant supplantées par les java.time Des classes.Convertissez votre XMLGregorianCalendar à java.time.ZonedDateTime.

ZonedDateTime zdt = myXMLGregorianCalendar.toGregorianCalendar().toZonedDateTime() ;

Ajustez à UTC en extrayant un Instant objet.

Instant instant = zdt.toInstant() ;

Depuis JDBC 4.2 et versions ultérieures, vous pouvez directement échanger java.time objets avec la base de données.Pas besoin d'utiliser l'héritage java.sql.Timestamp à nouveau la classe.

myPreparedStatement.setObject( … , instant ) ;

Récupération:

Instant instant = myResultSet.getObject( … , Instant.class ) ;

Ajustez l'UTC à un fuseau horaire particulier si vous souhaitez visualiser le même moment en utilisant l'heure de l'horloge murale utilisée par les habitants d'une région particulière.

ZoneId z = ZoneId.of( "Africa/Tunis" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

Convertir

Si vous devez vous connecter à un ancien code nécessitant un java.sql.Timestamp, vous pouvez effectuer des conversions aller-retour avec java.time.Instant.Appelez de nouvelles méthodes de conversion ajoutées aux anciennes classes.

java.sql.Timestamp ts = java.sql.Timestamp.from( instant ) ;

Aller dans l’autre sens.

Instant instant = ts.toInstant() ;

Voir également ma réponse à une question similaire.


À propos java.time

Le java.time Le framework est intégré à Java 8 et versions ultérieures.Ces cours supplantent les vieux pénibles héritage cours date-heure tels que java.util.Date, Calendar, & SimpleDateFormat.

Le Joda-Time projet, maintenant en Mode de Maintenance, conseille la migration vers le java.time Des classes.

Pour en savoir plus, consultez le Tutoriel Oracle.Et recherchez Stack Overflow pour de nombreux exemples et explications.La spécification est JSR310.

Vous pouvez échanger java.time objets directement avec votre base de données.Utiliser un Pilote JDBC conforme à JDBC4.2 ou plus tard.Pas besoin de cordes, pas besoin de java.sql.* Des classes.

Où obtenir les classes java.time ?

Le TroisDix-Extra le projet étend java.time avec des classes supplémentaires.Ce projet est un terrain d'essai pour d'éventuels futurs ajouts à java.time.Vous pouvez trouver ici des cours utiles tels que Interval, YearWeek, YearQuarter, et plus.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top