Risposta breve:
Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
Date out = Date.from(ldt.atZone(ZoneId.systemDefault()).toInstant());
Spiegazione: (basato su questa domanda su LocalDate
)
Nonostante il suo nome, java.util.Date
rappresenta un istante sulla linea temporale, non una "data". I dati effettivi memorizzati nell'oggetto sono long
conteggi di millisecondi dal 1970-01-01T00: 00Z (mezzanotte all'inizio del 1970 GMT / UTC).
La classe equivalente a java.util.Date
in JSR-310 è Instant
, quindi ci sono metodi convenienti per fornire la conversione avanti e indietro:
Date input = new Date();
Instant instant = input.toInstant();
Date output = Date.from(instant);
Un java.util.Date
esempio ha il concetto di fuso orario. Questo potrebbe sembrare strano se si chiama toString()
a java.util.Date
, perché toString
è relativo a un fuso orario. Tuttavia, questo metodo utilizza effettivamente il fuso orario predefinito di Java al volo per fornire la stringa. Il fuso orario non fa parte dello stato attuale di java.util.Date
.
Una Instant
, inoltre, non contiene alcuna informazione circa il fuso orario. Pertanto, per convertire da una Instant
data a ora locale è necessario specificare un fuso orario. Questo potrebbe essere il fuso orario predefinito ZoneId.systemDefault()
- o potrebbe essere un fuso orario controllato dall'applicazione, ad esempio un fuso orario dalle preferenze dell'utente. LocalDateTime
ha un metodo di fabbrica conveniente che richiede sia l'istante che il fuso orario:
Date in = new Date();
LocalDateTime ldt = LocalDateTime.ofInstant(in.toInstant(), ZoneId.systemDefault());
Al contrario, il LocalDateTime
fuso orario viene specificato chiamando il atZone(ZoneId)
metodo. La ZonedDateTime
possono poi essere convertiti direttamente ad un Instant
:
LocalDateTime ldt = ...
ZonedDateTime zdt = ldt.atZone(ZoneId.systemDefault());
Date output = Date.from(zdt.toInstant());
Si noti che la conversione da LocalDateTime
a ZonedDateTime
ha il potenziale per introdurre comportamenti imprevisti. Questo perché non tutte le date-ora locali esistono a causa dell'ora legale. In autunno / autunno, c'è una sovrapposizione nella linea temporale locale in cui la stessa data-ora locale si verifica due volte. In primavera, c'è un vuoto, in cui scompare un'ora. Vedi il Javadoc atZone(ZoneId)
per ulteriori informazioni sulla definizione di cosa farà la conversione.
Sintesi, se di andata e ritorno una java.util.Date
ad una LocalDateTime
e di nuovo ad un java.util.Date
si può finire con un istante diverso a causa di ora legale.
Informazioni aggiuntive: c'è un'altra differenza che influenzerà le date molto vecchie. java.util.Date
usa un calendario che cambia al 15 ottobre 1582, con date precedenti a quella usando il calendario giuliano invece di quello gregoriano. Al contrario, java.time.*
utilizza il sistema di calendario ISO (equivalente al gregoriano) per tutti i tempi. Nella maggior parte dei casi d'uso, il sistema di calendario ISO è quello che desideri, ma potresti vedere strani effetti quando si confrontano le date prima dell'anno 1582.