提交 7c4bebd6 authored 作者: Thomas Mueller's avatar Thomas Mueller

The JDBC methods PreparedStatement.setTimestamp, setTime, and setDate with a…

The JDBC methods PreparedStatement.setTimestamp, setTime, and setDate with a calendar, and the methods ResultSet.getTimestamp, getTime, and getDate with a calendar converted the value in the wrong way, so that for some timestamps the converted value was wrong (where summertime starts, one hour per year).
上级 2e060308
...@@ -611,7 +611,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements PreparedStat ...@@ -611,7 +611,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements PreparedStat
if (x == null) { if (x == null) {
setParameter(parameterIndex, ValueNull.INSTANCE); setParameter(parameterIndex, ValueNull.INSTANCE);
} else { } else {
setParameter(parameterIndex, DateTimeUtils.convertDateToUTC(x, calendar)); setParameter(parameterIndex, DateTimeUtils.convertDate(x, calendar));
} }
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
...@@ -635,7 +635,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements PreparedStat ...@@ -635,7 +635,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements PreparedStat
if (x == null) { if (x == null) {
setParameter(parameterIndex, ValueNull.INSTANCE); setParameter(parameterIndex, ValueNull.INSTANCE);
} else { } else {
setParameter(parameterIndex, DateTimeUtils.convertTimeToUTC(x, calendar)); setParameter(parameterIndex, DateTimeUtils.convertTime(x, calendar));
} }
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
...@@ -659,7 +659,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements PreparedStat ...@@ -659,7 +659,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements PreparedStat
if (x == null) { if (x == null) {
setParameter(parameterIndex, ValueNull.INSTANCE); setParameter(parameterIndex, ValueNull.INSTANCE);
} else { } else {
setParameter(parameterIndex, DateTimeUtils.convertTimestampToUTC(x, calendar)); setParameter(parameterIndex, DateTimeUtils.convertTimestamp(x, calendar));
} }
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
......
...@@ -806,8 +806,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet { ...@@ -806,8 +806,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("getDate(" + columnIndex + ", calendar)"); debugCode("getDate(" + columnIndex + ", calendar)");
} }
Date x = get(columnIndex).getDate(); return DateTimeUtils.convertDate(get(columnIndex), calendar);
return DateTimeUtils.convertDateToCalendar(x, calendar);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -828,8 +827,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet { ...@@ -828,8 +827,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("getDate(" + StringUtils.quoteJavaString(columnLabel) + ", calendar)"); debugCode("getDate(" + StringUtils.quoteJavaString(columnLabel) + ", calendar)");
} }
Date x = get(columnLabel).getDate(); return DateTimeUtils.convertDate(get(columnLabel), calendar);
return DateTimeUtils.convertDateToCalendar(x, calendar);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -850,8 +848,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet { ...@@ -850,8 +848,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("getTime(" + columnIndex + ", calendar)"); debugCode("getTime(" + columnIndex + ", calendar)");
} }
Time x = get(columnIndex).getTime(); return DateTimeUtils.convertTime(get(columnIndex), calendar);
return DateTimeUtils.convertTimeToCalendar(x, calendar);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -872,8 +869,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet { ...@@ -872,8 +869,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("getTime(" + StringUtils.quoteJavaString(columnLabel) + ", calendar)"); debugCode("getTime(" + StringUtils.quoteJavaString(columnLabel) + ", calendar)");
} }
Time x = get(columnLabel).getTime(); return DateTimeUtils.convertTime(get(columnLabel), calendar);
return DateTimeUtils.convertTimeToCalendar(x, calendar);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -894,8 +890,8 @@ public class JdbcResultSet extends TraceObject implements ResultSet { ...@@ -894,8 +890,8 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("getTimestamp(" + columnIndex + ", calendar)"); debugCode("getTimestamp(" + columnIndex + ", calendar)");
} }
Timestamp x = get(columnIndex).getTimestamp(); Value value = get(columnIndex);
return DateTimeUtils.convertTimestampToCalendar(x, calendar); return DateTimeUtils.convertTimestamp(value, calendar);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
...@@ -915,8 +911,8 @@ public class JdbcResultSet extends TraceObject implements ResultSet { ...@@ -915,8 +911,8 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
if (isDebugEnabled()) { if (isDebugEnabled()) {
debugCode("getTimestamp(" + StringUtils.quoteJavaString(columnLabel) + ", calendar)"); debugCode("getTimestamp(" + StringUtils.quoteJavaString(columnLabel) + ", calendar)");
} }
Timestamp x = get(columnLabel).getTimestamp(); Value value = get(columnLabel);
return DateTimeUtils.convertTimestampToCalendar(x, calendar); return DateTimeUtils.convertTimestamp(value, calendar);
} catch (Exception e) { } catch (Exception e) {
throw logAndConvert(e); throw logAndConvert(e);
} }
......
...@@ -11,18 +11,25 @@ import java.io.IOException; ...@@ -11,18 +11,25 @@ import java.io.IOException;
import java.io.StringReader; import java.io.StringReader;
import java.math.BigDecimal; import java.math.BigDecimal;
import java.sql.Connection; import java.sql.Connection;
import java.sql.Date;
import java.sql.ParameterMetaData; import java.sql.ParameterMetaData;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
import java.sql.ResultSetMetaData; import java.sql.ResultSetMetaData;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp; import java.sql.Timestamp;
import java.sql.Types; import java.sql.Types;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.SimpleTimeZone;
import java.util.TimeZone;
import java.util.UUID; import java.util.UUID;
import org.h2.api.Trigger; import org.h2.api.Trigger;
import org.h2.constant.ErrorCode; import org.h2.constant.ErrorCode;
import org.h2.test.TestBase; import org.h2.test.TestBase;
import org.h2.util.DateTimeUtils;
import org.h2.util.Task; import org.h2.util.Task;
/** /**
...@@ -44,6 +51,7 @@ public class TestPreparedStatement extends TestBase { ...@@ -44,6 +51,7 @@ public class TestPreparedStatement extends TestBase {
public void test() throws Exception { public void test() throws Exception {
deleteDb("preparedStatement"); deleteDb("preparedStatement");
Connection conn = getConnection("preparedStatement"); Connection conn = getConnection("preparedStatement");
testDateTimeTimestampWithCalendar(conn);
testCallTablePrepared(conn); testCallTablePrepared(conn);
testValues(conn); testValues(conn);
testToString(conn); testToString(conn);
...@@ -81,6 +89,95 @@ public class TestPreparedStatement extends TestBase { ...@@ -81,6 +89,95 @@ public class TestPreparedStatement extends TestBase {
deleteDb("preparedStatement"); deleteDb("preparedStatement");
} }
private void testDateTimeTimestampWithCalendar(Connection conn) throws SQLException {
Statement stat = conn.createStatement();
stat.execute("create table ts(x timestamp primary key)");
stat.execute("create table t(x time primary key)");
stat.execute("create table d(x date)");
Calendar utcCalendar = new GregorianCalendar(new SimpleTimeZone(0, "Z"));
TimeZone old = TimeZone.getDefault();
DateTimeUtils.resetCalendar();
TimeZone.setDefault(TimeZone.getTimeZone("PST"));
try {
Timestamp ts1 = Timestamp.valueOf("2010-03-13 18:15:00");
Time t1 = new Time(ts1.getTime());
Date d1 = new Date(ts1.getTime());
// when converted to UTC, this is 03:15, which doesn't actually exist
// because of summer time change at that day
Timestamp ts2 = Timestamp.valueOf("2010-03-13 19:15:00");
Time t2 = new Time(ts2.getTime());
Date d2 = new Date(ts2.getTime());
PreparedStatement prep;
ResultSet rs;
prep = conn.prepareStatement("insert into ts values(?)");
prep.setTimestamp(1, ts1, utcCalendar);
prep.execute();
prep.setTimestamp(1, ts2, utcCalendar);
prep.execute();
prep = conn.prepareStatement("insert into t values(?)");
prep.setTime(1, t1, utcCalendar);
prep.execute();
prep.setTime(1, t2, utcCalendar);
prep.execute();
prep = conn.prepareStatement("insert into d values(?)");
prep.setDate(1, d1, utcCalendar);
prep.execute();
prep.setDate(1, d2, utcCalendar);
prep.execute();
rs = stat.executeQuery("select * from ts order by x");
rs.next();
assertEquals("2010-03-14 02:15:00.0", rs.getString(1));
assertEquals("2010-03-13 18:15:00.0", rs.getTimestamp(1, utcCalendar).toString());
assertEquals("2010-03-14 03:15:00.0", rs.getTimestamp(1).toString());
assertEquals("2010-03-14 02:15:00.0", rs.getString("x"));
assertEquals("2010-03-13 18:15:00.0", rs.getTimestamp("x", utcCalendar).toString());
assertEquals("2010-03-14 03:15:00.0", rs.getTimestamp("x").toString());
rs.next();
assertEquals("2010-03-14 03:15:00.0", rs.getString(1));
assertEquals("2010-03-13 19:15:00.0", rs.getTimestamp(1, utcCalendar).toString());
assertEquals("2010-03-14 03:15:00.0", rs.getTimestamp(1).toString());
assertEquals("2010-03-14 03:15:00.0", rs.getString("x"));
assertEquals("2010-03-13 19:15:00.0", rs.getTimestamp("x", utcCalendar).toString());
assertEquals("2010-03-14 03:15:00.0", rs.getTimestamp("x").toString());
rs = stat.executeQuery("select * from t order by x");
rs.next();
assertEquals("02:15:00", rs.getString(1));
assertEquals("18:15:00", rs.getTime(1, utcCalendar).toString());
assertEquals("02:15:00", rs.getTime(1).toString());
assertEquals("02:15:00", rs.getString("x"));
assertEquals("18:15:00", rs.getTime("x", utcCalendar).toString());
assertEquals("02:15:00", rs.getTime("x").toString());
rs.next();
assertEquals("03:15:00", rs.getString(1));
assertEquals("19:15:00", rs.getTime(1, utcCalendar).toString());
assertEquals("03:15:00", rs.getTime(1).toString());
assertEquals("03:15:00", rs.getString("x"));
assertEquals("19:15:00", rs.getTime("x", utcCalendar).toString());
assertEquals("03:15:00", rs.getTime("x").toString());
rs = stat.executeQuery("select * from d order by x");
rs.next();
assertEquals("2010-03-14", rs.getString(1));
assertEquals("2010-03-13", rs.getDate(1, utcCalendar).toString());
assertEquals("2010-03-14", rs.getDate(1).toString());
assertEquals("2010-03-14", rs.getString("x"));
assertEquals("2010-03-13", rs.getDate("x", utcCalendar).toString());
assertEquals("2010-03-14", rs.getDate("x").toString());
rs.next();
assertEquals("2010-03-14", rs.getString(1));
assertEquals("2010-03-13", rs.getDate(1, utcCalendar).toString());
assertEquals("2010-03-14", rs.getDate(1).toString());
assertEquals("2010-03-14", rs.getString("x"));
assertEquals("2010-03-13", rs.getDate("x", utcCalendar).toString());
assertEquals("2010-03-14", rs.getDate("x").toString());
} finally {
TimeZone.setDefault(old);
DateTimeUtils.resetCalendar();
}
stat.execute("drop table ts");
stat.execute("drop table t");
stat.execute("drop table d");
}
private void testCallTablePrepared(Connection conn) throws SQLException { private void testCallTablePrepared(Connection conn) throws SQLException {
PreparedStatement prep = conn.prepareStatement("call table(x int = (1))"); PreparedStatement prep = conn.prepareStatement("call table(x int = (1))");
prep.executeQuery(); prep.executeQuery();
......
...@@ -463,10 +463,10 @@ public class TestDate extends TestBase { ...@@ -463,10 +463,10 @@ public class TestDate extends TestBase {
assertEquals("19999-08-07 13:14:15.16", ts2.getString()); assertEquals("19999-08-07 13:14:15.16", ts2.getString());
assertEquals("19999-08-07", d2.getString()); assertEquals("19999-08-07", d2.getString());
assertEquals("13:14:15.16", t2.getString()); assertEquals("13:14:15.16", t2.getString());
java.sql.Timestamp ts1a = DateTimeUtils.convertTimestampToCalendar(ts1.getTimestamp(), Calendar.getInstance()); ValueTimestamp ts1a = DateTimeUtils.convertTimestamp(ts1.getTimestamp(), Calendar.getInstance());
java.sql.Timestamp ts2a = DateTimeUtils.convertTimestampToCalendar(ts2.getTimestamp(), Calendar.getInstance()); ValueTimestamp ts2a = DateTimeUtils.convertTimestamp(ts2.getTimestamp(), Calendar.getInstance());
assertEquals("-999-08-07 13:14:15.16", ValueTimestamp.get(ts1a).getString()); assertEquals("-999-08-07 13:14:15.16", ts1a.getString());
assertEquals("19999-08-07 13:14:15.16", ValueTimestamp.get(ts2a).getString()); assertEquals("19999-08-07 13:14:15.16", ts2a.getString());
} }
} }
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论