Oracle
 sql >> Base de données >  >> RDS >> Oracle

Le fuseau horaire java.sql.Timestamp est-il spécifique ?

Bien que cela ne soit pas explicitement spécifié pour setTimestamp(int parameterIndex, Timestamp x) les conducteurs doivent suivre les règles établies par le setTimestamp(int parameterIndex, Timestamp x, Calendar cal) javadoc :

Définit le paramètre désigné sur le java.sql.Timestamp donné valeur, en utilisant le Calendar donné objet. Le chauffeur utilise le Calendar objet pour construire un SQL TIMESTAMP valeur, que le pilote envoie ensuite à la base de données. Avec un Calendar objet, le conducteur peut calculer l'horodatage en tenant compte d'un fuseau horaire personnalisé. Si aucun Calendar objet est spécifié, le pilote utilise le fuseau horaire par défaut, qui est celui de la machine virtuelle exécutant l'application.

Lorsque vous appelez avec setTimestamp(int parameterIndex, Timestamp x) le pilote JDBC utilise le fuseau horaire de la machine virtuelle pour calculer la date et l'heure de l'horodatage dans ce fuseau horaire. Cette date et cette heure sont stockées dans la base de données, et si la colonne de la base de données ne stocke pas d'informations sur le fuseau horaire, toutes les informations sur le fuseau sont perdues (ce qui signifie qu'il appartient à l'application ou aux applications utilisant la base de données d'utiliser le même fuseau horaire de manière cohérente ou proposer un autre schéma pour discerner le fuseau horaire (c'est-à-dire stocker dans une colonne séparée).

Par exemple :Votre fuseau horaire local est GMT+2. Vous stockez "2012-12-25 10:00:00 UTC". La valeur réelle stockée dans la base de données est "2012-12-25 12:00:00". Vous le récupérez à nouveau :vous le récupérez à nouveau sous la forme "2012-12-25 10:00:00 UTC" (mais uniquement si vous le récupérez en utilisant getTimestamp(..) ), mais lorsqu'une autre application accède à la base de données dans le fuseau horaire GMT+0, elle récupère l'horodatage sous la forme "2012-12-25 12:00:00 UTC".

Si vous souhaitez le stocker dans un fuseau horaire différent, vous devez utiliser le setTimestamp(int parameterIndex, Timestamp x, Calendar cal) avec une instance Calendar dans le fuseau horaire requis. Assurez-vous simplement que vous utilisez également le getter équivalent avec le même fuseau horaire lors de la récupération des valeurs (si vous utilisez un TIMESTAMP sans informations de fuseau horaire dans votre base de données).

Donc, en supposant que vous souhaitiez stocker le fuseau horaire GMT réel, vous devez utiliser :

Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
stmt.setTimestamp(11, tsSchedStartTime, cal);

Avec JDBC 4.2, un pilote conforme doit prendre en charge java.time.LocalDateTime (et java.time.LocalTime ) pour TIMESTAMP (et TIME ) via get/set/updateObject . Le java.time.Local* les classes sont sans fuseaux horaires, donc aucune conversion ne doit être appliquée (bien que cela puisse ouvrir un nouvel ensemble de problèmes si votre code supposait un fuseau horaire spécifique).