Dans l'application que je développe, j'ai besoin de convertir l'objet Java.time.Instant en Java.sql.Timestamp. Lorsque je crée un objet Instant, par exemple
Instant now = Instant.now();
et inspecter l'élément. Je reçois quelque chose comme 2017-03-13T14:28:59.970Z
Ensuite, j'essaie de créer un objet Timestamp comme ceci:
Timestamp current = Timestamp.from(now);
Et quand j'inspecte l'élément. Je reçois quelque chose comme 2017-03-13T16:28:59.970Z
Le même résultat mais avec un décalage supplémentaire de 2 heures . Quelqu'un peut-il expliquer ce qui se passe et me donner une réponse pour résoudre ce problème sans décalage?.
Quand j'ai créé comme ça:
LocalDateTime ldt = LocalDateTime.ofInstant(Instnant.now(), ZoneOffset.UTC);
Timestamp current = Timestamp.valueOf(ldt);
Tout fonctionne bien. Mais j'essaie d'éviter les conversions. Est-il possible de faire cela uniquement en utilisant l'objet Instant?
J’ai modifié le fuseau horaire de mon ordinateur en Europe/Bucarest pour une expérience. Il s'agit de l'heure UTC + 2 heures correspondant à votre fuseau horaire.
Maintenant, quand je copie votre code, j'obtiens un résultat similaire au vôtre:
Instant now = Instant.now();
System.out.println(now); // prints 2017-03-14T06:16:32.621Z
Timestamp current = Timestamp.from(now);
System.out.println(current); // 2017-03-14 08:16:32.621
La sortie est donnée dans les commentaires. Cependant, je continue:
DateFormat df = DateFormat.getDateTimeInstance();
df.setTimeZone(TimeZone.getTimeZone("UTC"));
// the following prints: Timestamp in UTC: 14-03-2017 06:16:32
System.out.println("Timestamp in UTC: " + df.format(current));
Maintenant, vous pouvez voir que la Timestamp
correspond vraiment à la Instant
à partir de laquelle nous sommes partis (seules les millisecondes ne sont pas imprimées, mais j'espère qu'elles y sont également). Donc, vous avez tout fait correctement et ne vous êtes confus, car lorsque nous avons imprimé la variable Timestamp
, nous appelions implicitement sa méthode toString
. Cette méthode saisit à son tour le paramètre de fuseau horaire de l'ordinateur et affiche l'heure dans cette zone. Seulement pour cette raison, les affichages sont différents.
L’autre chose que vous avez tentée, en utilisant LocalDateTime
, semble fonctionner, mais elle ne vous donne vraiment pas ce que vous voulez:
LocalDateTime ldt = LocalDateTime.ofInstant(Instant.now(), ZoneOffset.UTC);
System.out.println(ldt); // 2017-03-14T06:16:32.819
current = Timestamp.valueOf(ldt);
System.out.println(current); // 2017-03-14 06:16:32.819
System.out.println("Timestamp in UTC: " + df.format(current)); // 14-03-2017 04:16:32
Maintenant, lorsque nous imprimons la Timestamp
à l’aide de notre UTC DateFormat
, nous pouvons constater qu’il est 2 heures trop tôt, 04:16:32 UTC lorsque la Instant
est 06:16:32 UTC. Donc, cette méthode est trompeuse, on dirait que ça marche, mais ça ne marche pas.
Cela montre les problèmes qui ont conduit à la conception des classes de date et d’heure Java 8 pour remplacer les anciennes. Donc, la vraie et bonne solution à votre problème serait probablement de vous procurer un pilote JDBC 4.2 capable d’accepter facilement un objet Instant
afin d’éviter toute conversion en Timestamp
. Je ne sais pas si cela est disponible pour vous, mais je suis convaincu que ce le sera.
Si vous voulez l'horodatage actuel, pourquoi ne pas utiliser la fonction suivante, je l'ai utilisée dans divers projets et fonctionne parfaitement
public static Timestamp getTimeStamp()
{
// Calendar information
Calendar calendar = Calendar.getInstance();
Java.util.Date now = calendar.getTime();
Timestamp dbStamp = new Timestamp(now.getTime());
return dbStamp;
}
Exemple:
System.out.println( getTimeStamp() );
Output: 2017-03-13 15: 01: 34.027
MODIFIER
Utilisation de Java 8 LocalDateTime:
public static Timestamp getTimeStamp()
{
return Timestamp.valueOf(LocalDateTime.now());
}
Lors de l'enregistrement d'un enregistrement dans SQL Server DB, j'ai rencontré le même problème. J'ai utilisé Java.sql.Timestamp.valueOf(String s)
pour obtenir Timestamp inUTC:
import Java.time.Instant;
import Java.time.format.DateTimeFormatter;
....
....
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").withZone(UTC);
String dateTime = dateTimeFormatter.format(Instant date);
Timestamp timestamp = Timestamp.valueOf(dateTime);
Ça marche pour moi.