tl; dr
Come convertire java.util.Date in java.sql.Date?
Non farlo. Entrambe le classi sono obsolete.
- Utilizzare le classi java.time anziché legacy
java.util.Date
e java.sql.Date
con JDBC 4.2 o versioni successive.
- Converti in / da java.time se interagisce con il codice non ancora aggiornato in java.time.
Query di esempio con PreparedStatement
.
myPreparedStatement.setObject(
… , // Specify the ordinal number of which argument in SQL statement.
myJavaUtilDate.toInstant() // Convert from legacy class `java.util.Date` (a moment in UTC) to a modern `java.time.Instant` (a moment in UTC).
.atZone( ZoneId.of( "Africa/Tunis" ) ) // Adjust from UTC to a particular time zone, to determine a date. Instantiating a `ZonedDateTime`.
.toLocalDate() // Extract a date-only `java.time.LocalDate` object from the date-time `ZonedDateTime` object.
)
A disposizione:
Instant
invece di java.util.Date
Entrambi rappresentano un momento in UTC. ma ora con nanosecondi anziché millisecondi.
LocalDate
anziché java.sql.Date
Entrambi rappresentano un valore di sola data senza ora del giorno e senza fuso orario.
Dettagli
Se si sta tentando di lavorare con valori di sola data (senza ora del giorno, senza fuso orario), utilizzare la LocalDate
classe anziché java.util.Date
.
java.time
In Java 8 e versioni successive, le vecchie e problematiche classi data-ora in bundle con le prime versioni di Java sono state soppiantate dal nuovo pacchetto java.time . Vedi Tutorial Oracle . Gran parte delle funzionalità è stata trasferita su Java 6 e 7 in ThreeTen-Backport e ulteriormente adattata ad Android in ThreeTenABP .
Un tipo di dati SQL DATE
è pensato per essere solo data, senza ora del giorno e senza fuso orario. Java non ha mai avuto una tale classe † fino java.time.LocalDate
a quando in Java 8. Creiamo un tale valore ottenendo la data di oggi in base a un particolare fuso orario (il fuso orario è importante nel determinare una data come un nuovo giorno sorge prima a Parigi che a Montréal, per esempio).
LocalDate todayLocalDate = LocalDate.now( ZoneId.of( "America/Montreal" ) ); // Use proper "continent/region" time zone names; never use 3-4 letter codes like "EST" or "IST".
A questo punto, potremmo aver finito. Se il tuo driver JDBC è conforme alle specifiche JDBC 4.2 , dovresti essere in grado di passare un LocalDate
via setObject
su a PreparedStatement
per archiviare in un campo DATE SQL.
myPreparedStatement.setObject( 1 , localDate );
Allo stesso modo, utilizzare ResultSet::getObject
per recuperare da una colonna DATE SQL a un LocalDate
oggetto Java . Specificare la classe nel secondo argomento rende il tuo codice sicuro .
LocalDate localDate = ResultSet.getObject( 1 , LocalDate.class );
In altre parole, l'intera domanda è irrilevante ai sensi del JDBC 4.2 o successivo.
Se il driver JDBC non funziona in questo modo, è necessario ricorrere alla conversione nei tipi java.sql.
Converti in java.sql.Date
Per convertire, utilizzare i nuovi metodi aggiunti alle vecchie classi data-ora. Possiamo chiamare java.sql.Date.valueOf(…)
per convertire a LocalDate
.
java.sql.Date sqlDate = java.sql.Date.valueOf( todayLocalDate );
E andando nella direzione opposta.
LocalDate localDate = sqlDate.toLocalDate();
Conversione da java.util.Date
Mentre dovresti evitare di usare le vecchie classi data-ora, potresti essere costretto a farlo quando lavori con il codice esistente. In tal caso, è possibile convertire in / da java.time.
Passa attraverso la Instant
classe, che rappresenta un momento nella sequenza temporale in UTC. An Instant
è simile nell'idea a java.util.Date
. Ma nota che Instant
ha una risoluzione fino a nanosecondi mentre java.util.Date
ha una risoluzione di soli millisecondi .
Per convertire, utilizzare i nuovi metodi aggiunti alle vecchie classi. Ad esempio, java.util.Date.from( Instant )
e java.util.Date::toInstant
.
Instant instant = myUtilDate.toInstant();
Per determinare una data, abbiamo bisogno del contesto di un fuso orario. Per ogni dato momento, la data varia in tutto il mondo in base al fuso orario. Applicare a ZoneId
per ottenere a ZonedDateTime
.
ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
LocalDate localDate = zdt.toLocalDate();
† La classe java.sql.Date finge di essere solo data senza ora del giorno, ma in realtà esegue un'ora del giorno, adattata a una mezzanotte. Confondere? Sì, le vecchie classi di data e ora sono un disastro.
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à manutenzione , consiglia la migrazione alle classi java.time .
Per saperne di più, consulta 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. Utilizzare 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 aggiunte future a java.time. Si possono trovare alcune classi utili, come per esempio Interval
, YearWeek
, YearQuarter
e altro .