Java.sql.Timestamp est-il spécifique au fuseau horaire?

Je dois stocker UTC dateTime dans DB.
J’ai converti le dateTime donné dans un fuseau horaire spécifique en UTC. pour cela j’ai suivi le code ci-dessous.
Mon entrée dateTime est “20121225 10:00:00 Z” le fuseau horaire est “Asia / Calcutta”
Mon serveur / DB (oracle) fonctionne dans le même fuseau horaire (IST) “Asia / Calcutta”

Obtient l’object Date dans ce fuseau horaire spécifique

Ssortingng date = "20121225 10:00:00 Z"; Ssortingng timeZoneId = "Asia/Calcutta"; TimeZone timeZone = TimeZone.getTimeZone(timeZoneId); DateFormat dateFormatLocal = new SimpleDateFormat("yyyyMMdd HH:mm:ss z"); //This date object is given time and given timezone java.util.Date parsedDate = dateFormatLocal.parse(date + " " + timeZone.getDisplayName(false, TimeZone.SHORT)); if (timeZone.inDaylightTime(parsedDate)) { // We need to re-parse because we don't know if the date // is DST until it is parsed... parsedDate = dateFormatLocal.parse(date + " " + timeZone.getDisplayName(true, TimeZone.SHORT)); } //assigning to the java.sql.TimeStamp instace variable obj.setTsSchedStartTime(new java.sql.Timestamp(parsedDate.getTime())); 

Stocker dans DB

  if (tsSchedStartTime != null) { stmt.setTimestamp(11, tsSchedStartTime); } else { stmt.setNull(11, java.sql.Types.DATE); } 

SORTIE

DB (oracle) a enregistré la même date et dateTime: "20121225 10:00:00 pas en UTC.

J’ai confirmé depuis le sql ci-dessous.

  select to_char(sched_start_time, 'yyyy/mm/dd hh24:mi:ss') from myTable 

Mon serveur de firebase database fonctionne également sur le même fuseau horaire “Asia / Calcutta”

Il me donne les apparences ci-dessous

  1. Date.getTime() n’est pas en UTC
  2. Ou l’horodatage a un impact sur le fuseau horaire lors du stockage dans la firebase database. Qu’est-ce que je fais mal ici?

Encore une question:

Est-ce que timeStamp.toSsortingng() s’imprime dans le fuseau horaire local comme le fait java.util.date ? Pas UTC?

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

Définit le paramètre désigné sur la valeur donnée java.sql.Timestamp , en utilisant l’object Calendar donné. Le pilote utilise l’object Calendar pour TIMESTAMP valeur SQL TIMESTAMP , que le pilote envoie ensuite à la firebase database. Avec un object Calendar , le pilote peut calculer l’horodatage en tenant compte d’un fuseau horaire personnalisé. Si aucun object Calendar n’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 heure sont celles stockées dans la firebase database et si la colonne de la firebase database ne stocke pas les informations de fuseau horaire, toutes les informations sur la zone sont perdues (ce qui signifie que la même fuseau horaire de manière cohérente ou proposer un autre schéma pour distinguer 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 firebase database est “2012-12-25 12:00:00”. Vous le récupérez à nouveau: vous le récupérez comme “2012-12-25 10:00:00 UTC” (mais seulement si vous le récupérez à l’aide de getTimestamp(..) ), mais lorsqu’une autre application accède à la firebase database dans le fuseau horaire GMT +0, il récupérera l’horodatage en tant que “2012-12-25 12:00:00 UTC”.

Si vous souhaitez le stocker dans un fuseau horaire différent, vous devez utiliser setTimestamp(int parameterIndex, Timestamp x, Calendar cal) avec une instance de calendrier dans le fuseau horaire requirejs. Veillez simplement à utiliser également le getter équivalent avec le même fuseau horaire lors de la récupération de valeurs (si vous utilisez un TIMESTAMP sans informations de fuseau horaire dans votre firebase database).

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

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

Avec JDBC 4.2, un pilote compatible doit prendre en charge java.time.LocalDateTime (et java.time.LocalTime ) pour TIMESTAMP (et TIME ) via get/set/updateObject . Les classes java.time.Local* sont sans java.time.Local* horaire, donc aucune conversion ne doit être appliquée (bien que cela puisse ouvrir une nouvelle série de problèmes si votre code prenait un fuseau horaire spécifique).

Je pense que la bonne réponse devrait être java.sql.Timestamp n’est pas spécifique au fuseau horaire. Horodatage est un composite de java.util.Date et une valeur séparée de nanosecondes. Il n’y a pas d’informations de fuseau horaire dans cette classe. Ainsi, tout comme Date, cette classe contient simplement le nombre de millisecondes écastings depuis le 1er janvier 1970 à 00:00:00 GMT + nanos.

Dans PreparedStatement.setTimestamp (int parameterIndex, Timestamp x, Calendar cal), le pilote utilise le calendrier pour modifier le fuseau horaire par défaut. Mais l’horodatage contient toujours des millisecondes en heure GMT.

L’API ne sait pas exactement comment le pilote JDBC doit utiliser le calendrier. Les fournisseurs semblent se sentir libres de l’interpréter, par exemple la dernière fois que j’ai travaillé avec MySQL 5.5 Calendar, le pilote a simplement ignoré Calendar dans PreparedStatement.setTimestamp et ResultSet.getTimestamp.

Il est spécifique à votre pilote. Vous devez fournir un paramètre dans votre programme Java pour lui indiquer le fuseau horaire que vous souhaitez utiliser.

 java -Duser.timezone="America/New_York" GetCurrentDateTimeZone 

Plus loin ceci:

 to_char(new_time(sched_start_time, 'CURRENT_TIMEZONE', 'NEW_TIMEZONE'), 'MM/DD/YY HH:MI AM') 

Peut également être utile pour gérer correctement la conversion. Prise d’ ici

Pour Mysql, nous avons une limitation. Dans le pilote Mysql doc , nous avons:

Voici quelques problèmes et limitations connus pour MySQL Connector / J: Lorsque Connector / J récupère des horodatages pour un jour de passage à l’heure d’été à l’aide de la méthode getTimeStamp () sur le jeu de résultats, certaines des valeurs renvoyées peuvent être erronées. Les erreurs peuvent être évitées en utilisant les options de connexion suivantes lors de la connexion à une firebase database:

 useTimezone=true useLegacyDatetimeCode=false serverTimezone=UTC 

Ainsi, lorsque nous n’utilisons pas ces parameters et que nous appelons setTimestamp or getTimestamp avec agenda ou sans calendrier, nous avons l’horodatage dans le fuseau horaire jvm.

Exemple :

Le fuseau horaire jvm est GMT + 2. Dans la firebase database, nous avons un horodatage: 1461100256 = 19/04/16 21: 10: 56,000000000 GMT

 Properties props = new Properties(); props.setProperty("user", "root"); props.setProperty("password", ""); props.setProperty("useTimezone", "true"); props.setProperty("useLegacyDatetimeCode", "false"); props.setProperty("serverTimezone", "UTC"); Connection con = DriverManager.getConnection(conSsortingng, props); ...... Calendar nowGMT = Calendar.getInstance(TimeZone.getTimeZone("GMT")); Calendar nowGMTPlus4 = Calendar.getInstance(TimeZone.getTimeZone("GMT+4")); ...... rs.getTimestamp("timestampColumn");//Oracle driver convert date to jvm timezone and Mysql convert date to GMT (specified in the parameter) rs.getTimestamp("timestampColumn", nowGMT);//convert date to GMT rs.getTimestamp("timestampColumn", nowGMTPlus4);//convert date to GMT+4 timezone 

La première méthode retourne: 1461100256000 = 19/04/2016 – 21:10:56 GMT

La seconde méthode retourne: 1461100256000 = 19/04/2016 – 21:10:56 GMT

La troisième méthode retourne: 1461085856000 = 19/04/2016 – 17:10:56 GMT

Au lieu d’Oracle, lorsque nous utilisons les mêmes appels, nous avons:

La première méthode retourne: 1461093056000 = 19/04/2016 – 19:10:56 GMT

La seconde méthode retourne: 1461100256000 = 19/04/2016 – 21:10:56 GMT

La troisième méthode retourne: 1461085856000 = 19/04/2016 – 17:10:56 GMT

NB: Il n’est pas nécessaire de spécifier les parameters pour Oracle.