这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战」
❤️作者简介:Java领域优质创作者🏆,CSDN博客专家认证🏆,华为云享专家认证🏆
❤️技术活,该赏
❤️点赞 👍 收藏 ⭐再看,养成习惯
大家好,我是小虚竹。之前有粉丝私聊我,问能不能把JAVA8 新的日期时间API(JSR-310)知识点梳理出来。答案是肯定的,谁让我宠粉呢。由于内容偏多,会拆成多篇来写。
闲话就聊到这,请看下面的正文。
常用的日期时间API简介
介绍下java8API比较常用的日期时间API,按java.time 包的类顺序:
- Clock:时钟
- Instant:瞬间时间。
- LocalDate:本地日期。只有表示年月日
- LocalDateTime:本地日期时间,LocalDate+LocalTime
- LocalTime:本地时间,只有表示时分秒
- OffsetDateTime:有时间偏移量的日期时间(不包含基于ZoneRegion的时间偏移量)
- OffsetTime:有时间偏移量的时间
- ZonedDateTime:有时间偏移量的日期时间(包含基于ZoneRegion的时间偏移量)
博主把这些类都点开看了,都是属于不可变类。而且官方也说了,java.time包 下的类都是线程安全的。
Clock
Clock类说明
1 | java复制代码public abstract class Clock { |
Clock 是抽象类,内部提供了四个内部类,这是它的内部实现类
- FixedClock :始终返回相同瞬间的时钟,通常使用于测试。
- OffsetClock :偏移时钟,时间偏移量的单位是Duration。
- SystemClock :系统默认本地时钟。
- TickClock :偏移时钟,时间偏移量的单位是纳秒。
Clock 提供了下面这几个常用的方法(这几个方法在实现类里都有对应的实现):
1 | java复制代码// 获取时钟的当前Instant对象。 |
FixedClock
Clock.fixed
1 | java复制代码public static Clock fixed(Instant fixedInstant, ZoneId zone) |
需要传递instant
和zone
,并将返回具有固定瞬间的时钟。
1 | java复制代码 Instant instant = Instant.now(); |
由运行结果可知,返回的结果是有带对应时区的。
验证获取的时钟会不会改变:
1 | java复制代码 Clock clock = Clock.systemDefaultZone(); |
Clock.fixed 创建一个固定的时钟,clock 对象将始终提供与指定相同的时刻。。如图所示,强制睡眠1秒,但是时刻没变。
Clock.fixed 跟 Offset 方法更配
由上面可知Clock.fixed 得到一个固定的时钟,那要添加时间或者减去时间就要用到Offset 方法
示例代码如下
1 | java复制代码 Clock clock = Clock.systemDefaultZone(); |
OffsetClock
OffsetClock 是偏移时钟,时间偏移量的单位是Duration。
1 | java复制代码//Clock |
由源码可知,使用Clock.offset方法 返回的是OffsetClock实例对象
1 | java复制代码 Clock clock = Clock.systemDefaultZone(); |
SystemClock
SystemClock 是系统默认的本地时钟。
1 | java复制代码 Clock clock = Clock.systemDefaultZone(); |
居然完全一样。这就要看下源码了
Clock.systemDefaultZone()
用的是系统默认的时区ZoneId.systemDefault()
1 | csharp复制代码 public static Clock systemDefaultZone() { |
最终调用的也是System.currentTimeMillis()
Clock.systemUTC()
用的是UTC时区ZoneOffset.UTC
1 | java复制代码 public static Clock systemUTC() { |
最终调用的也是System.currentTimeMillis()
结论
Clock.systemDefaultZone() 和Clock.systemUTC()获取的millis()时间戳是一样的,就是对应时区的差别。
TickClock
TickClock 是偏移时钟,时间偏移量的最小单位是纳秒。
如图所示,Clock主要提供下面三个方法
1 | java复制代码//构造的时钟的计时单位是自定义的偏移量单位 |
实战:
1 | java复制代码 Clock tickClock = Clock.tick(Clock.systemDefaultZone(),Duration.ofHours(1L)); |
偏移量的单位支持:天,时,分,秒,豪秒,纳秒
Instant
Instant类说明
1 | java复制代码public final class Instant |
Instant表示瞬间时间。也是不可变类且是线程安全的。其实Java.time 这个包是线程安全的。
Instant是java 8新增的特性,里面有两个核心的字段
1 | java复制代码 ... |
一个是单位为秒的时间戳,另一个是单位为纳秒的时间戳。
是不是跟**System.currentTimeMillis()**返回的long时间戳很像,System.currentTimeMillis()返回的是毫秒级,Instant多了更精确的纳秒级时间戳。
Instant常用的用法
1 | java复制代码 Instant now = Instant.now(); |
Instant是没有时区的,但是Instant加上时区后,可以转化为ZonedDateTime
1 | java复制代码 Instant ins = Instant.now(); |
long型时间戳转Instant
要注意long型时间戳的时间单位选择Instant对应的方法转化
1 | java复制代码//1626796436 为秒级时间戳 |
Instant的坑
Instant.now()获取的时间与北京时间相差8个时区,这是一个细节,要避坑。
看源码,用的是UTC时间。
1 | java复制代码public static Instant now() { |
解决方案:
1 | java复制代码Instant now = Instant.now().plusMillis(TimeUnit.HOURS.toMillis(8)); |
LocalDate
LocalDate类说明
LocalDate表示本地日期。只有表示年月日。相当于:yyyy-MM-dd。
LocalDate常用的用法
获取当前日期
1 | java复制代码 LocalDate localDate1 = LocalDate.now(); |
获取localDate对象
1 | java复制代码 LocalDate localDate1 = LocalDate.of(2021, 8, 14); |
获取指定日期的年月日
1 | scss复制代码 LocalDate localDate1 = LocalDate.of(2021, 8, 14); |
修改年月日
1 | java复制代码 LocalDate localDate1 = LocalDate.of(2021, 8, 14); |
比较日期
1 | css复制代码 LocalDate localDate1 = LocalDate.of(2021, 8, 14); |
LocalDate 和String相互转化、Date和LocalDate相互转化
LocalDate 和String相互转化
1 | java复制代码 LocalDate localDate1 = LocalDate.of(2021, 8, 14); |
Date和LocalDate相互转化
1 | java复制代码 // Date 转 LocalDate |
LocalDateTime
LocalDateTime类说明
表示当前日期时间,相当于:yyyy-MM-ddTHH:mm:ss
LocalDateTime常用的用法
获取当前日期和时间
1 | java复制代码 LocalDate d = LocalDate.now(); // 当前日期 |
由运行结果可行,本地日期时间通过now()获取到的总是以当前默认时区返回的
获取指定日期和时间
1 | java复制代码 LocalDate d2 = LocalDate.of(2021, 07, 14); // 2021-07-14, 注意07=07月 |
日期时间的加减法及修改
1 | java复制代码 LocalDateTime currentTime = LocalDateTime.now(); // 当前日期和时间 |
LocalDateTime和Date相互转化
Date转LocalDateTime
1 | java复制代码 System.out.println("------------------方法一:分步写-----------------------"); |
LocalDateTime转Date
1 | java复制代码 System.out.println("------------------方法一:分步写-----------------------"); |
LocalTime
LocalTime类说明
LocalTime:本地时间,只有表示时分秒
LocalTime常用的用法
获取当前时间
1 | java复制代码 LocalTime localTime1 = LocalTime.now(); |
获取LocalTime对象
1 | java复制代码 LocalTime localTime1 = LocalTime.of(23, 26, 30); |
获取指定日期的时分秒
1 | java复制代码 LocalTime localTime1 = LocalTime.of(23, 26, 30); |
修改时分秒
1 | java复制代码 LocalTime localTime1 = LocalTime.of(23, 26, 30); |
比较时间
1 | java复制代码 LocalTime localTime1 = LocalTime.of(23, 26, 30); |
OffsetDateTime
OffsetDateTime类说明
OffsetDateTime:有时间偏移量的日期时间(不包含基于ZoneRegion的时间偏移量)
1 | java复制代码public final class OffsetDateTime |
上面的MIN 和MAX 是公有静态变量。
OffsetDateTime常用的用法
获取当前日期时间
1 | java复制代码 OffsetDateTime offsetDateTime1 = OffsetDateTime.now(); |
获取OffsetDateTime对象
1 | java复制代码 LocalDateTime localDateTime1 = LocalDateTime.of(2021, 8, 15, 13, 14, 20); |
获取指定日期的年月日时分秒
1 | java复制代码 LocalDateTime localDateTime1 = LocalDateTime.of(2021, 8, 15, 13, 14, 20); |
修改年月日时分秒
1 | java复制代码 LocalDateTime localDateTime1 = LocalDateTime.of(2021, 8, 15, 13, 14, 20); |
比较日期时间
1 | java复制代码 LocalDateTime localDateTime1 = LocalDateTime.of(2021, 8, 15, 13, 14, 20); |
字符串转化为OffsetDateTime对象
1 | java复制代码 String str = "2021-08-15T10:15:30+08:00"; |
OffsetTime
OffsetTime类说明
OffsetTime:有时间偏移量的时间
1 | java复制代码public final class OffsetTime |
上面的MIN 和MAX 是公有静态变量。
OffsetTime常用的用法
获取当前时间
1 | java复制代码 OffsetTime offsetTime1 = OffsetTime.now(); |
获取OffsetTime对象
1 | java复制代码 LocalTime localTime1 = LocalTime.of(13, 14, 20); |
获取指定时间的时分秒
1 | java复制代码 LocalTime localTime1 = LocalTime.of( 13, 14, 20); |
修改时分秒
1 | java复制代码 LocalTime localTime1 = LocalTime.of( 13, 14, 20); |
比较时间
1 | java复制代码 LocalTime localTime1 = LocalTime.of( 13, 14, 20); |
ZonedDateTime
ZonedDateTime类说明
表示一个带时区的日期和时间,ZonedDateTime可以理解为LocalDateTime+ZoneId
从源码可以看出来,ZonedDateTime类中定义了LocalDateTime和ZoneId两个变量。
且ZonedDateTime类也是不可变类且是线程安全的。
1 | java复制代码public final class ZonedDateTime |
ZonedDateTime常用的用法
获取当前日期时间
1 | java复制代码 // 默认时区获取当前时间 |
1 | java复制代码 ZonedDateTime zonedDateTime1 = ZonedDateTime.now(); |
获取ZonedDateTime对象
1 | java复制代码 LocalDateTime localDateTime1 = LocalDateTime.of(2021, 8, 15, 13, 14, 20); |
获取指定日期的年月日时分秒
1 | java复制代码 LocalDateTime localDateTime1 = LocalDateTime.of(2021, 8, 15, 13, 14, 20); |
修改年月日时分秒
1 | java复制代码 LocalDateTime localDateTime1 = LocalDateTime.of(2021, 8, 15, 13, 14, 20); |
比较日期时间
1 | java复制代码 LocalDateTime localDateTime1 = LocalDateTime.of(2021, 8, 15, 13, 14, 20); |
LocalDateTime+ZoneId变ZonedDateTime
1 | java复制代码 LocalDateTime localDateTime = LocalDateTime.now(); |
上面的例子说明了,LocalDateTime是可以转成ZonedDateTime的。
推荐相关文章
hutool日期时间系列文章
2DateUtil(时间工具类)-常用的时间类型Date,DateTime,Calendar和TemporalAccessor(LocalDateTime)转换
9LocalDateTimeUtil(JDK8+中的{@link LocalDateTime} 工具类封装)
10TemporalAccessorUtil{@link TemporalAccessor} 工具类封装
其他
java的SimpleDateFormat线程不安全出问题了,虚竹教你多种解决方案
本文转载自: 掘金