【Java】Java8中时间类的使用

1. GMT、UTC

1.1 GMT:格林威治(也称:格林尼治)时间,也叫世界时(Universal Time),也叫世界标准时间。是指位于英国伦敦郊区的【皇家格林尼治天文台】的标准时间,是本初子午线上的地方时,是0时区的区时。
1.2 UTC:Coordinated Universal Time,直译为:世界协调时间。它是以原子时作为计量单位的时间,计算结果极其严谨和精密。它比GMT时间更来得精准,误差值必须保持在0.9秒以内,倘若大于0.9秒就会通过闰秒来“解决”。
1.3 二者区别:

  • GMT是老的时间计量标准,根据地球的自转和公转来计算时间的,自转一圈是一天,公转一圈是一年。UTC是根据原子钟进行计时的,比GMT更加精确。
  • 二者在数值上几乎相等(不精确到秒的情况下)。
  • GMT是带有时区信息的(0时区),而UTC不带有时区信息。

2. Java8时间类概述

由于Java Date/Calendar API被广大开发者诟病,所以2014年随着Java 8的发布引入了全新的JSR 310日期时间。JSR 310日期时间所有API均在java.time包中。

3. ZoneId类与ZoneOffset类

3.1 ZoneId类用于表示时区,ZoneOffset类用于表示偏移量。时区是特定于地区而言的,它和地理上的地区(包括规则)强绑定在一起。比如整个中国都叫东八区,纽约在西五区等等。而偏移量仅仅记录了偏移的小时分钟而已,除此之外无任何其它信息。
3.2 生成ZoneId的三种方式:

  • 第一种为通过时区Id获取, 时区Id是字符串,通过ZoneId.getAvailableZoneIds()可查看所有可用的时区id。(推荐)
ZoneId zoneId1 = ZoneId.of("Australia/Sydney");
System.out.println(ZoneId.getAvailableZoneIds());
// sout [Asia/Aden, America/Cuiaba, Etc/GMT+9, Etc/GMT+8, Africa/Nairobi, ...]
  • 第二种为通过偏移量获取,偏移量的合法前缀有UTC、GMT和UT,具体值的写法为[+/-mm:ss]或[+/-mm]。
ZoneId zoneId2 = ZoneId.ofOffset("UTC", ZoneOffset.of("+08"));
ZoneId zoneId3 = ZoneId.ofOffset("GMT", ZoneOffset.of("-08:30"));
ZoneId zoneId4 = ZoneId.ofOffset("UT", ZoneOffset.of("+08:00"));
  • 第三种为在ZoneDateTime中获取时区,ZoneDateTime类是带有时区信息的日期时间类。
ZoneId zoneId5 = ZoneId.from(ZonedDateTime.now());

4. Instant类

4.1 Instant类表示的是一个时间戳,UTC格式下,距离1970年1月1日0时0分0秒的秒数,可精确到纳秒。Instant类不带有时区信息,是推荐的时间表示。
4.2 Instant类的两种创建方式:

  • 第一种是通过Instant.now(),获取的是当前时间戳。
  • 第二种是通过Instant.ofEpochSecond(),获取的是距起始秒特定秒数的时间。

4.3 Instant类的常用方法

Instant instant1 = Instant.now();
System.out.println("instant1 : "+instant1);
System.out.println("纪元秒 : "+instant1.getEpochSecond());
System.out.println("毫  秒 : "+instant1.toEpochMilli());
System.out.println("纳  秒 : "+instant1.getNano()); // 获取纳秒,不超过1000000000
ZonedDateTime zonedDateTime = instant1.atZone(ZoneId.of("Australia/Sydney")); // 转换为带时区信息的日期时间
System.out.println("悉尼时区时间: "+zonedDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
Instant instant2 = Instant.ofEpochSecond(100);
System.out.println("instant2 : "+instant2);
// sout
// instant1 : 2023-09-04T02:08:54.132Z
// 纪元秒 : 1693793334
// 毫  秒 : 1693793334132
// 纳  秒 : 132000000
// 悉尼时区时间: 2023-09-04 12:08:54
// instant2 : 1970-01-01T00:01:40Z

5. LocalXxx类

5.1 LocalDate表示本地时区的日期,LocalTime表示本地时区的时间,LocalDateTime表示本地时区的日期时间。LocalDate与LocalTime合并可构造出LocalDateTime。
5.2 LocalDateTime与ZoneDateTime的区别:虽然LocalDateTime也能修改时区信息,但是它更多的使用场景是不需要考虑时区时的日期时间表示。也就是说,没有跨时区表示日期时间的需要时使用LocalDateTime。当需要考虑时区时,最好使用ZoneDateTime。
5.3 Instant、LocalDateTime、ZoneDateTime的相互转换:

// Instant、LocalDateTime、ZoneDateTime的相互转换
Instant instant = Instant.now();
// Instant -> LocalDateTime
LocalDateTime localDateTimeIns = LocalDateTime.ofInstant(instant, ZoneId.of("Australia/Sydney"));
// Instant -> ZoneDateTime
ZonedDateTime zonedDateTimeIns = ZonedDateTime.ofInstant(instant, ZoneId.of("Australia/Sydney"));
// LocalDateTime -> ZoneDateTime
ZonedDateTime zonedDateTimeLDT = ZonedDateTime.of(localDateTimeIns, ZoneId.of("Australia/Sydney"));

6. Duration类和Period类

6.1 二者均用于表示时间区间,Duration类用于Time级别的,而Period类用于Date级别的。

7. 总结

  • GMT是旧的时间标准,UTC是新的时间标准。
  • Instant表示时间戳,不带有时区信息。
  • ZoneId表示时区,ZoneOffset表示偏移量。
  • ZoneDateTime表示带时区的日期时间。
  • LocalDate表示本地日期,LocalTime表示本地时间,LocalDateTime表示本地日期时间。
  • Duration为时间区间,Period为日期区间。

8. 参考

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值