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.
)
Obwohl dieser Code oben keinen Sinn hatte. Beide java.util.Date
und Instant
repräsentieren einen Moment in UTC, immer in UTC. Der obige Code hat den gleichen Effekt wie:
new java.util.Date() // Capture current moment in UTC.
Kein Vorteil hier zu verwenden ZonedDateTime
. Wenn Sie bereits eine haben ZonedDateTime
, passen Sie UTC an, indem Sie a extrahieren 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.
)
Andere Antwort richtig
Die Antwort von ssoltanid behandelt Ihre spezifische Frage, wie ein java.time-Objekt ( ZonedDateTime
) der neuen Schule in ein Objekt der alten Schule konvertiert werden kann, korrekt java.util.Date
. Extrahieren Sie die Instant
aus der ZonedDateTime und übergeben Sie an java.util.Date.from()
.
Datenverlust
Beachten Sie, dass Sie einen Datenverlust erleiden , als Instant
Spuren ns seit Epoche , während java.util.Date
Spuren Millisekunden seit Epoche.
Ihre Frage und Ihre Kommentare werfen andere Fragen auf.
Server in UTC halten
Auf Ihren Servern sollte das Host-Betriebssystem generell auf UTC eingestellt sein. Die JVM übernimmt diese Host-Betriebssystemeinstellung als Standardzeitzone in den mir bekannten Java-Implementierungen.
Geben Sie die Zeitzone an
Sie sollten sich jedoch niemals auf die aktuelle Standardzeitzone der JVM verlassen. Anstatt die Hosteinstellung zu übernehmen, kann ein Flag, das beim Starten einer JVM übergeben wird, eine andere Zeitzone festlegen. Noch schlimmer: Jeder Code in einem Thread einer App kann jederzeit einen Aufruf tätigen java.util.TimeZone::setDefault
, um diesen Standard zur Laufzeit zu ändern!
Cassandra- Timestamp
Typ
Jede anständige Datenbank und jeder anständige Treiber sollte automatisch die Anpassung einer übergebenen Datums- und Uhrzeit an UTC zur Speicherung übernehmen. Ich benutze Cassandra nicht, aber es scheint eine rudimentäre Unterstützung für Datum und Uhrzeit zu haben. Die Dokumentation besagt, dass sein Timestamp
Typ eine Anzahl von Millisekunden aus derselben Epoche ist (erster Moment von 1970 in UTC).
ISO 8601
Darüber hinaus akzeptiert Cassandra Zeichenfolgeneingaben in den Standardformaten ISO 8601 . Glücklicherweise verwendet java.time die ISO 8601-Formate als Standard für das Parsen / Generieren von Zeichenfolgen. Die Implementierung der Instant
Klasse toString
wird gut funktionieren.
Präzision: Millisekunde gegen Nanosekord
Aber zuerst müssen wir die Nanosekundengenauigkeit von ZonedDateTime auf Millisekunden reduzieren. Eine Möglichkeit besteht darin, einen neuen Instant in Millisekunden zu erstellen. Glücklicherweise verfügt java.time über einige praktische Methoden zum Konvertieren in und aus Millisekunden.
Beispielcode
Hier ist ein Beispielcode in 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
Oder Sie können gemäß diesem Cassandra Java-Treiberdokument eine java.util.Date
Instanz übergeben (nicht zu verwechseln mit java.sqlDate
). Daraus können Sie instantTruncatedToMilliseconds
im obigen Code ein JuDate erstellen.
java.util.Date dateForCassandra = java.util.Date.from( instantTruncatedToMilliseconds );
Wenn Sie dies oft tun, können Sie einen Einzeiler erstellen.
java.util.Date dateForCassandra = java.util.Date.from( zdt.toInstant() );
Aber es wäre ordentlicher, eine kleine Dienstprogrammmethode zu erstellen.
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;
}
Beachten Sie den Unterschied in all diesem Code als in der Frage. Der Code der Frage versuchte, die Zeitzone der ZonedDateTime-Instanz an UTC anzupassen. Das ist aber nicht nötig. Konzeptionell:
ZonedDateTime = Instant + ZoneId
Wir extrahieren nur den Instant-Teil, der sich bereits in UTC befindet (im Grunde genommen in UTC, lesen Sie das Klassendokument für genaue Details).
Über java.time
Das java.time- Framework ist in Java 8 und höher integriert. Diese Klassen verdrängen die lästigen alten Legacy - Datum-Zeit - Klassen wie java.util.Date
, Calendar
, & SimpleDateFormat
.
Das Joda-Time- Projekt, das sich jetzt im Wartungsmodus befindet , empfiehlt die Migration zu den Klassen java.time .
Weitere Informationen finden Sie im Oracle-Lernprogramm . Suchen Sie im Stapelüberlauf nach vielen Beispielen und Erklärungen. Die Spezifikation ist JSR 310 .
Sie können java.time- Objekte direkt mit Ihrer Datenbank austauschen . Verwenden Sie einen JDBC-Treiber, der mit JDBC 4.2 oder höher kompatibel ist . Keine Notwendigkeit für Strings, keine Notwendigkeit für java.sql.*
Klassen.
Woher bekomme ich die java.time-Klassen?
Das ThreeTen-Extra- Projekt erweitert java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen von java.time. Sie können einige nützliche Klassen hier wie finden Interval
, YearWeek
, YearQuarter
, und mehr .
java.util.Date
undjava.sql.Date
.