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


    开发手册

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

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

    原因

    Oracle官网文档中这么写:

    可以看到,根源是因为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.

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

    1. after的问题

    after的问题更加重要。

    期待的答案应该是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及其子类的对象比较。

  • 相关阅读:
    Https的1.0、2.0协议及长短链接区别
    点云直通滤波(附python open3d 代码)
    MySQL安全性策略:用户认证与数据加密
    线程池的实现
    2-7.基金销售行为规范及信息管理
    maven了解
    Apache ShardingSphere 5.1.0 正式发布
    想晋升Android架构师——学习这些核心技术够用吗?
    CV学习笔记-BP神经网络代码Python实例
    Hive中窗口函数的基本语法和示例
  • 原文地址:https://www.cnblogs.com/daheww/p/16741286.html