我正在谈论这种界面方法:
最常用的实现是cachedrowset中的实现:
你会注意到实现有两件非常奇怪的事情:
1)它修改作为参数传递的日历,即使还有返回值
2)它从SQL中提取所有时间信息,除了毫秒,它来自作为参数传递的日历。
接口描述相当不清楚,但假设实现是正确的 - 这个方法有什么意义?我可以理解一种方法,它可以使日历只提取时区,而无需修改它。但是拿一个日历,修改它,不仅提取区域而且提取毫秒...
有没有人对此API背后的历史/设计/推理有任何见解?
答案 0 :(得分:2)
这似乎是对JDBC API文档的错误解释(不幸的是javax.sql.rowset
有更多错误的解释)。
默认情况下,JDBC驱动程序需要存储或检索时间或时间戳,就好像存储在数据库中的时间位于JVM的当前时区中一样。由于这并不总是您想要的,API提供了提供Calendar
对象的方法,您需要使用它来派生实际使用的时区(我不知道它们为什么不使用{{} 1}}代替)。
这在PreparedStatement.setTimeStamp中指定:
使用
java.util.TimeZone
对象,驱动程序可以计算时间戳,并考虑自定义时区。如果未指定Calendar
对象,则驱动程序将使用默认时区,即运行应用程序的虚拟机的时区。
Calendar
中的方法getTimestamp
遵循(或应遵循)这些相同的规则。
因此,如果数据库存储时间'11:20'且您的本地时区为CET(UTC + 1),则检索的时间为10:20 UTC(欧洲中部时间11:20)。但是,如果我在GMT中提供ResultSet
,则返回的时间应为UTC时间11:20(欧洲中部时间12:20)。
答案 1 :(得分:1)
SQL数据库以年,月,日,小时,秒等形式存储时间戳的日期和时间值。这些值指定的实例取决于它们所在的 timezone 被解释(例如2014年1月1日15:00:00在欧洲不是在美国同时)。时区可能或可能不会成为时间戳的一部分,具体取决于列的类型。
Java java.sql.Timestamp
和java.util.Date
类表示时间的实例,与时区无关(或者更确切地说是固定的UTC时区)。
如果SQL数据库中的列没有存储时区信息以及日期+时间,那么为了从这样的时间戳创建Java Date
或TimeStamp
对象需要一个时区,所以它可以指向特定的实例(在参考UTC时区中)。
可以使用ResultSet.getTimestamp()
方法获取SQL时间戳数据,并使用参数Timestamp
对象中设置的时区信息将其转换为Java Calendar
实例。