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

本文介绍了Java 8中LocalDateTime类的创建、常用方法、格式化解析、时区处理、时间戳转换、间隔计算以及时间调节器的使用,帮助开发者理解和优化日期时间操作的线程安全性和效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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方法用于获取响应数值

返回值类型方法描述
intget(TemporalField field)从此日期时间获取指定字段的值为 int
intgetDayOfMonth()获取月份字段。
DayOfWeekgetDayOfWeek()获取星期几字段,这是一个枚举 DayOfWeek
intgetDayOfYear()获得日期字段。
intgetHour()获取时间字段。
longgetLong(TemporalField field)从此日期时间获取指定字段的值为 long
intgetMinute()获取小时字段。
MonthgetMonth()使用 Month枚举获取月份字段。
intgetMonthValue()将月份字段从1到12。
intgetNano()获得纳秒第二场。
intgetSecond()获得第二分钟的字段。
intgetYear()获取年份字段。

比较方法

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

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

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

2.格式化解析

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

        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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

努力改掉拖延症的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值