JSR 310日期时间API

Java以JDK 8为界,有两套处理日期和时间的API,分别是DateJSR 310

java.util.Date自JDK1.0就已经存在,用于表示日期+时间的类型,虽然年代十分久远,并且此类具有的职责不单一,使用很不方便等诸多毛病,但因为时间久远,它的生命力依旧顽强,用户量庞大。

简单说几个Date的缺点:

  1. 定义不一致,在java.util和java.sql都有Date类,而且对它进行格式化/解析类又跑到了java.text中去了。

  2. java.util.Date等类在建模日期的设计上行为不一致,缺陷明显。包括易变性、糟糕的偏移值、默认值、命名等。

  3. java.util.Date同时包含日期和时间,而其子类java.sql.Date却仅仅包含日期。

  4. 国际化支持的并不是很好,比如跨时区操作,夏令时等。

14年随着Java 8的发布引入了全新的JSR 310日期时间。JSR 310源于joda-time打造,解决了诸多问题,是整个Java 8的最大亮点之一。

JSR 310日期时间所有的API都在java.time包中,没有例外。

时区/偏移量ZoneId

在JDK 8之前,Java使用java.util.TimeZone来表示时区。而在JDK 8之后分别使用了ZoneId表示时区,ZoneOffset表示UTC的偏移量。时区和偏移量在概念和实际作用上是有较大的区别的:

  1. UTC偏移量仅仅是记录了偏移的小时分钟而已,除此之外并无其他任何信息。举个栗子:+8:00的意思就是比UTC时间早8小时,没有地理/时区的含义。

  2. 时区是特定与地区而言的,它和地理上的地区绑定在一起。比如整个中国都叫东八区。

中国没有夏令时,所有东八区对应的偏移量永远都是+8;纽约有夏令时,因此它的偏移量可能是-4或-5。

因为有着夏令时的存在,所以时区更好用。夏令时的问题,如果是用偏移量表示就会很麻烦,因为夏令时是可变的;用ZoneId时区去表示就很方便,因为时区内置了对夏令时规则的处理,在任何时候获取当地的时间都是正确的。

ZoneId代表是个时区的ID,如Asia/Shanghai。它规定了一些规则可用于将一个Instant时间戳转换为本地日期/时间LocaleDateTime。

JSR 310时区相关性

java.util.Date类型它具有时区无关性,带来的弊端就是一旦涉及到国际化时间转换等需求时,使用Date来处理很不方便。

JSR 310解决了Date存在的一系列问题:对日期、时间进行了分开表示(LocalDate,LocalTime,LocalDateTime),对本地时间和带时区的时间进行了分开管理。LocalXXX表示本地时间,也就是当前JVM所在的时区的时间,ZonedXXX表示的是一个带有时区的日期时间,它们能非常方便的互相完成转换。

读取字符串为JSR 310类型

一个独立的日期时间类型字符串如2021-06-27T09:20它是没有任何意义的,因为没有时区无法确定它代表哪个瞬间。

遇到一个日期时间格式字符串,要解析它一般有两种情况:

  1. 不带时区/偏移量的字符串:要么不理会说转换不了,要么约定一个时区(一般使用默认时区),使用LocalDateTime解析。

  2. 带时区的字符串用ZonedDateTime解析,带偏移量的字符串用OffsetDateTime解析。注意:有可能字符串参数偏移量为-05:00,转换为ZonedDateTime后偏移量就为-4:00,这是由于夏令时的缘故。

JSR 310格式化

针对JSR 310日期时间的格式化/解析,有一个专门的类java.time.format.DateTimeFormatter用于处理。DateTimeFormatter是一个不可变的类,所以线程是安全的,它还内置了许多格式化模板实例供使用。

想更加深入的了解,请看大佬文章:

全网最全!彻底弄透Java处理GMT/UTC日期时间 - YourBatman - 博客园 (cnblogs.com)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值