为什么阿里Java开发手册不推荐使用Timestamp?

开发手册

为什么阿里Java开发手册不推荐使用Timestamp?

网上解释不推荐用 java.sql.Datejava.sql.Time的文章有很多,但是解释为什么不推荐使用 java.sql.Timestamp文章没找到。

参考文章:一文告诉你Java日期时间API到底有多烂

原因

Oracle官网文档中这么写:

为什么阿里Java开发手册不推荐使用Timestamp?

可以看到,根源是因为 java.sql.Timestamp父类 java.sql.DatefastTime属性存储秒,而 java.sql.Timestampnanos存储秒以外的毫秒。所以秒和毫秒是分别存储的,从 Timestamp的构造方法也可以看出来:

public Timestamp(long time) {
    // 设置java.sql.Date的fastTime
    super((time/1000)*1000);
    // 设置java.sql.Timestamp的nanos

    if (nanos < 0) {
        nanos = 1000000000 + nanos;
        super.setTime(((time/1000)-1)*1000);
    }
}

所以会有什么问题呢?

  1. equals的问题

The Timestamp.equals(Object) method never returns true when passed an object that isn’t an instance of java.sql.Timestamp, because the nanos component of a date is unknown.

为什么阿里Java开发手册不推荐使用Timestamp?

可能程序员会想,我两个时间都是从一个millis中创建的,那时间应该是一样的。但是因为 Timestamp的设计,它们的值不相等。

  1. after的问题

after的问题更加重要。

为什么阿里Java开发手册不推荐使用Timestamp?

期待的答案应该是 false,但程序返回的是 true。通过查看源码,找到了 after方法的代码:

    public boolean after(Date when) {
        // 比较mills
        return getMillisOf(this) > getMillisOf(when);
    }

    static final long getMillisOf(Date date) {
        if (date.cdate == null || date.cdate.isNormalized()) {
            // 拿fastTime的值做的比较
            return date.fastTime;
        }
        BaseCalendar.Date d = (BaseCalendar.Date) date.cdate.clone();
        return gcal.getTime(d);
    }

可以看到,它其实是拿两个对象的 fastTime值做的比较。

打断点,可以看到两个对象的 fastTime值分别为:

date对象的fastTime值为:     1664429777371
timestamp对象的fastTime值为:1664429777000

date的 fastTime值大于timestamp。那这又是为什么呢?

看一下Timestamp的构造方法:

public Timestamp(long time) {
    // 设置java.sql.Date的fastTime
    super((time/1000)*1000);
    // 设置java.sql.Timestamp的nanos

    if (nanos < 0) {
        nanos = 1000000000 + nanos;
        super.setTime(((time/1000)-1)*1000);
    }
}

可以知道timestamp对象的fastTime的后三位为0。

而看Date的构造方法:

    public Date(long date) {
        fastTime = date;
    }

它是直接把传入的值赋值给 fastTime

所以此处timestamp的 fastTime值小于date。

总结

不要将 java.sql.Timestamp和其它 java.util.Date及其子类的对象比较。

Original: https://www.cnblogs.com/daheww/p/16741286.html
Author: daheww
Title: 为什么阿里Java开发手册不推荐使用Timestamp?

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/715207/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球