前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java新的时间API究竟怎么用

Java新的时间API究竟怎么用

作者头像
KINGYT
发布2019-09-26 15:21:18
1.1K0
发布2019-09-26 15:21:18
举报

Java新时间API中有三个特别重要的类,分别是Instant、LocalDateTime、ZonedDateTime,它们分别对应到上一篇文章中讲到的时间概念为:机器时间、无时区的本地时间、有时区的本地时间。

机器时间其实可以理解为UTC时间的另一种表现形式,其可以唯一确定时间线上的某一时刻。

无时区的本地时间因为没有时区信息,所以其无法唯一确定时间线上的某一时刻。

有时区的本地时间其实是在UTC时间的基础上加一些时间偏移,所以也是可以唯一确定时间线上的某一时刻。

Java的新时间API其实都是围绕这三个类来实现的,所以,彻底理解这三个类的目的及使用场景对于灵活使用Java新时间API来说非常重要。

下面我们用示例来讲解下Java的新时间API究竟怎么用。

1. 获取当前时间的年月日等信息。

代码语言:javascript
复制
static void t1() {
  LocalDateTime ldt = LocalDateTime.now();
  System.out.println(ldt.getYear());

  ZonedDateTime zdt = ZonedDateTime.now();
  System.out.println(zdt.getYear());

  // 对于获取当前时刻的human time信息(年月日时分秒)来说
  // 用LocalDateTime或者ZonedDateTime都是一样的
  // 他们的底层都是先获取machine time,然后再按照所在时区
  // 将machine time转成human time
  // ZonedDateTime比LocalDateTime的唯一区别就是携带了时区信息
  // 但如果只是为了获取年月日等信息,时区是没用的
}

2. 获取某一机器时间的年月日等信息。

代码语言:javascript
复制
static void t2() {
  long millis = System.currentTimeMillis();
  Instant instant = Instant.ofEpochMilli(millis);

  LocalDateTime ldt = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
  System.out.println(ldt.getYear());

  ZonedDateTime zdt = ZonedDateTime.ofInstant(instant, ZoneId.systemDefault());
  System.out.println(zdt.getYear());

  // 机器时间要先转成Instant实例后,才能被Java新时间API使用
}

3. 人类时间转机器时间。

代码语言:javascript
复制
static void t3() {
  // 由于LocalDateTime没有时区信息,所以它无法直接转成机器时间
  // 只能通过主动提供时区信息的方式才可以
  LocalDateTime ldt = LocalDateTime.now();
  long millis = ldt.toInstant(ZoneOffset.of("+08:00")).toEpochMilli();
  System.out.println(millis);

  // 由于ZonedDateTime内已经有时区信息了,所以它可以直接转成机器时间
  ZonedDateTime zdt = ZonedDateTime.now();
  millis = zdt.toInstant().toEpochMilli();
  System.out.println(millis);

  // 还需要注意的是,代表人类时间的类并不是直接转成的机器时间,而是通过Instant类间接完成
}

4. 解析时间字符串。

代码语言:javascript
复制
static void t4() {
  // 被解析的字符串不能有时区信息
  LocalDateTime ldt = LocalDateTime.parse("2019-09-25T16:32:42");
  System.out.println(ldt);

  // 被解析的字符串必须有时区信息
  ZonedDateTime zdt = ZonedDateTime.parse("2019-09-25T16:32:42+08:00");
  System.out.println(zdt);
}

5. 时间的运算。

代码语言:javascript
复制
static void t5() {
  // LocalDateTime的时间加减就是纯粹的加减
  LocalDateTime ldt = LocalDateTime.parse("2019-03-10T01:59:59");
  System.out.println(ldt.plusHours(1).getHour()); // 输出:2

  // ZonedDateTime的时间加减还会考虑时区信息
  // 比如2019-03-10T02:00:00开始,美国开始施行 daylight saving time (夏令时)
  // 他们的本地时间会向后拨一个小时,即:凌晨2点会变成凌晨3点
  // 有关 daylight saving time 更多信息,请看以下文章:
  // https://en.wikipedia.org/wiki/Daylight_saving_time
  ZonedDateTime zdt = ldt.atZone(ZoneId.of("America/New_York"));
  System.out.println(zdt.plusHours(1).getHour()); // 输出:3

  // 所以说,如果涉及到时间的运算,要用ZonedDateTime
}

6. 获取某一机器时间所属那天的零点的机器时间。

代码语言:javascript
复制
static long startOfDay(long millis) {
  return LocalDate.ofInstant(Instant.ofEpochMilli(millis), ZoneId.systemDefault())
      .atStartOfDay(ZoneId.systemDefault())
      .toInstant()
      .toEpochMilli();
}

7. 获取某一机器时间所属那个星期的星期一零点的机器时间。

代码语言:javascript
复制
static long startOfWeek(long millis) {
  return LocalDate.ofInstant(Instant.ofEpochMilli(millis), ZoneId.systemDefault())
      .atStartOfDay(ZoneId.systemDefault())
      .with(DayOfWeek.MONDAY)
      .toInstant()
      .toEpochMilli();
}

8. 获取某一机器时间所属那个月的一号零点的机器时间。

代码语言:javascript
复制
static long startOfMonth(long millis) {
  return LocalDate.ofInstant(Instant.ofEpochMilli(millis), ZoneId.systemDefault())
      .atStartOfDay(ZoneId.systemDefault())
      .withDayOfMonth(1)
      .toInstant()
      .toEpochMilli();
}

好,例子就这么多吧,我觉得到这里大家都差不多懂了。

有关Java新时间API更多介绍,请参考Java官方教程:

https://docs.oracle.com/javase/tutorial/datetime/TOC.html

希望对大家有所帮助。

完。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Linux内核及JVM底层相关技术研究 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档