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.
)
Sebbene non ci fosse alcun punto in quel codice sopra. Entrambi java.util.Date
e Instant
rappresentano un momento in UTC, sempre in UTC. Il codice sopra ha lo stesso effetto di:
new java.util.Date() // Capture current moment in UTC.
Nessun vantaggio qui per l'utilizzo ZonedDateTime
. Se hai già un ZonedDateTime
, regola su UTC estraendo un file 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.
)
Altra risposta corretta
La risposta di ssoltanid affronta correttamente la tua domanda specifica, come convertire un oggetto java.time di nuova scuola in un oggetto ZonedDateTime
di vecchia scuola java.util.Date
. Estrarre il Instant
da ZonedDateTime e passare a java.util.Date.from()
.
Perdita di dati
Si noti che si soffre di perdita di dati , come Instant
tracce nanosecondi dal epoca , mentre java.util.Date
le tracce millisecondi dal epoca.
La tua domanda e i tuoi commenti sollevano altri problemi.
Mantieni i server in UTC
I tuoi server dovrebbero avere il loro sistema operativo host impostato su UTC come best practice in generale. La JVM riprende questa impostazione del sistema operativo host come fuso orario predefinito, nelle implementazioni Java di cui sono a conoscenza.
Specificare il fuso orario
Ma non dovresti mai fare affidamento sul fuso orario predefinito corrente della JVM. Invece di prendere l'impostazione dell'host, un flag passato all'avvio di una JVM può impostare un altro fuso orario. Ancora peggio: qualsiasi codice in qualsiasi thread di qualsiasi app in qualsiasi momento può effettuare una chiamata a java.util.TimeZone::setDefault
per modificare l'impostazione predefinita in fase di esecuzione!
Timestamp
Tipo Cassandra
Qualsiasi database e driver decente dovrebbe gestire automaticamente la regolazione di una data-ora passata su UTC per l'archiviazione. Non uso Cassandra, ma sembra avere un supporto rudimentale per la data e l'ora. La documentazione dice che il suo Timestamp
tipo è un conteggio di millisecondi della stessa epoca (primo momento del 1970 in UTC).
ISO 8601
Inoltre, Cassandra accetta input di stringhe nei formati standard ISO 8601 . Fortunatamente, java.time utilizza i formati ISO 8601 come impostazioni predefinite per l'analisi / la generazione di stringhe. L' implementazione della Instant
classe toString
andrà bene.
Precisione: millisecondi vs nanosecord
Ma prima dobbiamo ridurre la precisione in nanosecondi di ZonedDateTime a millisecondi. Un modo è creare un nuovo istantaneo usando i millisecondi. Fortunatamente, java.time ha alcuni metodi utili per la conversione in e da millisecondi.
Codice di esempio
Di seguito è riportato un codice di esempio 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
O secondo questo documento del driver Java Cassandra , puoi passare java.util.Date
un'istanza (da non confondere con java.sqlDate
). Quindi potresti creare un juDate da quello instantTruncatedToMilliseconds
nel codice sopra.
java.util.Date dateForCassandra = java.util.Date.from( instantTruncatedToMilliseconds );
Se lo fai spesso, potresti creare una battuta.
java.util.Date dateForCassandra = java.util.Date.from( zdt.toInstant() );
Ma sarebbe più ordinato creare un piccolo metodo di utilità.
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;
}
Notare la differenza in tutto questo codice rispetto alla domanda. Il codice della domanda stava tentando di regolare il fuso orario dell'istanza di ZonedDateTime su UTC. Ma non è necessario. Concettualmente:
ZonedDateTime = Istantaneo + ZoneId
Estraiamo solo la parte Instant, che è già in UTC (fondamentalmente in UTC, leggi il documento di classe per dettagli precisi).
Informazioni su java.time
Il framework java.time è integrato in Java 8 e versioni successive. Queste classi soppiantare la vecchia fastidiosi legacy classi data-time come java.util.Date
, Calendar
, e SimpleDateFormat
.
Il progetto Joda-Time , ora in modalità di manutenzione , consiglia la migrazione alle classi java.time .
Per saperne di più, vedere il tutorial Oracle . E cerca Stack Overflow per molti esempi e spiegazioni. La specifica è JSR 310 .
Puoi scambiare oggetti java.time direttamente con il tuo database. Utilizza un driver JDBC conforme a JDBC 4.2 o successivo. Non c'è bisogno di stringhe, non c'è bisogno di java.sql.*
classi.
Dove ottenere le classi java.time?
Il progetto ThreeTen-Extra estende java.time con classi aggiuntive. Questo progetto è un banco di prova per possibili future aggiunte a java.time. Si possono trovare alcune classi utili, come per esempio Interval
, YearWeek
, YearQuarter
e altro .
java.util.Date
ejava.sql.Date
.