Wie konvertiere ich java.util.Date in java.sql.Date?

453

Ich versuche, a java.util.Dateals Eingabe zu verwenden und dann eine Abfrage damit zu erstellen - also brauche ich a java.sql.Date.

Ich war überrascht, dass die Konvertierung nicht implizit oder explizit durchgeführt werden konnte - aber ich weiß nicht einmal, wie ich das tun würde, da die Java-API für mich noch ziemlich neu ist.

David Ackerman
quelle
Ein ähnliches Problem finden Sie hier stackoverflow.com/questions/12131068/…
Lem
Für mich stellte sich heraus, dass ich nicht konvertieren musste. Es gab eine import java.sql.*in meinem Code, die java.util.date zwingende und somit Probleme verursachen , wenn Datumswerte zuweisen, mit dem letzteren waren in Ordnung , aber nicht die ersten. HTH
HumanInDisguise
1
@DavidAckerman Verstehst du, dass ein java.util.Date ein Datum und eine Uhrzeit ist, ein java.sql.Date jedoch nur ein Datum ohne Tageszeit? (Eigentlich gibt es eine Tageszeit, die aber ignoriert wird, ein schlechter Hack eines Klassendesigns.) In SQL DATEbedeutet dies nur Datum.
Basil Bourque
2
Ich war mir der Nuancen von '09 in der Tat nicht bewusst, und da diese Frage so beliebt ist, habe ich die akzeptierte Antwort in eine Antwort geändert, die sowohl moderner als auch vollständiger ist. Vielen Dank an alle für Ihre Eingabe!
David Ackerman

Antworten:

89

tl; dr

Wie konvertiere ich java.util.Date in java.sql.Date?

Tu es nicht. Beide Klassen sind veraltet.

  • Verwenden Sie java.time- Klassen anstelle von Legacy java.util.Date& java.sql.Datemit JDBC 4.2 oder höher.
  • Konvertieren Sie nach / von java.time, wenn Sie mit Code zusammenarbeiten, der noch nicht auf java.time aktualisiert wurde.

Beispielabfrage mit 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.
)

Ersatz:

  • Instantanstelle von java.util.Date
    Beide stellen einen Moment in UTC dar. aber jetzt mit Nanosekunden statt Millisekunden.
  • LocalDateanstelle von java.sql.Date
    Beide stellen einen Nur-Datum-Wert ohne Tageszeit und ohne Zeitzone dar.

Einzelheiten

Wenn Sie versuchen, mit Nur-Datum-Werten (keine Uhrzeit, keine Zeitzone) zu arbeiten, verwenden Sie die LocalDateKlasse anstelle von java.util.Date.

Tabelle der Datums- und Uhrzeittypen in Java (sowohl Legacy als auch Modern) und im SQL-Standard.

java.time

In Java 8 und höher wurden die problematischen alten Datums- / Uhrzeitklassen, die mit früheren Versionen von Java gebündelt wurden, durch das neue Paket java.time ersetzt . Siehe Oracle Tutorial . Ein Großteil der Funktionen wurde in ThreeTen-Backport auf Java 6 & 7 zurückportiert und in ThreeTenABP weiter an Android angepasst .

Ein SQL-Datentyp DATE soll nur ein Datum ohne Tageszeit und ohne Zeitzone sein. Java hatte bis genau java.time.LocalDatein Java 8 nie genau eine solche Klasse †. Erstellen wir einen solchen Wert, indem wir das heutige Datum nach einer bestimmten Zeitzone abrufen (die Zeitzone ist wichtig, um ein Datum zu bestimmen, wenn ein neuer Tag in Paris früher als in Montréal beginnt, z Beispiel).

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".

An diesem Punkt können wir fertig sein. Wenn Ihr JDBC-Treiber der JDBC 4.2-Spezifikation entspricht , sollten Sie in der Lage sein, ein LocalDateVia setObjectan ein PreparedStatementzu übergeben, um es in einem SQL DATE-Feld zu speichern.

myPreparedStatement.setObject( 1 , localDate );

Verwenden Sie ResultSet::getObjectdiese Option auch, um von einer SQL DATE-Spalte in ein Java- LocalDateObjekt abzurufen . Wenn Sie die Klasse im zweiten Argument angeben, ist Ihr Code typsicher .

LocalDate localDate = ResultSet.getObject( 1 , LocalDate.class );

Mit anderen Worten, diese gesamte Frage ist unter JDBC 4.2 oder höher irrelevant .

Wenn Ihr JDBC-Treiber nicht auf diese Weise funktioniert, müssen Sie auf die Konvertierung in die Typen java.sql zurückgreifen.

In java.sql.Date konvertieren

Verwenden Sie zum Konvertieren neue Methoden, die den alten Datums- / Zeitklassen hinzugefügt wurden. Wir können anrufen java.sql.Date.valueOf(…), um a zu konvertieren LocalDate.

java.sql.Date sqlDate = java.sql.Date.valueOf( todayLocalDate );

Und in die andere Richtung gehen.

LocalDate localDate = sqlDate.toLocalDate();

Konvertieren von java.util.Date

Während Sie die Verwendung der alten Datums- / Uhrzeitklassen vermeiden sollten, müssen Sie möglicherweise gezwungen sein, mit vorhandenem Code zu arbeiten. In diesem Fall können Sie nach / von java.time konvertieren.

Gehen Sie die InstantKlasse durch, die einen Moment auf der Zeitachse in UTC darstellt. An Instantist in der Idee ähnlich wie a java.util.Date. Beachten Sie jedoch, dass Instantdie Auflösung bis zu Nanosekunden und java.util.Datedie Auflösung nur Millisekunden beträgt.

Verwenden Sie zum Konvertieren neue Methoden, die den alten Klassen hinzugefügt wurden. Zum Beispiel java.util.Date.from( Instant )und java.util.Date::toInstant.

Instant instant = myUtilDate.toInstant();

Um ein Datum zu bestimmen, benötigen wir den Kontext einer Zeitzone. Für jeden Moment variiert das Datum weltweit nach Zeitzone. Wenden Sie ein ZoneIdan, um ein zu erhalten ZonedDateTime.

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant ( instant , zoneId );
LocalDate localDate = zdt.toLocalDate();

† Die java.sql.Date Klasse gibt vor , ohne Zeit-of-day date-nur zu sein , aber tatsächlich hat eine Laufzeit-Tag, zu einer Mitternacht Zeit angepasst. Verwirrend? Ja, die alten Datums- und Uhrzeitklassen sind ein Chaos.


Ü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 Zeichenfolgen, keine Notwendigkeit für java.sql.*Klassen.

Woher bekomme ich die java.time-Klassen?

Tabelle, welche java.time-Bibliothek mit welcher Java- oder Android-Version verwendet werden soll

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 .

Basil Bourque
quelle
478

Keine Ursache....

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);

  }

}

erklärt es. Der Link lautet http://www.java2s.com/Tutorial/Java/0040__Data-Type/ConvertfromajavautilDateObjecttoajavasqlDateObject.htm

David Ackerman
quelle
34
Dies ist keine explizite Konvertierung! Aus dem Javadoc: "Wenn der angegebene Millisekundenwert Zeitinformationen enthält, setzt der Treiber die Zeitkomponenten auf die Zeit in der Standardzeitzone (der Zeitzone der virtuellen Java-Maschine, in der die Anwendung ausgeführt wird), die null GMT entspricht." Unabhängig von Ihrer Zeit in Ihrem java.util.Date wird es als 00:00:00 in eine Spalte mit dem Datentyp DATE eingefügt.
1
@ David Ackerman ..... Diese Methode gibt die epochsecondsdh Millisekunden danach zurück 1,JAN,1970. Aber was ist, wenn wir das Datum einer Person vor diesem Datum speichern wollen ... oder so ähnlich0000-00-00 as default
Arjun KP
31
In meinem Fall lautet die richtige Antwort <code> java.sql.Timestamp sqlTimestamp = new java.sql.Timestamp (utilDate.getTime ()); </ code>, da die Zeitfelder erhalten bleiben.
Alberto de Paola
2
@ wired00 Ja, die alten Datums- / Uhrzeitklassen, die mit den frühen Versionen von Java gebündelt sind , sind ein Chaos , schlecht gestaltet, einschließlich einiger grober Hacks. Versuchen Sie nach Möglichkeit, das neue java.time-Framework in Java 8 und höher zu verwenden. Diese neuen Klassen ersetzen die alten. Die java.time-Klassen und die alten Klassen verfügen über einige praktische Methoden zum Hin- und Herkonvertieren - nützlich, während wir darauf warten, dass die JDBC-Treiber aktualisiert werden, um die neuen java.time-Typen direkt zu verwenden.
Basil Bourque
1
@ wired00 In meiner neuen Antwort auf diese Frage erfahren Sie, wie Sie java.time verwenden. Suchen Sie auch in StackOverflow nach vielen weiteren Beispielen.
Basil Bourque
39

Bei der anderen Antwort haben Sie möglicherweise Probleme mit den Zeitinformationen (vergleichen Sie die Daten mit unerwarteten Ergebnissen!)

Ich schlage vor:

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);
Mauretto
quelle
5
Wenn er java.sql.Date für eine Datumsspalte in einer Datenbank verwendet, werden diese Zeitinformationen abgeschnitten. Sie haben die Lösung meiner Meinung nach überarbeitet.
Darioo
4
Ja, vielleicht habe ich es getan. Ich muss manchmal die java.sql.Data mit dem aktuellen Datum vergleichen und imho ist dies der beste Weg. Ich hoffe es kann helfen.
Mauretto
Zu Ihrer Information, die furchtbar lästig alten Datum Zeitklassen wie java.util.Date, java.util.Calendarund java.text.SimpleDateFormatsind jetzt Erbe , durch die verdrängte java.time Klassen in Java gebaut 8 und höher. Siehe Tutorial von Oracle .
Basil Bourque
Natürlich war dieses Thema vor ungefähr 10 Jahren, vor Java 8.
Mauretto
26

Diese Funktion gibt ein konvertiertes SQL-Datum vom Java-Datumsobjekt zurück.

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

Das Konvertieren java.util.Datain java.sql.Dataverliert Stunde, Minute und Sekunde. Wenn es also möglich ist, schlage ich vor, dass Sie Folgendes verwenden java.sql.Timestamp:

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

Für weitere Informationen können Sie diese Frage überprüfen .

Shellbye
quelle
16

In meinem Fall, in dem das Datum aus JXDatePicker (Java-Kalender) ausgewählt und als SQL-Datumstyp in der Datenbank gespeichert wird, funktioniert das unten einwandfrei.

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

Dabei ist pickDate ein Objekt von JXDatePicker

Jack Jay
quelle
5

Diese Funktion gibt ein konvertiertes SQL-Datum vom Java-Datumsobjekt zurück.

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;
    }
Tanmay Kumar Shaw
quelle
3

Formatieren Sie zuerst Ihr java.util.Date. Verwenden Sie dann das formatierte Datum, um das Datum in java.sql.Date abzurufen

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);
Hackfield
quelle
2

Hier ist das Beispiel der Konvertierung von Util Date in SQL Date und ya dies ist ein Beispiel, das ich in meinem Projekt verwende, könnte auch für Sie hilfreich sein.

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)
Kishan Bheemajiyani
quelle
2

Ich bin ein Neuling: Nach langem Herumlaufen hat das geklappt. Gedanken könnten nützlich sein

     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
PKSawmy
quelle
Zu Ihrer Information, die furchtbar lästig alten Datum Zeitklassen wie java.util.Date, java.util.Calendarund java.text.SimpleDateFormatsind jetzt Erbe , durch die verdrängte java.time Klassen in Java gebaut 8 und höher. Siehe Tutorial von Oracle .
Basil Bourque
2
java.sql.Date sqlDate = new java.sql.Date(javaDate.getTime());

Hier ist javaDate die Instanz von java.util.Date

Rajeev Ranjan
quelle
1
Im Vergleich zu den Antworten von David Ackerman, Chetan und Tanmay Kumar Shaw, scheint es nicht wirklich etwas Neues hinzuzufügen, oder?
Ole VV
1

Methode zum Vergleichen von 2 Daten (util.date oder 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;
}
Donovan Thomson
quelle
0

versuche es damit

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;
}
kapil das
quelle
-1

Ich denke, der beste Weg, um zu konvertieren, ist:

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

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

Wenn Sie die dtVariable in eine SQL-Tabelle einfügen möchten, haben Sie folgende Möglichkeiten:

insert into table (expireAt) values ('"+dt+"');
user6043502
quelle
1
Dies scheint im Wesentlichen die gleiche zu sein wie diese Antwort, die ein Jahr zuvor veröffentlicht wurde.
Bernhard Barker
-3

Ich benutze den folgenden Code, bitte probieren Sie es aus

DateFormat fm= new SimpleDateFormatter();

Geben Sie beispielsweise das Format des gewünschten Datums an "DD-MM_YYYY"oder verwenden Sie 'YYYY-mm-dd' dann den Datentyp Java-Datum als

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

dann wird Ihr Datum analysiert

UmeshA
quelle
-3

Mit dieser Methode können Sie das Util-Datum in das SQL-Datum konvertieren.

DateUtilities.convertUtilDateToSql(java.util.Date)
Emmanuel Angelo.R
quelle
Es gibt keine DateUtilities-Klasse in der Standard-Java-Bibliothek (und ich kann diese Methode bei einer schnellen Google-Suche überhaupt nicht finden). Wenn dies aus einer bestimmten Bibliothek stammt, möchten Sie dies möglicherweise sagen und einen Link zu den Dokumenten einfügen.
Bernhard Barker
-4

Ich habe die folgende Codierung ausprobiert, die gut funktioniert hat.

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

PONRAJ
quelle
-8

Wenn Sie MySQL verwenden, kann einer Datumsspalte eine Zeichenfolgendarstellung dieses Datums übergeben werden

Also benutze ich die DateFormatter-Klasse, um sie zu formatieren und dann als String in der SQL-Anweisung oder der vorbereiteten Anweisung festzulegen

Hier ist die Code-Abbildung:

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 ());

// Übergebe dann dieses Datum in deiner SQL-Anweisung

Benjamin Ndugga
quelle
14
Willkommen bei stackoverflow. Ich habe einige Kommentare zu Ihrer Antwort. Die Frage war "wie man ein java.util.Date in java.sql.Date konvertiert". Der Code, den Sie eingefügt haben, formatiert ein java.util.Date als JJJJ-MM-TT. Dies ist in diesem Zusammenhang tatsächlich von begrenztem Nutzen, da Sie die Datei java.sql.Date direkt an die jdbc-Treiber übergeben sollten, anstatt sie als Zeichenfolge auszuführen.
Jontro