oracle java.util.Timestamp.after() 比较毫秒时出错?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2321359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
java.util.Timestamp.after() wrong when comparing milliseconds?
提问by BestPractices
I am pulling dates out of an Oracle database. They are set on a java.util.Date field and they are in reality java.sql.Timestamp instances (which is a subclass of Java.util.Date). If I compare two of these timestamps from two different database records by calling after() on the first date and compare it to the second, I get the wrong answer when all parts of the date are the same except for the milliseconds.
我正在从 Oracle 数据库中提取日期。它们设置在 java.util.Date 字段上,实际上它们是 java.sql.Timestamp 实例(它是 Java.util.Date 的子类)。如果我通过在第一个日期调用 after() 来比较来自两个不同数据库记录的两个时间戳并将其与第二个进行比较,那么当日期的所有部分都相同时,除了毫秒之外,我会得到错误的答案。
All of the following should result in "true", however the second set of numbers does not:
以下所有结果都应为“真”,但第二组数字不会:
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
I know nanos are stored separately from the Date instance in the Timestamp class and I am curious if this is the issue.
我知道 nanos 与 Timestamp 类中的 Date 实例分开存储,我很好奇这是否是问题所在。
采纳答案by Konrad Garus
You can compare them, but only by comparing millis. While it's quite ugly, it seems to work in all cases (regardless of which is java.sql.Timestamp
or java.util.Date
).
您可以比较它们,但只能通过比较毫秒。虽然它很丑陋,但它似乎适用于所有情况(无论是java.sql.Timestamp
还是java.util.Date
)。
if(date1.getTime() > date2.getTime()) {
//...
}
回答by s_t_e_v_e
The key to the problem here is when the Timestamps are cast up to Date objects. The aftermethod of Date is being used instead of the aftermethod in Timestamp. When not cast to Date, the aftermethod of Timestamp will work correctly.
这里问题的关键是时间戳何时被转换为 Date 对象。在后日期的方法正在使用,而不是之后在时间戳方法。当不强制转换为 Date 时,Timestamp的after方法将正常工作。
I guess I need a lesson now on covariant method parametersas to why the aftermethod in Timestamp isn't called in the following code.
我想我现在需要关于协变方法参数的课程,以了解为什么在以下代码中没有调用 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());
}
results
结果
one: 1266873627200
two: 1266873627000
1266873627000 after 1266873627200
回答by Sam Merrell
It looks like the problem you're having is that firstDate and secondDate are set to Java.util.Date objects but the JavaDoc for java.sql.Timestampmentions that it is a composite of java.util.Date and a separate nanoseconds value.
看起来您遇到的问题是 firstDate 和 secondDate 设置为 Java.util.Date 对象,但java.sql.Timestamp的 JavaDoc提到它是 java.util.Date 和单独的纳秒值的组合。
This is why it is returning false when you are trying to compare the two. If you changed firstDate and secondDate over to actual Timestamp objects they should work.
这就是为什么当您尝试比较两者时它返回 false 的原因。如果您将 firstDate 和 secondDate 更改为实际的 Timestamp 对象,它们应该可以工作。
回答by Alexander Pogrebnyak
Without the actual code this is a speculation, but I think one of your objects is java.util.Date
and the other is java.sql.Timestamp
you cannot really compare them, as the millis
field in 'Timestamp' is truncated to a second and the remainder is stored in nanos
field. It's really unfortunate that Timestamp
is a subclass of Date
. This definitely leads to a problem that you are experiencing.
如果没有实际代码,这是一种推测,但我认为您的一个对象是java.util.Date
,另一个是java.sql.Timestamp
您无法真正比较它们,因为millis
“时间戳”中的字段被截断为一秒,其余部分存储在nanos
字段中。真是不幸的Timestamp
是Date
. 这肯定会导致您遇到的问题。
EDIT.
编辑。
One more possibility, is that your DB driver returns its own subclass of Timestamp
. Because the class is not final it's quite possible that their implementation screwed up Timestamp's compare
, not that it's particularly hard to do.
另一种可能性是您的数据库驱动程序返回其自己的Timestamp
. 因为该类不是最终的,所以他们的实现很可能搞砸了 Timestamp 的compare
,而不是特别难做到。