Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java.sql.Timestamp是从java.util.Date创建的,为什么总是在它之前?_Java_Time - Fatal编程技术网

java.sql.Timestamp是从java.util.Date创建的,为什么总是在它之前?

java.sql.Timestamp是从java.util.Date创建的,为什么总是在它之前?,java,time,Java,Time,在一个bug之后,我注意到如果使用以毫秒为单位的构造函数从java.util.Date创建java.sql.Timestamp,则Date实例总是在时间戳之后。这是令人费解的,因为(a)before()的契约指定了严格的比较,(b)如果不相等,时间戳(因为它有纳秒)本身可能在日期()之后。但是结果是相反的,并且是可重复的(对于JDK1.6和1.7,使用不同的JVM时区)。比较两个日期是正确的,但是对一个日期调用before()或after()并给出Timestamp参数会产生意外的结果 下面的示

在一个bug之后,我注意到如果使用以毫秒为单位的构造函数从java.util.Date创建java.sql.Timestamp,则Date实例总是在时间戳之后。这是令人费解的,因为(a)before()的契约指定了严格的比较,(b)如果不相等,时间戳(因为它有纳秒)本身可能在日期()之后。但是结果是相反的,并且是可重复的(对于JDK1.6和1.7,使用不同的JVM时区)。比较两个日期是正确的,但是对一个日期调用before()或after()并给出Timestamp参数会产生意外的结果

下面的示例代码有两个日期和一个时间戳实例,它们都具有相同的毫秒值。然而,将日期与时间戳进行比较会显示日期在时间戳之后

import java.util.Date;
import java.sql.Timestamp;

public class X extends Date {

    public static void main(String[] args) {
        Date d1 = new Date();
        Date d2 = new Date(d1.getTime());
        Timestamp t = new Timestamp (d1.getTime());
        System.out.println ("date1 = " + d1 + " (" + d1.getTime() + ")" );
        System.out.println ("date2 = " + d2 + " (" + d2.getTime() + ")" );
        System.out.println ("timestamp = " + t + "  (" + t.getTime() + ")" );
        System.out.println ("d1 before d2: " + d1.before(d2));
        System.out.println ("d1 after  d2: " + d1.after(d2));
        System.out.println ("d1 before ts: " + d1.before(t));
        System.out.println ("d1 after  ts: " + d1.after(t)); //why true?
    }
}
样本输出:

C:\>\Java\jdk1.7.0_05\bin\java X
date1 = Tue Oct 30 10:15:59 EDT 2012 (1351606559812)
date2 = Tue Oct 30 10:15:59 EDT 2012 (1351606559812)
timestamp = 2012-10-30 10:15:59.812  (1351606559812)
d1 before d2: false
d1 after  d2: false
d1 before ts: false
d1 after  ts: true
最后一行是奇怪的一行


谢谢。

如果您查看内部表示以及
after()
方法中比较的内容,您可以看到例如

millis = 1351607849957
您将获得一个
日期

fastTime = 1351607849957
fastTime = 1351607849000
nanos = 957000000
以及带有

fastTime = 1351607849957
fastTime = 1351607849000
nanos = 957000000
由于所有的比较都是
fastTime
部分,因此您可以观察到您的行为。
正如@user714965在上面指出的,您不应该将
时间戳
视为
日期
java.sql的API文档中所说:

注意:此类型是一个
java.util.Date
和一个单独的纳秒值的组合。
java.util.Date
组件中只存储整数秒。分数秒-纳米-是分开的

(这与Keppil的回答一致)

它还说:

由于
Timestamp
类和上述
java.util.Date
类之间的差异,建议代码不要将
Timestamp
值作为
java.util.Date
的一个实例来查看。
Timestamp
java.util.Date
之间的继承关系实际上表示实现继承,而不是类型继承

这意味着您不应该将
时间戳
视为
java.util.Date
,如果您将它传递给
java.util.Date.after()
(该方法需要一个
java.util.Date
——您正在传递一个
时间戳,将其视为
java.util.Date
,此注释说您不应该这样做)


在标准Java库中,这当然是糟糕的设计。如果您需要处理日期和时间,请使用一个设计更好、功能更强大的库。

使用调试器指出这一点。并提醒“[…]建议代码不要将时间戳值作为Java.util.Date的实例进行查看。”
d1.compareTo(ts)
结果
1
,表明存在1纳米级的差异或类似的东西。我相信这是一个bug,是的。找到它很好!仅供参考,非常麻烦的旧日期时间类,如,
java.text.SimpleDateFormat
,现在被内置到java 8和更高版本中的类所取代。看。是的,我知道这些se差异(以及不兼容,尤其是equals())以及Joda,但我正在寻找这种奇怪行为的解释。请注意,您可以深入研究类的源代码,例如
java.sql.Timestamp
,您可以在JDK安装目录中的文件
src.zip
中找到它。