【问题标题】:java.util.Timestamp.after() wrong when comparing milliseconds?java.util.Timestamp.after() 比较毫秒时出错?
【发布时间】:2010-02-23 20:12:49
【问题描述】:

我正在从 Oracle 数据库中提取日期。它们设置在 java.util.Date 字段上,它们实际上是 java.sql.Timestamp 实例(它是 Java.util.Date 的子类)。如果我通过在第一个日期调用 after() 来比较两个不同数据库记录中的两个时间戳并将其与第二个日期进行比较,那么当日期的所有部分除了毫秒之外都相同时,我会得到错误的答案。

以下所有结果都应为“真”,但第二组数字则不然:

firstDate  = 1/1/2000 12:00:20:00
secondDate = 1/1/2000 12:00:10:00
result = firstDate.after(secondDate);
result is TRUE <-- EXPECTED RESULT

firstDate  = 1/1/2000 12:00:00:10
secondDate = 1/1/2000 12:00:00:00
result = firstDate.after(secondDate);
result is FALSE <-- NOT EXPECTED, result should be TRUE 

我知道 nanos 与 Timestamp 类中的 Date 实例分开存储,我很好奇这是否是问题所在。

【问题讨论】:

  • 使用 SimpleDateFormat 打印日期以便调试。
  • 请发布实际代码,而不是伪代码。其次,没有java.util.Timestamp这样的东西,你的意思是java.sql.Timestamp吗?

标签: java oracle time


【解决方案1】:

您可以比较它们,但只能通过比较毫秒。虽然它很丑陋,但它似乎适用于所有情况(无论是java.sql.Timestamp 还是java.util.Date)。

if(date1.getTime() > date2.getTime()) {
  //...
}

【讨论】:

    【解决方案2】:

    这里问题的关键是时间戳何时转换为 Date 对象。正在使用 Date 的 after 方法,而不是 Timestamp 中的 after 方法。当不强制转换为 Date 时,Timestamp 的 after 方法将正常工作。

    我想我现在需要在covariant method parameters 上学习一下为什么下面的代码中没有调用 Timestamp 中的 after 方法。

        java.sql.Timestamp one = new java.sql.Timestamp(1266873627200L);
        java.sql.Timestamp two = new java.sql.Timestamp(1266873627000L);
    
        java.util.Date oneDate = (java.util.Date) one;
        java.util.Date twoDate = (java.util.Date) two;
    
    
        System.out.println("one: " + oneDate.getTime());
        System.out.println("two: " + twoDate.getTime());
    
        if (oneDate.after(twoDate)) {
            System.out.println(oneDate.getTime() + " after " + twoDate.getTime());
        } else {
            System.out.println(twoDate.getTime() + " after " + oneDate.getTime());
        }
    

    结果

    one: 1266873627200
    two: 1266873627000
    1266873627000 after 1266873627200
    

    【讨论】:

      【解决方案3】:

      看起来您遇到的问题是 firstDate 和 secondDate 设置为 Java.util.Date 对象,但 java.sql.Timestamp 的 JavaDoc 提到它是 java.util.Date 和单独的纳秒值的组合.

      这就是当您尝试比较两者时它返回 false 的原因。如果您将 firstDate 和 secondDate 更改为实际的 Timestamp 对象,它们应该可以工作。

      【讨论】:

        【解决方案4】:

        如果没有实际代码,这是一种推测,但我认为您的一个对象是 java.util.Date,另一个是 java.sql.Timestamp,您无法真正比​​较它们,因为“时间戳”中的 millis 字段被截断为第二个,余数存储在nanos 字段中。很遗憾TimestampDate 的子类。这肯定会导致您遇到问题。

        编辑。

        另一种可能性是,您的 DB 驱动程序返回其自己的 Timestamp 子类。因为这个类不是最终的,所以他们的实现很可能搞砸了 Timestamp 的compare,并不是说它特别难做到。

        【讨论】:

        • 它们都是 java.sql.Timestamp 实例。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-29
        • 1970-01-01
        • 2014-12-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多