此代码段:
private Date fetchTimestampFromDatabase(SqlRowSet rs, String field) {
try {
System.out.println(rs.getTimestamp(field));
for (int i = 0; i < 10; i++) {
System.out.println(rs.getTimestamp(field, Calendar.getInstance(TimeZone.getTimeZone("UTC"))));
Thread.sleep(200);
...
给出以下结果:
2014-06-06 10:44:58.696
2014-06-06 12:44:58.75
2014-06-06 12:44:58.95
2014-06-06 12:44:58.15
2014-06-06 12:44:58.35
2014-06-06 12:44:58.55
2014-06-06 12:44:58.75
2014-06-06 12:44:58.95
2014-06-06 12:44:58.15
2014-06-06 12:44:58.35
2014-06-06 12:44:58.55
很好,时区偏移是正确应用的,但为什么地球上的毫秒被摇晃,大概是从日历实例中获取的呢?
读取方法的javadoc,我发现了一个相当模糊的陈述,似乎暗示这是按照指定的行为:
&#34;此方法使用给定的日历为时间戳构建适当的毫秒值&#34;
the source file的第6180行确认了这一点:
cal.set(Calendar.YEAR, defaultCal.get(Calendar.YEAR));
cal.set(Calendar.MONTH, defaultCal.get(Calendar.MONTH));
cal.set(Calendar.DAY_OF_MONTH, defaultCal.get(Calendar.DAY_OF_MONTH));
cal.set(Calendar.HOUR_OF_DAY, defaultCal.get(Calendar.HOUR_OF_DAY));
cal.set(Calendar.MINUTE, defaultCal.get(Calendar.MINUTE));
cal.set(Calendar.SECOND, defaultCal.get(Calendar.SECOND));
return new java.sql.Timestamp(cal.getTime().getTime());
有谁知道为什么没有设置Calendar.MILLISECOND?
干杯
答案 0 :(得分:1)
文档似乎表明预计将在日历中提供毫秒值。 但是,它与ResultSet的documentation(RowSet扩展)有些不同。
此方法使用给定的日历构造适当的日历 如果底层数据库的时间戳,则为时间戳的毫秒值 不存储时区信息。
这似乎将2个看似无关的概念联系在一起 - 数据库中存在时区信息,数据库中存在时间戳字段的精度。
源代码中的问题实际上是在日历填充之前开始的:
defaultCal.setTime((java.util.Date)value);
通过将时间戳转换为java.util.Date,所有部分第二个数据都将丢失。如Timestamp javadoc:
中所述注意:此类型是java.util.Date和单独的类型的组合 纳秒值。只有整数秒存储在 java.util.Date组件。