减少使用 Date类 相关组合

什么是Date类?

Date类表示时间上的特定时刻,具有毫秒精度。

简言之,指发生某一事情的确定的日子、时期的抽象。

在教学中,几乎所有的课程都指向使用Date类对象封装传递系统中的日期、时刻。

如果有心阅读JDK中Date类的注释:

Prior to JDK 1.1, the class Date had two additional functions. It allowed the interpretation of dates as year, month, day, hour, minute, and second values. It also allowed the formatting and parsing of date strings. Unfortunately, the API for these functions was not amenable to internationalization. As of JDK 1.1, the Calendar class should be used to convert between dates and time fields and the DateFormat class should be used to format and parse date strings. The corresponding methods in Date are deprecated.

Date类源自JDK1.0,在JDK1.1之后发现其API无法适应国际化,从JDK 1.1开始,应该使用Calendar类在日期和时间字段之间进行转换,而使用DateFormat类格式化和解析日期字符串。Date中的对应方法已弃用。

查询Date类中@Deprecated(弃用)注释,可以发现大部分的API已是过时且不合理的设计:

无法解决闰秒、无法适应不同的时区标准等

其中最严重的问题当属,Date类在多线程场景下(即大部分互联网生态),由于其字段可变特性,导致线程不安全的问题,需要开发者自己去确保线程的安全性。

小结,Date类有3大问题:

  1. 闰秒问题(闰年的前一年最后一分钟为61秒);
  2. 国际化问题(不同的时区标准);
  3. 线程不安全问题(单一对象可变的属性)。

JDK如何解决Date类上述的问题?

根据Date类的指引,JDK1.1之后推荐使用 Calendar 日历类 与 DataFormat 日期格式类。

  •  Calendar类

Calendar类是一个抽象类,它提供了一些方法,用于在时间上的特定时刻和一组日历字段(如YEAR、MONTH、DAY_OF_MONTH、HOUR等)之间进行转换,以及操作日历字段(如获取下周的日期)。

时间上的瞬间用毫秒值表示,毫秒值是自Epoch(1970年1月1日00:00:00.000 GMT (Gregorian))的偏移量。

Calendar对Date中存在的闰秒问题国际化问题进行了解决:Calendar以两种方式表示当前时间:从epoch(1970年1月1日0:00 UTC)开始的UTC毫秒,以及本地字段,如MONTH、HOUR、AM_PM等。可以从字段中计算millis,反之亦然。

线程的安全性没有提供相应的方案。

  • DataFormat类(抽象类)

DateFormat是日期/时间格式化子类的抽象类,该子类以独立于语言的方式格式化和解析日期或时间。日期/时间格式化子类,比如SimpleDateFormat,允许格式化(即,日期→文本)、解析(文本→日期)和规范化。日期表示为date对象或自1970年1月1日00:00:00 GMT以来的毫秒数。

因此用于使用的实体类教学中惯用的SimpleDateFormat。

SimpleDateFormat是一个具体的类,用于以对语言环境敏感的方式格式化和解析日期。它允许格式化(日期→文本)、解析(文本→日期)和规范化。SimpleDateFormat向下兼容可使用Date类日期,即常见的Date+SimpleDateFormat组合,实际上根据JDK1.1的建议,应该是Calendar+SimpleDateFormat组合。但,即使是这样,也存在一个问题。

从SimpleDateFormat类的注释结尾,清晰的写着,它不是一个线程安全的类,SimpleDateFormat也有着不同步的问题,线程安全问题。

基于Calendar+SimpleDateFormat组合,JDK有没有提供解决以上问题的方案?

答案是肯定的。

从JDK1.8开始,JDK增加了新的日期时间类 LocalDateTime 类以及新的日期格式类 DateTimeFormatter类。

  • LocalDateTime

LocalDateTime是一个不可变的date-time对象,它表示一个日期-时间,通常被视为年-月-日-小时-分钟-秒。该类不存储或表示时区。相反,它是对日期的描述,如用于生日,并结合在墙上的时钟上看到的当地时间。在没有偏移量或时区等附加信息的情况下,它无法表示时间线上的一个瞬间。

因此解决了线程安全的需求,开发者无需考虑并发编程。

  • DateTimeFormatter

DateTimeFormatter用于打印和解析日期时间对象的格式化程序。实例化的过程为获取所需的格式化器,载入日期对象即可完成格式化。类的注释结尾写着此类为线程安全类。

所以如果希望线程安全,可以使用:LocalDateTime+DateTimeFormatter组合。

一定要线程安全吗?如何选择?

实际上,从设计角度而言,大部分的业务场景都是单线程的,所以没必要每个类都设计为不可变或全部synchronized。所以按实际业务的需求分配合适的组合。

单线程:Calendar+SimpleDateFormat

多线程:LocalDateTime+DateTimeFormatter

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值