JDK8日期类入门

关于jdk8的时间类的用法,网上有很多教程教你如何用,比如:

System.out.println(LocalDateTime.now());

可以获取当前的时间,

2020-12-06T18:02:39.215

但我想从另一个角度来思考这些时间类。

首先,我想明确一个观点:

JDK8中的日期类是什么?

我认为其本质就是对这个世界上时间的一种抽象封装

为什么这么说呢,耐心点看下去。

第一个问题,地球上的时间从哪来?

害。这不是屁话么,小学生都知道地球上的时间是通过地球绕太阳公转来的,以本初子午线为0时区,将地球划分为12个时区。比如北京就在东8区,也就是`UTC/GMT+08:00`

所以第一个概念就有了,那就是时区,JDK8里称为Zone,对应的用来求指定时区的类是ZonedDateTime,以下为代码示例:

import java.time.ZoneId;
import java.time.ZonedDateTime;

/**
 * @author Alin
 * @desc //TODO
 * @date 2020/12/6
 */
public class TestLocalDateTime {
    public static void main(String[] args) {
        final ZonedDateTime now = ZonedDateTime.now();
        System.out.println(now);
        final ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
        System.out.println(zonedDateTime.toString());
    }
}

从结果可以看出,不同时区对应的时间不同,东京比上海快了一个小时:

2020-12-06T19:02:59.765+08:00[Asia/Shanghai]
2020-12-06T20:02:59.766+09:00[Asia/Tokyo]

当然,这个世界的时间设计不可能只有时区,以东8区举例,

此时区内该如何计算时间呢?

JDK8提供了几种方式,比如:

  • LocalDateTime
  • LocalDate
  • Instant

代码示例:

public class TestLocalDateTime {
    @Test
    void test2(){
        System.out.println(LocalDateTime.now());
        System.out.println(LocalDate.now());
        final Instant now = Instant.now();
        System.out.println(now);
        System.out.println(now.toEpochMilli());
        System.out.println(System.currentTimeMillis());
        System.out.println(LocalTime.now());
    }
}
2020-12-06T19:36:35.323
2020-12-06
2020-12-06T11:36:35.323Z
1607254595323
1607254595328
19:36:35.328

从结果看,LocalDateTime可以获得当前时区的年月日时分秒,LocalDate则是年月日,Instant则可以获取自1970-01-01T00:00:00Z到现在的毫秒数,LocalTime就是时分秒了,注意,Instant获取的结果是不考虑时区的,所以差了8个小时,其他是指系统默认时区。

从命名上看的也很明显,Local指本地(本时区、系统默认时区),Date指日期,Time指时间。

按照逻辑推断,其中必然有转换关系,知道了年月日时分秒,那肯定能单独转换为年月日或者时分秒吧,的确JDK8也做了封装:

public class TestLocalDateTime {
    @Test
    void test3(){
        final LocalDateTime localDateTime = LocalDateTime.now();
        final LocalDate localDate = LocalDate.now();
        final LocalTime localTime = LocalTime.now();
        final Instant instant = Instant.now();

        final LocalDate toLocalDate = localDateTime.toLocalDate();
        final LocalTime toLocalTime = localDateTime.toLocalTime();
        final long milli = localDateTime.toInstant(ZoneOffset.UTC).toEpochMilli();
    }
}

我们这个世界还需要哪些时间单位呢?

比如,年、月、周、日,对应的类如YearMonthDayOfWeekMonthDay,被设计用来增强代码的可读性和可靠性。

时间也是有范围的,比如几个小时/持续了几秒/天/月等:

Duration表示以秒和纳秒为基准的时长。例如,“10.3秒”。

Period表示以年、月、日衡量的时长。例如,“1年5个月零13天”。

另外,该如何格式化日期呢,这个JDk8也有封装,最常用的DateTimeFormatter就可以做到:

public class TestLocalDateTime {
    @Test
    void test4(){
        final LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
    }
}

还有一个很方便的工具类TemporalAdjusters,代码如下:

public class TestLocalDateTime {
    @Test
    void test5(){
        final LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime);
        final LocalDateTime with = localDateTime.with(TemporalAdjusters.lastDayOfMonth());
        System.out.println(with);
    }
}

可以方便的计算诸如本月的最后一天等等问题,具体可自查api:

2020-12-06T20:07:26.181
2020-12-31T20:07:26.181
posted @ 2020-12-06 20:15  夜旦  阅读(317)  评论(0编辑  收藏  举报