Java 在SQLServerCallableStatement.setDateTime()中设置GMT时区

Java 在SQLServerCallableStatement.setDateTime()中设置GMT时区,java,sql-server,jdbc,Java,Sql Server,Jdbc,我正在使用类型为SQLServerCallableStatement的可调用语句,因为我需要调用接受表类型参数的存储过程。prepared语句有一个方法setDateTime(),我用它来设置查询的开始和结束日期,如下所示: DateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss"); formatter.setTimeZone(TimeZone.getTimeZone("GMT")); Timestamp start

我正在使用类型为
SQLServerCallableStatement
的可调用语句,因为我需要调用接受表类型参数的存储过程。prepared语句有一个方法
setDateTime()
,我用它来设置查询的开始和结束日期,如下所示:

DateFormat formatter = new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss");
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));

Timestamp start = new Timestamp(formatter.parse(startDate).getTime());
Timestamp end = new Timestamp(formatter.parse(endDate).getTime());
Timestamp asOf = (asOfDate == null || asOfDate.isEmpty())  ? null : new Timestamp(formatter.parse(asOfDate).getTime());

final String sprocSQL = "EXEC timeseries.selectMultipleTimeseries @identifier_list=?, @dataset=?, @field_list=?, @publisher=?, @start_date=?, @end_date=?, @asof_date=?";
SQLServerCallableStatement stmt = connection.prepareCall(sprocSQL).unwrap(com.microsoft.sqlserver.jdbc.SQLServerCallableStatement.class);
stmt.setStructured(1, "timeseries.IdentifierList", identifierList);
stmt.setString(2, dataset);
stmt.setStructured(3, "timeseries.FieldList", fieldList);
stmt.setString(4, publisher);
stmt.setDateTime(5, start);
stmt.setDateTime(6, end);
stmt.setDateTime(7, asOf);
startDate
endDate
以GMT为单位,并且是正确的<代码>开始和<代码>结束是本地时间,也是正确的(我是欧洲/伦敦DST,即GMT+1)。问题似乎是传递给数据库的是localtime,但数据库将其解释为GMT。因此,如果
startDate
是09:00am,我将从10:00am获取数据。我怀疑正在发生的是,时间戳变量
start
end
以某种方式被视为字符串,并在没有TZ信息的情况下传递给数据库。是否有办法将此时区信息添加到
setDateTime()


查看
开始
,时间是正确的,上午9点。但是,当我将其打印为字符串时,它显示为10am,这是查询返回的数据-来自10am的数据。

首先,您使用的是
TimeZone.getTimeZone(“GMT”)
而不是
GMT+1
。其次,不要使用过时的
时间戳
stmt.setDateTime()
。将
stmt.setObject()
方法与
java.time
package中适当支持的类一起使用。相关,可能重复:。