【问题标题】:How do I retrieve the right timestamp from a MySQL database in Java?如何从 Java 中的 MySQL 数据库中检索正确的时间戳?
【发布时间】:2015-10-15 08:59:21
【问题描述】:

我将测量值​​存储在 MySQL 数据库中。 测量值包含一个时间戳字段,该字段以下列格式存储时间戳:

2015-10-10 10:10:10.11(所以有两位数的毫秒)

在我的 Java 代码中,我通过以下方式检索该值:

resultSet.getTimestamp(id)

当我打印这个值时,它给了我:

2015-10-10 11:11:11.000000011

所以我想弄清楚为什么它会这样,以及我应该如何解决这个问题,以便获得正确的价值?

编辑:

当使用 select * from measurement

时,这些值在数据库中正确显示

我猜它应该在 Java / JDBC 检索方式的某个地方。 getTimestamp 和 getString 都给了我相同的结果。

编辑 2:

resultSet = statement.executeQuery("select * from measurement");

Measurement m;

while(resultSet.next()) {
    m = new Measurement(
        resultSet.getString(1), 
        resultSet.getString(2), 
        resultSet.getDouble(4), 
        resultSet.getTimestamp(3));
    System.out.println(m);
}

【问题讨论】:

  • 您能否添加更多代码,我敢打赌您在某个时刻将时间戳存储在 long 或 double 中,然后您会失去精度......
  • 您使用的是哪个版本的 MySQL?
  • @Tunaki 我正在使用 MySQL 5.6.26,因为我需要至少 5.6.4 来存储小数秒。
  • @Jordi Castilla 我还没有通过代码存储数据,我已经通过 PHPmyAdmin 手动插入了
  • 根据您的最后一条评论:您很可能是正确的,因为 getTimestamp().getNano() 返回了我正在寻找的数字。因此,Java 以某种方式将小数部分转换为纳秒。,请粘贴您的 java 代码,该代码检索并从 sql 时间戳转换为 java Date....

标签: java mysql database timestamp


【解决方案1】:

我从来都不喜欢 MySQL 的 JDBC 驱动程序如何处理 TIMESTAMP 类型。我会使用:

select ROUND(UNIX_TIMESTAMP(col1)*1000) FROM measurement

然后阅读它

java.util.Date d = new java.util.Date(resultSet.getLong(1));

【讨论】:

  • 这看起来确实是解决我的问题的可靠方法。但是我也可以去存储我猜的 UNIX_TIMESTAMP...
【解决方案2】:

我一直在研究实施。尽管我有点不知所措,但我还是发现了一些“有趣”的信息。

com.mysql.jdbc.ResultSet.getTimestamp()的实现有一些端倪:

int year = 0;
int month = 0;
int day = 0;
int hour = 0;
int minutes = 0;
int seconds = 0;
int nanos = 0; <<< CLUE

if (numDigits < 9) {
    int factor = (int) (Math.pow(10, 9 - numDigits));
    nanos = nanos * factor;
}

TimeUtil.fastTimestampCreate(tz, year, month, day, hour, minutes, seconds, nanos);

所以它似乎解析了 '.' 之后的所有内容。纳秒以前导零结尾。所以.11变成.000000011.

所以我认为这解释了它发生的原因......

解决这个问题的方法有很多,其中一些是:

  1. 获取UNIX_TIMESTAMP 作为用户5449350 的答案。
  2. 存储UNIX_TIMESTAMPS 而不是TIMESTAMP / DATETIME
  3. 更正错误的 Date 对象并使用Calendar 更正它

    Date t = resultSet.getTimestamp(3);
    Calendar c = Calendar.getInstance();
    c.setTime(t);
    c.set(Calendar.MILLISECOND, ((Timestamp)t).getNanos());
    t = c.getTime();
    

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-27
    • 2011-07-08
    • 1970-01-01
    • 1970-01-01
    • 2013-05-27
    • 2019-08-09
    • 2015-06-13
    • 2012-08-20
    相关资源
    最近更新 更多