LocalDateTime用法

首先介绍一下这个是Java8出的新的日期时间API
常用、重要对象介绍
ZoneId: 时区ID,用来确定Instant和LocalDateTime互相转换的规则
Instant: 用来表示时间线上的一个点(瞬时)
LocalDate: 表示没有时区的日期, LocalDate是不可变并且线程安全的
LocalTime: 表示没有时区的时间, LocalTime是不可变并且线程安全的
LocalDateTime: 表示没有时区的日期时间, LocalDateTime是不可变并且线程安全的
Clock: 用于访问当前时刻、日期、时间,用到时区
Duration: 用秒和纳秒表示时间的数量(长短),用于计算两个日期的“时间”间隔
Period: 用于计算两个“日期”间隔

本文将以实例讲解日常开发中常用到的时间日期操作,如:

获取当前日期、时间
指定时间日期创建对应的对象
计算两个时间点的间隔
判断两个时间的前后
时间日期的格式化
获取时间戳
时间、日期相加减
获取给定时间点的年份、月份、周、星期等
获取当前时间

LocalDate localDate = LocalDate.now();
        LocalTime localTime = LocalTime.now();
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println("当前日期:" + localDate);
        System.out.println("当前时间:" + localTime);
        System.out.println("当前日期时间:" + localDateTime);

运行结果:

RestController 判断非空_java


根据指定日期/时间创建对象

LocalDate localDate = LocalDate.of(2012, 12, 22);
        LocalTime localTime = LocalTime.of(5, 20, 13);
        LocalDateTime localDateTime = LocalDateTime.of(2012, 12, 22, 5, 20, 13);
        System.out.println("日期:" + localDate);
        System.out.println("时间:" + localTime);
        System.out.println("日期时间:" + localDateTime);

运行结果:

RestController 判断非空_RestController 判断非空_02


日期时间的加减

LocalDate,只有精度大于或等于日的加减,如年、月、日;

LocalTime,只有精度小于或等于时的加减,如时、分、秒、纳秒;

LocalDateTime,可以进行任意精度的时间相加减;

LocalDateTime localDateTime = LocalDateTime.now();
        //以下方法的参数都是long类型,返回值都是LocalDateTime
        LocalDateTime plusYears = localDateTime.plusYears(2L);
        LocalDateTime plusMonths = localDateTime.plusMonths(3L);
        LocalDateTime plusDays = localDateTime.plusDays(7L);
        LocalDateTime plusHours = localDateTime.plusHours(2L);
        LocalDateTime plusMinutes = localDateTime.plusMinutes(10L);
        LocalDateTime plusSeconds = localDateTime.plusSeconds(10L);

        System.out.println(
                "当前时间是 : " + localDateTime + "\n"
                + "当前时间加2年后为 : " + plusYears + "\n"
                + "当前时间加3个月后为 : " + plusMonths + "\n"
                + "当前时间加7日后为 : " + plusDays + "\n"
                + "当前时间加2小时后为 : " + plusHours + "\n"
                + "当前时间加10分钟后为 : " + plusMinutes + "\n"
                + "当前时间加10秒后为 : " + plusSeconds + "\n"
        );

        //也可以以另一种方式来相加减日期,即plus(long amountToAdd, TemporalUnit unit)
        //参数1 : 相加的数量
        //参数2 : 相加的单位
        LocalDateTime nextMonth = localDateTime.plus(1, ChronoUnit.MONTHS);
        LocalDateTime nextYear = localDateTime.plus(1, ChronoUnit.YEARS);
        LocalDateTime nextWeek = localDateTime.plus(1, ChronoUnit.WEEKS);

        System.out.println(
                "现在 : " + localDateTime + "\n"
                + "下一年 : " + nextYear + "\n"
                + "下个月 : " + nextMonth + "\n"
                + "下周 :" + nextWeek + "\n"
        );

运行结果:

RestController 判断非空_时间日期_03


将年、月、日等修改为指定的值,并返回新的日期(时间)对象

注: 其效果与时间日期相加减差不多,如今天是2022-09-23,要想变为2022-09-30有两种方式

a. localDate.plusDays(30L) -> 相加指定的天数

b. localDate.withDayOfYear(30) -> 直接指定到哪一天

LocalDate localDate = LocalDate.now();
        //当前时间基础上,指定本年当中的第几天,取值范围为1-365,366
        LocalDate withDayOfYear = localDate.withDayOfYear(300);
        //当前时间基础上,指定本月当中的第几天,取值范围为1-29,30,31
        LocalDate withDayOfMonth = localDate.withDayOfMonth(5);
        //当前时间基础上,直接指定年份
        LocalDate withYear = localDate.withYear(2018);
        //当前时间基础上,直接指定月份
        LocalDate withMonth = localDate.withMonth(5);
        System.out.println(
                "当前时间是 : " + localDate + "\n"
                + "指定本年当中的第300天 : " + withDayOfYear + "\n"
                + "指定本月当中的第5天 : " + withDayOfMonth + "\n"
                + "直接指定年份为2018 : " + withYear + "\n"
                + "直接指定月份为5月 : " + withMonth + "\n"
        );

运行结果:

RestController 判断非空_日期时间_04


获取日期的年月日周时分秒

LocalDateTime localDateTime = LocalDateTime.now();
        int dayOfYear = localDateTime.getDayOfYear();
        int dayOfMonth = localDateTime.getDayOfMonth();
        DayOfWeek dayOfWeek = localDateTime.getDayOfWeek();
        System.out.println(
                "今天是:" + localDateTime + "\n"
                + "本年当中第" + dayOfYear + "天" + "\n"
                + "本月当中第" + dayOfMonth + "天" + "\n"
                + "本周中星期" + dayOfWeek.getValue() + "-即:" + dayOfWeek + "\n");

        //获取当天时间的年月日时分秒
        int year = localDateTime.getYear();
        Month month = localDateTime.getMonth();
        int day = localDateTime.getDayOfMonth();
        int hour = localDateTime.getHour();
        int minute = localDateTime.getMinute();
        int second = localDateTime.getSecond();
        System.out.println("今天是" + localDateTime + "\n"
                + "年 : " + year + "\n"
                + "月 : " + month.getValue() + "-即 "+ month + "\n"
                + "日 : " + day + "\n"
                + "时 : " + hour + "\n"
                + "分 : " + minute + "\n"
                + "秒 : " + second + "\n"
        );

运行结果:

RestController 判断非空_RestController 判断非空_05


时间日期前后的比较与判断

//判断两个时间点的前后
        LocalDate localDate1 = LocalDate.of(2022, 9, 9);
        LocalDate localDate2 = LocalDate.of(2021, 9, 9);
        boolean date1IsBeforeDate2 = localDate1.isBefore(localDate2);
        System.out.println("date1IsBeforeDate2 : " + date1IsBeforeDate2);

运行结果:

RestController 判断非空_日期时间_06


时间戳

事实上Instant就是java8以前的Date,

可以使用以下两个类中的方法在这两个类型之间进行转换,

比如Date.from(Instant)就是用来把Instant转换成java.util.date的,

而new Date().toInstant()就是将Date转换成Instant的

Instant instant = Instant.now();
        //2022-09-23T03:18:29.416694900Z
        System.out.println(instant);
        Date date = Date.from(instant);
        Instant instant2 = date.toInstant();
        //Fri Sep 23 11:18:29 CST 2022
        System.out.println(date);
        //2022-09-23T03:18:29.416Z
        System.out.println(instant2);

计算时间、日期间隔
Duration:用于计算两个“时间”间隔
Period:用于计算两个“日期”间隔

//计算两个日期的日期间隔-年月日
        LocalDate date1 = LocalDate.of(2022, 2, 13);
        LocalDate date2 = LocalDate.of(2021, 3, 12);
        //内部是用date2-date1,所以得到的结果是负数
        Period period = Period.between(date1, date2);
        System.out.println("相差年数 : " + period.getYears());
        System.out.println("相差月数 : " + period.getMonths());
        System.out.println("相差日数 : " + period.getDays());
        //还可以这样获取相差的年月日
        System.out.println("-------------------------------");
        long years = period.get(ChronoUnit.YEARS);
        long months = period.get(ChronoUnit.MONTHS);
        long days = period.get(ChronoUnit.DAYS);
        System.out.println("相差的年月日分别为 : " + years + "," + months + "," + days);
        //注意,当获取两个日期的间隔时,并不是单纯的年月日对应的数字相加减,而是会先算出具体差多少天,再折算成相差几年几月几日的

        //计算两个时间的间隔
        System.out.println("-------------------------------");
        LocalDateTime date3 = LocalDateTime.now();
        LocalDateTime date4 = LocalDateTime.of(2021, 1, 3, 01, 04, 20);
        Duration duration = Duration.between(date3, date4);
        System.out.println(
                date3 + " 与 " + date4 + " 间隔  " + "\n"
                + " 天 :" + duration.toDays() + "\n"
                + " 时 :" + duration.toHours() + "\n"
                + " 分 :" + duration.toMinutes() + "\n"
                + " 毫秒 :" + duration.toMillis() + "\n"
                + " 纳秒 :" + duration.toNanos() + "\n"
        );
        //注意,并没有获得秒差的,但既然可以获得毫秒,秒就可以自行获取了

运行结果:

RestController 判断非空_RestController 判断非空_07


时间日期的格式化(格式化后返回的类型是String)

1.使用统一格式

//使用统一日期格式
        DateTimeFormatter formatter1 = DateTimeFormatter.ISO_DATE_TIME;
        LocalDateTime date1 = LocalDateTime.now();
        //反过来调用也可以 : date1.format(formatter1);
        String date1Str = formatter1.format(date1);
        System.out.println(date1Str);

运行结果:
2022-09-23T11:27:05.4389181

2.自定义格式

LocalDateTime date1 = LocalDateTime.now();
        DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
        String date2Str = formatter2.format(date1);
        System.out.println(date2Str);

运行结果:
2022年09月23日 11:28:48

注:自定义转化的格式一定要与日期类型对应

LocalDate只能设置仅含年月日的格式
LocalTime只能设置仅含时分秒的格式
LocalDateTime可以设置含年月日时分秒的格式

DateTimeFormatter formatter3 = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        System.out.println(formatter3.format(LocalDate.now()));

        System.out.println("-------------------------------");

        DateTimeFormatter formatter4 = DateTimeFormatter.ofPattern("HH:mm:ss");
        System.out.println(formatter4.format(LocalTime.now()));

运行结果:

RestController 判断非空_RestController 判断非空_08


将时间字符串形式转化为日期对象

String datetime =  "2022-09-18 15:30:30";
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime ldt = LocalDateTime.parse(datetime, dtf);
        System.out.println(ldt);

运行结果:
2022-09-18T15:30:30

注:格式的写法必须与字符串的形式一样
2018-01-13 21:27:30 对应 yyyy-MM-dd HH:mm:ss
20180113213328 对应 yyyyMMddHHmmss
否则会报运行时异常!

但要记住:得到的最终结果都是类似2018-01-13T21:27:30的格式

因为在输出LocalDateTime对象时,会调用其重写的toString方法。

将时间日期对象转为格式化后的时间日期对象

//新的格式化API中,格式化后的结果都默认是String,有时我们也需要返回经过格式化的同类型对象
        LocalDateTime ldt1 = LocalDateTime.now();
        DateTimeFormatter dtf1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String temp = dtf1.format(ldt1);
        LocalDateTime formatDateTime = LocalDateTime.parse(temp, dtf1);
        System.out.println(formatDateTime);

运行结果:
2022-09-23T11:34:12

long毫秒值转换为日期

System.out.println("---------long毫秒值转换为日期---------");
        DateTimeFormatter df= DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String longToDateTime = df.format(LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()),ZoneId.of("Asia/Shanghai")));
        System.out.println(longToDateTime);

运行结果:

RestController 判断非空_日期时间_09