Часовые пояса в SQL DATE и java.sql.Date

Меня немного смущает поведение типа данных SQL DATE по сравнению с поведением java.sql.Date . Возьмем, например, следующий оператор:

select cast(? as date)           -- in most databases
select cast(? as date) from dual -- in Oracle

Давайте подготовим и выполним оператор с помощью Java

PreparedStatement stmt = connection.prepareStatement(sql);
stmt.setDate(1, new java.sql.Date(0)); // GMT 1970-01-01 00:00:00
ResultSet rs = stmt.executeQuery();
rs.next();

// I live in Zurich, which is CET, not GMT. So the following prints -3600000, 
// which is CET 1970-01-01 00:00:00
// ... or   GMT 1969-12-31 23:00:00
System.out.println(rs.getDate(1).getTime());

Другими словами, метка времени GMT, которую я привязываю к оператору, становится меткой времени CET, которую я возвращаю. На каком шаге добавляется часовой пояс и почему?

Примечание:

  • Я заметил, что это верно для любой из этих баз данных:

    DB2, Derby, H2, HSQLDB, Ingres, MySQL, Oracle, Postgres, SQL Server, Sybase ASE, Sybase SQL Anywhere

  • Я заметил, что это неверно для SQLite (который на самом деле не имеет истинных типов данных DATE )
  • Все это не имеет значения при использовании java.sql.Timestamp вместо java.sql.Date
  • Это похожий вопрос, который, однако, не отвечает на этот вопрос: java.util.Date vs java. sql.Date

37
задан Community 23 May 2017 в 11:55
поделиться