java8新特性——新的时间&日期API(java.time:LocalDateTime系列)

java8新特性专栏:https://blog.csdn.net/caoyuan666/category_11801993.html?spm=1001.2014.3001.5482

0.引言

为解决java8以前Date、Calendar等时间日期相关类线程不安全的问题(利用多线程对其进行更改时将报错),java8引入了更加方便完善的java.time。整体结构图如下所示。
在这里插入图片描述

1.LocalDate、LocalTime、LocalDateTime

根据需求,新的java.time提供了LocalDate、LocalTime、LocalDateTime分别表示日期、时间、日期+时间。他们的使用方法类似,这里仅以LocalDateTime举例

1.1 创建方式

创建一般有两种方式,通过now()获取当前时间,通过of()获取指定日期时间

  • now() 从默认时区的系统时钟获取当前的日期时间。
  • now(Clock clock) 从指定的时钟获取当前的日期时间。
  • now(ZoneId zone) 从指定时区的系统时钟获取当前的日期时间。
        LocalDateTime now1 = LocalDateTime.now();
        LocalDateTime now2 = LocalDateTime.now(ZoneId.of("Asia/Tokyo"));
        System.out.println(now1);
        System.out.println(now2);
2022-05-07T16:29:03.640
2022-05-07T17:29:03.640
  • of(int year, int month, int dayOfMonth, int hour, int minute, int second)

of()有个重载的静态方法,详解开发手册

        LocalDateTime dt1 = LocalDateTime.of(2022, 2, 2, 2, 20, 20);
        System.out.println(dt1);
        // 2022-02-02T02:20:20

1.2 常用方法

get方法用于获取响应数值

返回值类型 方法 描述
int get(TemporalField field) 从此日期时间获取指定字段的值为 int
int getDayOfMonth() 获取月份字段。
DayOfWeek getDayOfWeek() 获取星期几字段,这是一个枚举 DayOfWeek
int getDayOfYear() 获得日期字段。
int getHour() 获取时间字段。
long getLong(TemporalField field) 从此日期时间获取指定字段的值为 long
int getMinute() 获取小时字段。
Month getMonth() 使用 Month枚举获取月份字段。
int getMonthValue() 将月份字段从1到12。
int getNano() 获得纳秒第二场。
int getSecond() 获得第二分钟的字段。
int getYear() 获取年份字段。

比较方法

返回值类型 方法 描述
boolean isAfter(ChronoLocalDateTime<?> other) 检查这个日期时间是否在指定的日期之后。
boolean isBefore(ChronoLocalDateTime<?> other) 检查此日期时间是否在指定的日期时间之前。
boolean isEqual(ChronoLocalDateTime<?> other) 检查此日期时间是否等于指定的日期时间。

加减方法:用于根据响应单位处理

  • plusxxx(),如plusSeconds(long seconds)
  • minusxxx(),如minusHours(long hours)

2.格式化解析

DateTimeFormatter :主要用于日期时间 & String之间的解析与格式化

扫描二维码关注公众号,回复: 14761775 查看本文章
        LocalDateTime ldt = LocalDateTime.of(1997, 1, 1, 10, 10);
        String s = ldt.toString();
        System.out.println(s);

        // 1.自定义格式化&解析
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yy:MM:dd===HH:mm:ss");
        String format = ldt.format(dtf);
        String format1 = dtf.format(ldt);
        System.out.println(format);
        System.out.println(format1);

        TemporalAccessor parse = dtf.parse(format);
        System.out.println(parse.getClass());
        LocalDateTime parse1 = LocalDateTime.parse(format1, dtf);
        System.out.println(parse);
        System.out.println(parse1);
        System.out.println("-----------------");

        // 2.ISO_LOCAL_DATE标准格式化
        DateTimeFormatter isoDateTime = DateTimeFormatter.ISO_LOCAL_DATE;
        LocalDate ld = LocalDate.now();
        String format2 = ld.format(isoDateTime);
        System.out.println(format2);
        System.out.println("-----------------");

        // 3.时间格式化
        LocalTime now = LocalTime.now();
        DateTimeFormatter isoLocalTime = DateTimeFormatter.ISO_LOCAL_TIME;
        System.out.println(now.format(isoLocalTime));
1997-01-01T10:10
97:01:01===10:10:00
97:01:01===10:10:00
class java.time.format.Parsed
{},ISO resolved to 2097-01-01T10:10
2097-01-01T10:10
-----------------
2022-05-07
-----------------
17:02:38.774

Process finished with exit code 0

3.时区

  • ZoneId:时区ID
  • ZoneOfferset:时区补偿
        LocalDateTime now1 = LocalDateTime.now();
        LocalDateTime now2 = LocalDateTime.now(ZoneId.of("Australia/Sydney"));
        System.out.println(now1);
        System.out.println(now2);

        System.out.println(ZoneOffset.UTC);
        System.out.println(ZoneOffset.ofHours(8));

2022-05-07T19:01:35.412
2022-05-07T21:01:35.414
Z
+08:00

4.时间戳

  • 时间戳:以Unix元年:1970年1月1日 00:00:00 到某个时间的毫秒值
  • UTC时间:子午线所在时区的基准时间,时间戳获取的默认时区
  • 与LocalDateTime转换,注意时区,我国为东8区
        Instant now = Instant.now();
        long epochSecond = now.getEpochSecond();
        Instant instant1 = Instant.ofEpochSecond(epochSecond);
        System.out.println(now);
        System.out.println(epochSecond);
        System.out.println(instant1);
        System.out.println("-------------");

        // LocalDateTime & Instant 转换
        LocalDateTime dateTime = LocalDateTime.ofInstant(now, ZoneId.of("Asia/Shanghai"));
        LocalDateTime dateTime1 = LocalDateTime.ofInstant(now, ZoneId.systemDefault());
        Instant instant = dateTime.toInstant(ZoneOffset.ofHours(8));
        System.out.println(dateTime);
        System.out.println(dateTime1);
        System.out.println(instant);
2022-05-07T10:59:34.371Z
1651921174
2022-05-07T10:59:34Z
-------------
2022-05-07T18:59:34.371
2022-05-07T18:59:34.371
2022-05-07T10:59:34.371Z

Process finished with exit code 0

5.间隔

  • 时间之前:Duration
  • 日期之间:Period

获取两个点之间的间隔,可转换为需要显示的时间单位:

  • getXXX():如getSeconds()
  • toXXX():如toMillis()
        LocalDateTime start = LocalDateTime.now();
        Thread.sleep(1000);
        LocalDateTime end = LocalDateTime.now();

        System.out.println(Duration.between(start, end).getSeconds());
        System.out.println(Duration.between(start, end).toMillis());
1
1002

6.时间调节器

使用TemporalAdjust调整日期,找到下一个所需日期

  • TemporalAdjuster:函数式接口,如下所示,可以自己实现
  • TemporalAdjusters:实现TemporalAdjuster接口的工具类,提供了常用方法
@FunctionalInterface
public interface TemporalAdjuster {
    
    
    Temporal adjustInto(Temporal temporal);

}

示例操作:

        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
        System.out.println(now.getDayOfWeek());
        System.out.println(now.withDayOfMonth(1));
        System.out.println(now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)));
        System.out.println(now.with(TemporalAdjusters.firstDayOfNextMonth()));

        // 找下一个工作日
        LocalDateTime nextDate = now.with((obj) -> {
            LocalDateTime date = (LocalDateTime) obj;
            DayOfWeek dayOfWeek = date.getDayOfWeek();

            if (dayOfWeek.equals(DayOfWeek.FRIDAY)) {
                return date.plusDays(3);
            } else if (dayOfWeek.equals(DayOfWeek.SATURDAY)) {
                return date.plusDays(2);
            } else {
                return date.plusDays(1);
            }
        });
        System.out.println(nextDate);
2022-05-07T19:31:33.665
SATURDAY
2022-05-01T19:31:33.665
2022-05-08T19:31:33.665
2022-06-01T19:31:33.665
2022-05-09T19:31:33.665

猜你喜欢

转载自blog.csdn.net/caoyuan666/article/details/124637886