Avant d'écrire un Java Date de SQL de la colonne TIMESTAMP, ne JDBC traduire la date de la JVM de fuseau horaire pour la session de base de données de fuseau horaire?
Avant d'écrire un Java Date SQL TIMESTAMP colonne, ne JDBC traduire la date à partir de la machine virtuelle Java de fuseau horaire à celui de la session de base de données?
Par exemple, supposons que la machine virtuelle Java de fuseau horaire est UTC et la session de base de données de fuseau horaire est UTC-5. Si un programme Java tente de stocker 2000-01-01 00:00:00
en la passant à PreparedStatement#setTimestamp(de type int Timestamp)
, selon le JDBC standard, la base de données du magasin TIMESTAMP '2000-01-01 00:00:00'
ou TIMESTAMP '1999-12-31 19:00:00'
?
- Les fuseaux horaires sont (ou devraient être) uniquement pour la présentation des dates, pas pour le stockage. Si aucune traduction ne devrait se produire. Toutefois, c'est de conjecturer, pas de réponse.
- Donc RedGrittyBrick, vous vous attendez à la base de données pour stocker
TIMESTAMP '2000-01-01 00:00:00'
? - RedGrittyBrick, fuseau horaire est pertinent pour les dates si vous stockez le fuseau horaire. Un SQL de la colonne TIMESTAMP ne stocke pas le temps de la zone, bien que, si elle fait sens pour stocker des dates indépendant de la localisation (qui est, par rapport au fuseau horaire UTC).
- RedGrittyBrick, le principal problème que j'essaie de comprendre, c'est comment, le cas échéant, JDBC standard nécessite un pilote JDBC de la mise en œuvre d'appliquer un fuseau horaire à une date à laquelle il transfère la date entre le JDBC client et le serveur de base de données.
- Voir aussi: stackoverflow.com/questions/2858182/...
InformationsquelleAutor Derek Mahar | 2010-11-08
Vous devez vous connecter pour publier un commentaire.
Non, JDBC est juste une API sur la façon dont le client peut accéder à la base de données. Pour le timestamp de stockage, cela doit dépendre de l'organisation qui écrit les pilotes de base de données qui est conforme à l'API JDBC standard.
Voici de mise en œuvre de MySQL mise en œuvre de
PreparedStatement
. Ils semblent prendre de Java JVM fuseau horaire pour MySQL Fuseau horaire (cocher lasetTimestampInternal()
méthode).setTimestampInternal()
se traduit par la date donnée pour la zone serveur de temps (x = TimeUtil.changeTimezone(this.connection, x, tz, 2059 this.connection.getServerTimezone());
). Il a également les formats de la date en une chaîne de caractères à l'aide deSimpleDateFormat
qui est locale dépendante.setTimestamp()
se traduit par la date donnée en utilisant la JVM de fuseau horaire. Voir les méthodesAbstractJdbc2Statement#setTimestamp(int, Timestamp, Calendar)
cvs.pgfoundry.org/cgi-bin/cvsweb.cgi/jdbc/pgjdbc/org/postgresql/... etTimestampUtils#toString(Calendar, Timestamp)
cvs.pgfoundry.org/cgi-bin/cvsweb.cgi/jdbc/pgjdbc/org/postgresql/.... Fuseau horaire la manipulation est pilote JDBC dépendants!datetime
champ comme le jour depuis 1900 et en millisecondes dans la journée et définir localesCalendar(1900, 0, dayN)
, si vous voulez travailler avec UTC - vous besoin deTimeZone.setDefault(TimeZone.getTimeZone("GMT+00:00"));
avant le chargement des pilotes, reportez-vous à stackoverflow.com/a/29705750/173149Maintenant, mon exigence est qu'il doit stocker la valeur dans l'heure GMT/UTC quel que soit le fuseau horaire de la JVM. Est-il un moyen de régler le fuseau horaire à la volée, puis à annuler une fois que je suis fait avec JDBC?
Edit:
Ok, j'ai trouvé un moyen de contourner ce problème. A la suite de
Vous pouvez utiliser surchargé
setTimestamp
setter accepterCalendar
exemple pour spécifier le fuseau horaireDe l'échantillon (Si vous utilisez Joda datetime):
Comme par javaDoc:
Définit le paramètre désigné à la
java.sql.Timestamp
valeur, en utilisant leCalendar
objet. Le pilote utilise laCalendar
objet de construire unSQL TIMESTAMP
de la valeur, le pilote envoie ensuite à la base de données. Avec unCalendar
objet, le conducteur peut calculer le timestamp en tenant compte d'un personnalisé du fuseau horaire. Si aucun Calendrier de l'objet est spécifié, le pilote utilise le fuseau horaire par défaut, qui est celui de la machine virtuelle qui exécute l'application.La spec est maladroit. La java.util.Date de magasins de millisecondes à partir de l'époque dans le GMT cadre de référence. Java.sql.Timestamp est une Date plus nanosecondes dans le même cadre de référence. Tous les non-déconseillé getters et setters utiliser le GMT cadre de référence. Pour toute sorte de raison, le fuseau horaire par défaut pour un stockage un Horodatage doit être GMT.
Dans un multi-niveaux de l'application, le front-end, le pilote, et le serveur de base de données pourraient tous être dans des fuseaux horaires différents. Certains des niveaux pourraient être dans des fuseaux horaires différents en même temps; par exemple, si vous faites de l'internet d'équilibrage de charge de l'échelle d'un continent, ou si vous avez une application mobile pour la connexion à un serveur central. Un nuage de l'environnement d'exploitation serait bien le même scénario où vous n'avez aucune idée de l'endroit où le pilote JDBC être en cours d'exécution, ni aucune garantie qui ne changera jamais.
Le seul moyen que je connaisse pour assurer la cohérence dans ces environnements est à utiliser uniquement le paramètre set et des ResultSet getter qui acceptent un Calendrier, et assurez-vous que chaque application qui accède aux données utilise la certains de calendrier, de préférence GMT ou UTC.