Come convertire java.util.Date in java.sql.Date?


453

Sto cercando di utilizzare un java.util.Dateinput e quindi creare una query con esso, quindi ho bisogno di un java.sql.Date.

Sono stato sorpreso di scoprire che non poteva fare la conversione in modo implicito o esplicito, ma non so nemmeno come lo farei, poiché l'API Java è ancora abbastanza nuova per me.


Puoi trovare un problema simile qui stackoverflow.com/questions/12131068/…
Lem,

Per me, si è scoperto che non avevo bisogno di convertirmi. Nel import java.sql.*mio codice c'era un , che sovrascriveva java.util.date e quindi causava problemi nell'assegnazione di valori di data che andavano bene con quest'ultimo ma non con il primo. HTH
HumanInDisguise,

1
@DavidAckerman Capisci che una data java.util è una data e un'ora del giorno, ma una data java.sql è solo una data senza ora del giorno? (In realtà c'è un momento del giorno ma questo viene ignorato, un brutto trucco di un design di classe) In SQL, DATEsignifica solo data.
Basil Bourque,

2
In effetti non ero a conoscenza delle sfumature del '09, e poiché questa domanda è così popolare, ho cambiato la risposta accettata a una più moderna e completa. Grazie a tutti per il vostro contributo!
David Ackerman,

Risposte:


89

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.Datee java.sql.Datecon 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:

  • Instantinvece di java.util.Date
    Entrambi rappresentano un momento in UTC. ma ora con nanosecondi anziché millisecondi.
  • LocalDateanziché 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 LocalDateclasse anziché java.util.Date.

Tabella dei tipi di data e ora in Java (sia legacy che moderna) e nello standard SQL.

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.LocalDatea 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 LocalDatevia setObjectsu a PreparedStatementper archiviare in un campo DATE SQL.

myPreparedStatement.setObject( 1 , localDate );

Allo stesso modo, utilizzare ResultSet::getObjectper recuperare da una colonna DATE SQL a un LocalDateoggetto 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 Instantclasse, che rappresenta un momento nella sequenza temporale in UTC. An Instantè simile nell'idea a java.util.Date. Ma nota che Instantha una risoluzione fino a nanosecondi mentre java.util.Dateha 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 ZoneIdper 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?

Tabella della libreria java.time da utilizzare con la versione di Java o Android

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, YearQuartere altro .


478

Non importa....

public class MainClass {

  public static void main(String[] args) {
    java.util.Date utilDate = new java.util.Date();
    java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
    System.out.println("utilDate:" + utilDate);
    System.out.println("sqlDate:" + sqlDate);

  }

}

lo spiega. Il link è http://www.java2s.com/Tutorial/Java/0040__Data-Type/ConvertfromajavautilDateObjecttoajavasqlDateObject.htm


34
Questa non è una conversione esplicita! Da Javadoc: "Se il valore in millisecondi specificato contiene informazioni sull'ora, il driver imposterà i componenti dell'ora sull'ora nel fuso orario predefinito (il fuso orario della macchina virtuale Java che esegue l'applicazione) che corrisponde a zero GMT." Quindi, indipendentemente dal tuo tempo su java.util.Date, verrà inserito come 00:00:00 in una colonna con il tipo di dati impostato su DATA.

1
@David Ackerman ..... questo metodo restituisce i epochsecondsmillisecondi seguenti dopo 1,JAN,1970. Ma cosa succede se vogliamo memorizzare la data di una persona prima di questa data .... o qualcosa del genere0000-00-00 as default
Arjun KP

31
Nel mio caso la risposta corretta è <code> java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp (utilDate.getTime ()); </code>, poiché conserva i campi temporali.
Alberto de Paola,

2
@ wired00 Sì, le vecchie classi di data e ora in bundle con le prime versioni di Java sono un casino , mal progettato con alcuni hack rozzi. Quando possibile, prova a utilizzare il nuovo framework java.time in Java 8 e versioni successive. Queste nuove classi soppiantano le vecchie. Le classi java.time e le vecchie classi hanno alcuni metodi utili per la conversione avanti e indietro, utile mentre aspettiamo che i driver JDBC vengano aggiornati per utilizzare direttamente i nuovi tipi java.time.
Basil Bourque,

1
@ wired00 Vedi la mia nuova risposta a questa domanda su come usare java.time. Cerca anche StackOverflow per molti altri esempi.
Basil Bourque,

39

Con l'altra risposta potresti avere problemi con le informazioni sull'ora (confronta le date con risultati imprevisti!)

Suggerisco:

java.util.Calendar cal = Calendar.getInstance();
java.util.Date utilDate = new java.util.Date(); // your util date
cal.setTime(utilDate);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);    
java.sql.Date sqlDate = new java.sql.Date(cal.getTime().getTime()); // your sql date
System.out.println("utilDate:" + utilDate);
System.out.println("sqlDate:" + sqlDate);

5
Se utilizza java.sql.Date per una colonna Data in un database, le informazioni sull'ora verranno troncate. Secondo me, hai riprogettato troppo la soluzione.
darioo,

4
Sì, forse l'ho fatto. A volte ho bisogno di confrontare java.sql.Data con la data corrente e imho questo è il modo migliore. Spero possa essere d'aiuto.
mauretto,

Cordiali saluti, le vecchie classi data-ora terribilmente fastidiose come java.util.Date, java.util.Calendare java.text.SimpleDateFormatora sono legacy , soppiantate dalle classi java.time integrate in Java 8 e versioni successive. Vedi Tutorial di Oracle .
Basil Bourque,

Certo, questo argomento era di circa 10 anni fa, pre-java 8.
mauretto

26

Questa funzione restituirà una data SQL convertita dall'oggetto java date.

public java.sql.Date convertJavaDateToSqlDate(java.util.Date date) {
    return new java.sql.Date(date.getTime());
}

18

La conversione java.util.Datain java.sql.Dataperderà ora, minuti e secondi. Quindi, se è possibile, ti suggerisco di usare in java.sql.Timestampquesto modo:

prepareStatement.setTimestamp(1, new Timestamp(utilDate.getTime()));

Per maggiori informazioni, puoi controllare questa domanda .


16

Nel mio caso di scegliere la data da JXDatePicker (java calender) e averlo archiviato nel database come tipo di data SQL, di seguito funziona bene.

java.sql.Date date = new java.sql.Date(pickedDate.getDate().getTime());

dove PickDate è oggetto di JXDatePicker


5

Questa funzione restituirà una data SQL convertita dall'oggetto java date.

public static java.sql.Date convertFromJAVADateToSQLDate(
            java.util.Date javaDate) {
        java.sql.Date sqlDate = null;
        if (javaDate != null) {
            sqlDate = new Date(javaDate.getTime());
        }
        return sqlDate;
    }

3

Formatta prima java.util.Date. Quindi utilizzare la data formattata per ottenere la data in java.sql.Date

java.util.Date utilDate = "Your date"
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
final String stringDate= dateFormat.format(utilDate);
final java.sql.Date sqlDate=  java.sql.Date.valueOf(stringDate);

2

Qui l'esempio di conversione della data di utilizzo in data Sql e questo è un esempio di quello che sto usando nel mio progetto potrebbe essere utile anche a te.

java.util.Date utilStartDate = table_Login.getDob();(orwhat ever date your give form obj)
java.sql.Date sqlStartDate = new java.sql.Date(utilStartDate.getTime());(converting date)

2

Sono alle prime armi: dopo tanto correre in giro ha funzionato. Il pensiero potrebbe essere utile

     String bufDt =  bDOB.getText();  //data from form
     DateFormat dF = new SimpleDateFormat("dd-MM-yyyy"); //data in form is in this format
     Date bbdt = (Date)dF.parse(bufDt);  // string data is converted into java util date
     DateFormat dsF = new SimpleDateFormat("yyyy-MM-dd"); //converted date is reformatted for conversion to sql.date
     String ndt = dsF.format(bbdt); // java util date is converted to compatible java sql date
     java.sql.Date sqlDate=  java.sql.Date.valueOf(ndt);  // finally data from the form is convered to java sql. date for placing in database

Cordiali saluti, le vecchie classi data-ora terribilmente fastidiose come java.util.Date, java.util.Calendare java.text.SimpleDateFormatora sono legacy , soppiantate dalle classi java.time integrate in Java 8 e versioni successive. Vedi Tutorial di Oracle .
Basil Bourque,

2
java.sql.Date sqlDate = new java.sql.Date(javaDate.getTime());

Qui javaDate è l'istanza di java.util.Date


1
Non sembra davvero aggiungere nulla di nuovo rispetto alle risposte di David Ackerman, Chetan e Tanmay Kumar Shaw, vero?
Ole VV,

1

Metodo per confrontare 2 date (util.date o sql.date)

 public static boolean isSameDay(Date a, Date b) {
    Calendar calA = new GregorianCalendar();
    calA.setTime(a);

    Calendar calB = new GregorianCalendar();
    calB.setTime(b);

    final int yearA = calA.get(Calendar.YEAR);
    final int monthA = calA.get(Calendar.MONTH);
    final int dayA = calA.get(Calendar.DAY_OF_YEAR);

    final int yearB = calB.get(Calendar.YEAR);
    final int monthB = calB.get(Calendar.MONTH);
    final int dayB = calB.get(Calendar.DAY_OF_YEAR);

    return yearA == yearB && monthA == monthB && dayA == dayB;
}

0

prova con questo

public static String toMysqlDateStr(Date date) {
    String dateForMySql = "";
    if (date == null) {
        dateForMySql = null;
    } else {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        dateForMySql = sdf.format(date);
    }

    return dateForMySql;
}

-1

Penso che il modo migliore per convertire sia:

static java.sql.Timestamp SQLDateTime(Long utilDate) {
    return new java.sql.Timestamp(utilDate);
}

Date date = new Date();
java.sql.Timestamp dt = SQLDateTime(date.getTime());

Se vuoi inserire la dtvariabile in una tabella SQL puoi fare:

insert into table (expireAt) values ('"+dt+"');

1
Questo sembra essere sostanzialmente lo stesso di questa risposta pubblicata un anno prima.
Bernhard Barker,

-3

sto usando il seguente codice per favore provalo

DateFormat fm= new SimpleDateFormatter();

specificare il formato della data desiderata, ad esempio, "DD-MM_YYYY"oppure 'YYYY-mm-dd' utilizzare il tipo di dati Date java come

fm.format("object of java.util.date");

quindi analizzerà la tua data


-3

Puoi utilizzare questo metodo per convertire la data di utilità in data sql,

DateUtilities.convertUtilDateToSql(java.util.Date)

Non esiste una classe DateUtilities nella libreria Java standard (e non riesco nemmeno a trovare questo metodo ovunque da una rapida ricerca su Google). Se proviene da una libreria specifica, potresti voler dire altrettanto e includere un collegamento ai documenti.
Bernhard Barker,

-4

Stavo provando il seguente codice che ha funzionato bene.

java.util.Date utilDate = new java.util.Date ();
java.sql.Date sqlDate = new java.sql.Date (utilDate);


-8

Se stai usando Mysql una colonna data può essere passata una rappresentazione String di questa data

quindi utilizzo la classe DateFormatter per formattarla e quindi impostarla come stringa nell'istruzione sql o nell'istruzione preparata

ecco l'illustrazione del codice:

private String converUtilDateToSqlDate(java.util.Date utilDate) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    String sqlDate = sdf.format(utilDate);
    return sqlDate;
}

String date = converUtilDateToSqlDate (otherTransaction.getTransDate ());

// quindi passa questa data nella tua dichiarazione sql


14
Benvenuto in StackOverflow, ho alcuni commenti alla tua risposta. La domanda era "come convertire un java.util.Date in java.sql.Date". Il codice incollato formatta java.util.Date come yyyy-MM-dd. Questo in realtà è di utilità limitata in questo contesto poiché si dovrebbe passare java.sql.Date direttamente ai driver jdbc invece di farlo come una stringa.
jontro,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.