Ich möchte eine LocalDate
in einer DATE
Spalte speichern und unverändert abrufen. Sowohl DATE
als auch LocalDate
sind per Definition "lokale" Typen. Daher sollte das Konzept der Zeitzone in keiner Weise stören.So ordnen Sie SQL DATE LocalDate zu
Der folgende Code ist ein minimales Beispiel, das eine Tabelle mit einer Spalte DATE
in einer In-Memory-Datenbank erstellt. Das Mavenartefakt com.h2database:h2:1.4.192
muss im Klassenpfad sein.
Zunächst definieren Methoden insert
und retrieve
:
static void insert(DataSource ds, String date) throws SQLException {
try (Connection conn = ds.getConnection();
Statement stmt = conn.createStatement()) {
stmt.execute("CREATE TABLE people (id BIGINT NOT NULL AUTO_INCREMENT"
+ ", born DATE NOT NULL, PRIMARY KEY (id));");
stmt.execute("INSERT INTO people (born) VALUES ('" + date + "')");
}
}
static LocalDate retrieve(DataSource ds) throws SQLException {
try (Connection conn = ds.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM people limit 1")) {
if (rs.next()) {
java.sql.Date retrieved = java.sql.Date.valueOf(rs.getString("born"));
return retrieved.toLocalDate();
}
throw new IllegalStateException("No data");
}
}
Beachten Sie, dass die insert
Methode den toString
Wert des LocalDate
in einfache Anführungszeichen verwendet, so gibt es keine Möglichkeit für Java ™ Zeitzone Mehrdeutigkeit zu erstellen. Jetzt insert
einmal anrufen und dann mehrmals retrieve
mit unterschiedlichen timzone Einstellungen jedes Mal:
public static void main(String[] args) throws Exception {
DataSource ds = JdbcConnectionPool.create("jdbc:h2:mem:test", "sa", "sa");
LocalDate born = LocalDate.parse("2015-05-20");
insert(ds, born.toString());
System.out.println("Inserted: " + born);
for (int i : new int[]{-14, 0, 12}) {
TimeZone z = TimeZone.getTimeZone(String.format("Etc/GMT%+02d", i));
TimeZone.setDefault(z);
System.out.println("Retrieved: " + retrieve(ds));
}
}
Dann folgt das gedruckt wird:
Inserted: 2015-05-20 Retrieved: 2015-05-20 Retrieved: 2015-05-19 Retrieved: 2015-05-18
Wie die retrieve
Methode zu schreiben, so dass es den gleichen Wert zurückgibt das wurde bedingungslos eingefügt, unter der Annahme, dass die Datenbanktabelle nicht ändert?
Sie java.util.Date importierende? Auf dieser 'requested =' Zeile verwenden Sie das vollqualifizierte 'java.sql.Date' auf der linken Seite der Zuweisung, aber nicht das Recht. –
Warum haben Sie erwartet, dass das 3 gleiche 'LocalDate' gedruckt wird? Sie fügen das Datum "2015-05-20" ein. Wenn Sie dann die Standardzeitzone ändern, gibt die Methode 'java.sql.Date.toLocalDate' ein anderes Ergebnis zurück. – Tunaki
@BasilBourque behoben –