奇怪的Java SQL时间戳日历检索行为-从日历中获取毫秒



代码片段:

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,我发现一个相当模糊的语句,似乎暗示这是指定的行为:

"此方法使用给定的日历为时间戳构造一个适当的毫秒值"

源文件的第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中提供毫秒值。但是,它与ResultSet (RowSet从其扩展)的文档有些不同。

这个方法使用给定的日历构造一个合适的如果底层数据库有,则为时间戳的毫秒值不存储时区信息

这似乎将两个看似无关的概念联系在一起——数据库中时区信息的存在和数据库中时间戳字段的精度。

源代码中的问题实际上在日历填充之前开始:

   defaultCal.setTime((java.util.Date)value);

通过将时间戳转换为java.util。日期,所有部分秒数据丢失。如时间戳javadoc中所述:

注意:该类型是java.util.Date和一个独立的纳秒值。中只存储整数秒java.util.Date组件。

最新更新