tl; dr
java.util.Date.from( // Transfer the moment in UTC, truncating any microseconds or nanoseconds to milliseconds.
Instant.now() ; // Capture current moment in UTC, with resolution as fine as nanoseconds.
)
Bien qu'il n'y ait aucun intérêt dans ce code ci-dessus. Les deux java.util.Date
et Instant
représentent un moment en UTC, toujours en UTC. Le code ci-dessus a le même effet que:
new java.util.Date() // Capture current moment in UTC.
Aucun avantage ici à utiliser ZonedDateTime
. Si vous avez déjà un ZonedDateTime
, ajustez à UTC en extrayant un fichier Instant
.
java.util.Date.from( // Truncates any micros/nanos.
myZonedDateTime.toInstant() // Adjust to UTC. Same moment, same point on the timeline, different wall-clock time.
)
Autre réponse correcte
La réponse de ssoltanid répond correctement à votre question spécifique, comment convertir un objet java.time ( ZonedDateTime
) de la nouvelle école en un objet de la vieille école java.util.Date
. Extrayez le Instant
de ZonedDateTime et passez à java.util.Date.from()
.
Perte de données
Notez que vous subir une perte de données , comme des Instant
pistes nanosecondes depuis l' époque en java.util.Date
pistes millisecondes depuis l' époque.
Votre question et vos commentaires soulèvent d'autres problèmes.
Gardez les serveurs en UTC
Vos serveurs doivent avoir leur système d'exploitation hôte défini sur UTC comme meilleure pratique en général. La JVM prend ce paramètre du système d'exploitation hôte comme son fuseau horaire par défaut, dans les implémentations Java dont je suis conscient.
Spécifiez le fuseau horaire
Mais vous ne devez jamais vous fier au fuseau horaire par défaut actuel de la JVM. Plutôt que de choisir le paramètre d'hôte, un indicateur passé lors du lancement d'une JVM peut définir un autre fuseau horaire. Pire encore: n'importe quel code dans n'importe quel thread de n'importe quelle application à tout moment peut faire un appel java.util.TimeZone::setDefault
pour changer cette valeur par défaut au moment de l'exécution!
Timestamp
Type de Cassandra
Toute base de données et pilote décents doivent automatiquement gérer l'ajustement d'une date-heure passée à UTC pour le stockage. Je n'utilise pas Cassandra, mais il semble avoir un support rudimentaire pour la date-heure. La documentation indique que son Timestamp
type est un décompte de millisecondes de la même époque (premier moment de 1970 en UTC).
ISO 8601
De plus, Cassandra accepte les entrées de chaîne dans les formats standard ISO 8601 . Heureusement, java.time utilise les formats ISO 8601 par défaut pour analyser / générer des chaînes. L' implémentation de Instant
la classe toString
fera l'affaire.
Précision: Milliseconde vs Nanosecord
Mais d'abord, nous devons réduire la précision nanoseconde de ZonedDateTime à quelques millisecondes. Une façon consiste à créer un nouvel instantané en millisecondes. Heureusement, java.time propose des méthodes pratiques pour convertir vers et depuis des millisecondes.
Exemple de code
Voici un exemple de code dans Java 8 Update 60.
ZonedDateTime zdt = ZonedDateTime.now( ZoneId.of( "America/Montreal" ) );
…
Instant instant = zdt.toInstant();
Instant instantTruncatedToMilliseconds = Instant.ofEpochMilli( instant.toEpochMilli() );
String fodderForCassandra = instantTruncatedToMilliseconds.toString(); // Example: 2015-08-18T06:36:40.321Z
Ou selon ce document de pilote Java Cassandra , vous pouvez passer une java.util.Date
instance (à ne pas confondre avec java.sqlDate
). Vous pouvez donc créer un juDate à partir de cela instantTruncatedToMilliseconds
dans le code ci-dessus.
java.util.Date dateForCassandra = java.util.Date.from( instantTruncatedToMilliseconds );
Si vous faites cela souvent, vous pouvez créer une doublure unique.
java.util.Date dateForCassandra = java.util.Date.from( zdt.toInstant() );
Mais il serait plus judicieux de créer une petite méthode utilitaire.
static public java.util.Date toJavaUtilDateFromZonedDateTime ( ZonedDateTime zdt ) {
Instant instant = zdt.toInstant();
// Data-loss, going from nanosecond resolution to milliseconds.
java.util.Date utilDate = java.util.Date.from( instant ) ;
return utilDate;
}
Notez la différence dans tout ce code que dans la question. Le code de la question essayait d'ajuster le fuseau horaire de l'instance ZonedDateTime à UTC. Mais ce n'est pas nécessaire. Conceptuellement:
ZonedDateTime = Instant + ZoneId
Nous extrayons simplement la partie Instant, qui est déjà en UTC (essentiellement en UTC, lisez la documentation de la classe pour plus de détails).
À propos de java.time
Le framework java.time est intégré à Java 8 et versions ultérieures. Ces classes supplantent les anciens gênants hérités des classes date-heure tels que java.util.Date
, Calendar
, et SimpleDateFormat
.
Le projet Joda-Time , désormais en mode maintenance , conseille la migration vers les classes java.time .
Pour en savoir plus, consultez le didacticiel Oracle . Et recherchez Stack Overflow pour de nombreux exemples et explications. La spécification est JSR 310 .
Vous pouvez échanger des objets java.time directement avec votre base de données. Utilisez un pilote JDBC compatible avec JDBC 4.2 ou version ultérieure. Pas besoin de chaînes, pas besoin de java.sql.*
classes.
Où obtenir les classes java.time?
Le projet ThreeTen-Extra étend java.time avec des classes supplémentaires. Ce projet est un terrain d'essai pour d'éventuels futurs ajouts à java.time. Vous trouverez peut - être des classes utiles ici, comme Interval
, YearWeek
, YearQuarter
et plus .
java.util.Date
etjava.sql.Date
.