提交 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
if (x == null) {
setParameter(parameterIndex, ValueNull.INSTANCE);
} else {
setParameter(parameterIndex, DateTimeUtils.convertDateToUTC(x, calendar));
setParameter(parameterIndex, DateTimeUtils.convertDate(x, calendar));
}
} catch (Exception e) {
throw logAndConvert(e);
......@@ -635,7 +635,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements PreparedStat
if (x == null) {
setParameter(parameterIndex, ValueNull.INSTANCE);
} else {
setParameter(parameterIndex, DateTimeUtils.convertTimeToUTC(x, calendar));
setParameter(parameterIndex, DateTimeUtils.convertTime(x, calendar));
}
} catch (Exception e) {
throw logAndConvert(e);
......@@ -659,7 +659,7 @@ public class JdbcPreparedStatement extends JdbcStatement implements PreparedStat
if (x == null) {
setParameter(parameterIndex, ValueNull.INSTANCE);
} else {
setParameter(parameterIndex, DateTimeUtils.convertTimestampToUTC(x, calendar));
setParameter(parameterIndex, DateTimeUtils.convertTimestamp(x, calendar));
}
} catch (Exception e) {
throw logAndConvert(e);
......
......@@ -806,8 +806,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
if (isDebugEnabled()) {
debugCode("getDate(" + columnIndex + ", calendar)");
}
Date x = get(columnIndex).getDate();
return DateTimeUtils.convertDateToCalendar(x, calendar);
return DateTimeUtils.convertDate(get(columnIndex), calendar);
} catch (Exception e) {
throw logAndConvert(e);
}
......@@ -828,8 +827,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
if (isDebugEnabled()) {
debugCode("getDate(" + StringUtils.quoteJavaString(columnLabel) + ", calendar)");
}
Date x = get(columnLabel).getDate();
return DateTimeUtils.convertDateToCalendar(x, calendar);
return DateTimeUtils.convertDate(get(columnLabel), calendar);
} catch (Exception e) {
throw logAndConvert(e);
}
......@@ -850,8 +848,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
if (isDebugEnabled()) {
debugCode("getTime(" + columnIndex + ", calendar)");
}
Time x = get(columnIndex).getTime();
return DateTimeUtils.convertTimeToCalendar(x, calendar);
return DateTimeUtils.convertTime(get(columnIndex), calendar);
} catch (Exception e) {
throw logAndConvert(e);
}
......@@ -872,8 +869,7 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
if (isDebugEnabled()) {
debugCode("getTime(" + StringUtils.quoteJavaString(columnLabel) + ", calendar)");
}
Time x = get(columnLabel).getTime();
return DateTimeUtils.convertTimeToCalendar(x, calendar);
return DateTimeUtils.convertTime(get(columnLabel), calendar);
} catch (Exception e) {
throw logAndConvert(e);
}
......@@ -894,8 +890,8 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
if (isDebugEnabled()) {
debugCode("getTimestamp(" + columnIndex + ", calendar)");
}
Timestamp x = get(columnIndex).getTimestamp();
return DateTimeUtils.convertTimestampToCalendar(x, calendar);
Value value = get(columnIndex);
return DateTimeUtils.convertTimestamp(value, calendar);
} catch (Exception e) {
throw logAndConvert(e);
}
......@@ -915,8 +911,8 @@ public class JdbcResultSet extends TraceObject implements ResultSet {
if (isDebugEnabled()) {
debugCode("getTimestamp(" + StringUtils.quoteJavaString(columnLabel) + ", calendar)");
}
Timestamp x = get(columnLabel).getTimestamp();
return DateTimeUtils.convertTimestampToCalendar(x, calendar);
Value value = get(columnLabel);
return DateTimeUtils.convertTimestamp(value, calendar);
} catch (Exception e) {
throw logAndConvert(e);
}
......
......@@ -11,18 +11,25 @@ import java.io.IOException;
import java.io.StringReader;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.Date;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Time;
import java.sql.Timestamp;
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 org.h2.api.Trigger;
import org.h2.constant.ErrorCode;
import org.h2.test.TestBase;
import org.h2.util.DateTimeUtils;
import org.h2.util.Task;
/**
......@@ -44,6 +51,7 @@ public class TestPreparedStatement extends TestBase {
public void test() throws Exception {
deleteDb("preparedStatement");
Connection conn = getConnection("preparedStatement");
testDateTimeTimestampWithCalendar(conn);
testCallTablePrepared(conn);
testValues(conn);
testToString(conn);
......@@ -81,6 +89,95 @@ public class TestPreparedStatement extends TestBase {
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 {
PreparedStatement prep = conn.prepareStatement("call table(x int = (1))");
prep.executeQuery();
......
......@@ -463,10 +463,10 @@ public class TestDate extends TestBase {
assertEquals("19999-08-07 13:14:15.16", ts2.getString());
assertEquals("19999-08-07", d2.getString());
assertEquals("13:14:15.16", t2.getString());
java.sql.Timestamp ts1a = DateTimeUtils.convertTimestampToCalendar(ts1.getTimestamp(), Calendar.getInstance());
java.sql.Timestamp ts2a = DateTimeUtils.convertTimestampToCalendar(ts2.getTimestamp(), Calendar.getInstance());
assertEquals("-999-08-07 13:14:15.16", ValueTimestamp.get(ts1a).getString());
assertEquals("19999-08-07 13:14:15.16", ValueTimestamp.get(ts2a).getString());
ValueTimestamp ts1a = DateTimeUtils.convertTimestamp(ts1.getTimestamp(), Calendar.getInstance());
ValueTimestamp ts2a = DateTimeUtils.convertTimestamp(ts2.getTimestamp(), Calendar.getInstance());
assertEquals("-999-08-07 13:14:15.16", ts1a.getString());
assertEquals("19999-08-07 13:14:15.16", ts2a.getString());
}
}
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论