• JDK1.8新特性---新时间日期API


    以下内容均来自如下参考链接:

    jdk8之前日期时间相关的操作大多用的是Date类或者Calendar类,例如:

     Date date = new Date();
     SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
     System.out.println(formatter.format(date)); // 2022-09-18 22:50:58

    Date类或者Calendar类的缺点:

    • 非线程安全 : java.util.Date 是非线程安全的,所有的日期类都是可变的,这是Java的日期类最大的问题之一。

    • 设计很差 :Java的日期时间类的定义并不一致,在 java.util 和 java.sql 的包中都有日期类,此外用于格式化和解析的类在 java.text 包中定义。java.util.Date同时包含日期和时间,而 java.sql.Date仅包含日期,将其纳入java.sql包并不合理。另外这两个类都有相同的名字,这本身就是一个非常糟糕的设计。

    • 时区处理麻烦 : 日期类并不提供国际化,没有时区支持,因此Java引入了java.util.Calendar 和 java.util.TimeZone 类,但他们同样存在上述所有的问题。jd8以后增加了 LocalDate和 Zoned,能更方便优雅的处理日期时间。

           因为原本的Date(jdk1.0提出)、Calendar(jdk1.1提出)使用起来比较困难,即使Calendar类在Date类的基础上改善,但是使用起来还是很麻烦的,所以,在jdk1.8的时候就提出了一些新的时间日期API。

    1. java.time包

           java.time包是在第三方包joda包中的joda-Time的基础上吸收了joda-Time的精华而创建出的,并且在Date类中新增了toInstant()方法,用于将Date转换成新的形式(其实也就是转换成为瞬时,也就是Instant类的对象)。

           包含值对象的基础包 (简记为基础包),在java.time包中的时间日期类纠正了过去Date类和Calendar类中的缺陷,所以在将来很长一段时间内可能都会使用java.time包中的类,这个包中最常用的三个类就是LocalDateTime类、LocalDate类、LocalTime类

    1.1 LocalDateTime类(本地日期时间类)

    包含年月日时分秒,当日期和时间都需要使用时可以使用LocalDateTime

    (LocalDateTime相当于LocalDate + LocalTime的合体)

     package timeAPI;
     ​
     import java.text.SimpleDateFormat;
     import java.time.*;
     import java.util.Date;
     ​
     /**
      * @ClassName LocalDateTimeAPI
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/9/18 22:35
      * @Version 1.0
      */
     public class LocalDateTimeAPI {
         public static void main(String[] args) {
             Date date = new Date();
             SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
             System.out.println(formatter.format(date));
     ​
             // 获取当前日期时间:2022-09-18T22:37:32.623
             LocalDateTime nowDateTime = LocalDateTime.now();
             System.out.println("nowDateTime = " + nowDateTime);
     ​
             // 获取当前日期:2022-09-18
             LocalDate localDate = nowDateTime.toLocalDate();
             System.out.println("localDate = " + localDate);
     ​
             // 获取当前时间:22:40:06.052
             LocalTime localTime = nowDateTime.toLocalTime();
             System.out.println("localTime = " + localTime);
     ​
             // 获得当前年份:2022
             int year = nowDateTime.getYear();
             System.out.println("year = " + year);
     ​
             // 获得当前月份:SEPTEMBER
             Month month = nowDateTime.getMonth();
             System.out.println("month = " + month);
             int monthValue = nowDateTime.getMonth().getValue();
             System.out.println("monthValue = " + monthValue);// 9
     ​
             // 获得当前天为该年中的第几天:261
             int dayOfYear = nowDateTime.getDayOfYear();
             System.out.println("dayOfYear = " + dayOfYear);
     ​
             // 获得当前天为该月中的第几天:18
             int dayOfMonth = nowDateTime.getDayOfMonth();
             System.out.println("dayOfMonth = " + dayOfMonth);
     ​
             // 获得当前天为该星期中的第几天:SUNDAY
             DayOfWeek dayOfWeek = nowDateTime.getDayOfWeek();
             System.out.println("dayOfWeek = " + dayOfWeek);
             int dayWeek = nowDateTime.getDayOfWeek().getValue();
             System.out.println("dayWeek = " + dayWeek);// 7
     ​
             // 获得当前小时:22
             int hour = nowDateTime.getHour();
             System.out.println("hour = " + hour);
     ​
             // 获得当前分钟:46
             int minute = nowDateTime.getMinute();
             System.out.println("minute = " + minute);
     ​
             // 获得当前秒数:13
             int second = nowDateTime.getSecond();
             System.out.println("second = " + second);
         }
     }

    1.2 LocalDate类(本地日期类)

    只包含年月日,不包含时分秒,当不需要具体的时间时可以使用LocalDate

     package timeAPI;
     ​
     import java.time.DayOfWeek;
     import java.time.LocalDate;
     import java.time.Month;
     ​
     /**
      * @ClassName LocalDateAPI
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/9/18 22:59
      * @Version 1.0
      */
     public class LocalDateAPI {
         public static void main(String[] args) {
             // 获得当前日期:2022-09-18
             LocalDate nowDate = LocalDate.now();
             System.out.println("nowDate = " + nowDate);
     ​
             // 获得年份:2022
             int year = nowDate.getYear();
             System.out.println("year = " + year);
     ​
             // 获得月份:SEPTEMBER
             Month month = nowDate.getMonth();
             System.out.println("month = " + month);
             int monthValue = nowDate.getMonth().getValue();
             System.out.println("monthValue = " + monthValue);// 9
             int monthValue1 = nowDate.getMonthValue();
             System.out.println("monthValue1 = " + monthValue1);// 9
     ​
             // 今天为该年中的第几天:261
             int dayOfYear = nowDate.getDayOfYear();
             System.out.println("dayOfYear = " + dayOfYear);
     ​
             // 今天为该月中的第几天:18
             int dayOfMonth = nowDate.getDayOfMonth();
             System.out.println("dayOfMonth = " + dayOfMonth);
     ​
             // 今天为该周中的星期几:SUNDAY
             DayOfWeek dayOfWeek = nowDate.getDayOfWeek();
             System.out.println("dayOfWeek = " + dayOfWeek);
             int dayWeek = nowDate.getDayOfWeek().getValue();
             System.out.println("dayWeek = " + dayWeek);// 7
         }
     }

    1.3 LocalTime类(本地时间类)

    只包含时分秒,不包含年月日,当不需要具体的日期时可以使用LocalTime

     package timeAPI;
     ​
     import java.time.LocalTime;
     ​
     /**
      * @ClassName LocalTimeAPI
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/9/18 23:08
      * @Version 1.0
      */
     public class LocalTimeAPI {
         public static void main(String[] args) {
             // 获得当前时间:23:09:09.294
             LocalTime nowTime = LocalTime.now();
             System.out.println("nowTime = " + nowTime);
     ​
             // 获得当前小时:23
             int hour = nowTime.getHour();
             System.out.println("hour = " + hour);
     ​
             // 获得当前分钟:10
             int minute = nowTime.getMinute();
             System.out.println("minute = " + minute);
     ​
             // 获得当前秒数:51
             int second = nowTime.getSecond();
             System.out.println("second = " + second);
         }
     }

    1.4 ZonedDateTime类(时区类)

    参考链接:ZonedDateTime类_窝在小角落里学习的博客-CSDN博客_zoneddatetime

           因为LocalDateTime没有时区,无法确定某一时刻,导致LocalDateTime无法与时间戳进行转换。其实LocalDateTime和ZonedDateTime很相似,区别只是LocalDateTime总是表示本地日期和时间,而ZonedDateTime要表示一个带时区的日期和时间。

           我们可以简单地把ZonedDateTime理解成LocalDateTime + ZoneId。ZoneId是java.time引入的新的时区类,注意和旧的java.util.TimeZone区别。

    ZonedDateTime类的常用方法如下:

     //从默认时区中的系统时钟中获取当前日期时间
     static ZonedDateTime now() 
     ​
     //从指定的时钟中获取当前日期时间
     static ZonedDateTime now(Clock clock) 
      
     //从指定时区中的系统时钟中获得当前日期时间  
     static ZonedDateTime now(ZoneId zone) 
     ​
     //获得 ZonedDateTime实例从年,月,日,小时,分钟,秒,纳秒和时区
     static ZonedDateTime of(int year, int month, int dayOfMonth, int hour, int minute, int second, int nanoOfSecond, ZoneId zone) 
       
     //获得 ZonedDateTime实例从本地日期和时间
     static ZonedDateTime of(LocalDate date, LocalTime time, ZoneId zone) 
      
     //获得 ZonedDateTime实例从本地日期时间
     static ZonedDateTime of(LocalDateTime localDateTime, ZoneId zone) 
       
     //获得 ZonedDateTime实例从一个文本字符串,如 2007-12-03T10:15:30+01:00[Europe/Paris]
     static ZonedDateTime parse(CharSequence text) 
     ​
     //获得 ZonedDateTime实例从使用特定格式的文本字符串
     static ZonedDateTime parse(CharSequence text, DateTimeFormatter formatter) 
     ​
     //返回此日期时间的副本,以不同的时区,保留即时
     ZonedDateTime withZoneSameInstant(ZoneId zone)

    注意:LocalDateTime类也提供了一个方法来获取ZonedDateTime对象

     //结合时间与时区来创建一个 ZonedDateTime
     ZonedDateTime atZone(ZoneId zone)

    举例:

     package timeAPI;
     ​
     import java.time.LocalDateTime;
     import java.time.ZoneId;
     import java.time.ZonedDateTime;
     ​
     /**
      * @ClassName ZonedDateTimeTest
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/9/21 20:19
      * @Version 1.0
      */
     public class ZonedDateTimeTest {
         public static void main(String[] args) {
             // 从默认时区中的系统时钟中获取当前日期时间:2022-09-21T20:23:16.600+08:00[Asia/Shanghai]
             ZonedDateTime nowZonedDateTime = ZonedDateTime.now();
             System.out.println("nowZonedDateTime = " + nowZonedDateTime);
     ​
             // 获得指定时区的当前日期时间:2022-09-21T08:23:16.601-04:00[America/New_York]
             ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("America/New_York"));
             System.out.println("zonedDateTime = " + zonedDateTime);
     ​
             // 获得指定时间指定时区的日期时间
             LocalDateTime localDateTime = LocalDateTime.of(2022, 11, 11, 22, 22, 22);
             System.out.println("localDateTime = " + localDateTime);// 2022-11-11T22:22:22
             ZonedDateTime zonedDateTime1 = ZonedDateTime.of(localDateTime, ZoneId.of("America/New_York"));
             System.out.println("zonedDateTime1 = " + zonedDateTime1);// 2022-11-11T22:22:22-05:00[America/New_York]
     ​
             // LocalDateTime.atZone()方法: 获得指定时间默认时区与指定时区的日期时间
             ZonedDateTime zonedDateTime2 = localDateTime.atZone(ZoneId.systemDefault());
             System.out.println("zonedDateTime2 = " + zonedDateTime2);// 2022-11-11T22:22:22+08:00[Asia/Shanghai]
             ZonedDateTime zonedDateTime3 = localDateTime.atZone(ZoneId.of("America/New_York"));
             System.out.println("zonedDateTime3 = " + zonedDateTime3);// 2022-11-11T22:22:22-05:00[America/New_York]
     ​
     ​
             /**
              * 时区转换
              */
             LocalDateTime dateTime = LocalDateTime.of(2020, 2, 2, 22, 22, 22);
             System.out.println("dateTime = " + dateTime);// 2020-02-02T22:22:22
             ZonedDateTime zoneTime = ZonedDateTime.of(dateTime, ZoneId.of("Asia/Shanghai"));
             System.out.println("zoneTime = " + zoneTime);// 2020-02-02T22:22:22+08:00[Asia/Shanghai]
             ZonedDateTime zoneTime2 = zoneTime.withZoneSameInstant(ZoneId.of("America/New_York"));
             System.out.println("zoneTime2 = " + zoneTime2);// 2020-02-02T09:22:22-05:00[America/New_York]
         }
     }

    1.5 Duration类(持续时间类)

    参考链接:

           在JDK8中,可以使用java.time.Duration来计算两个时间之间的时间差,可用于LocalDateTime之间的比较,也可用于Instant之间的比较,这个类是不可变的、线程安全的、最终类。

           Duration类通过秒和纳秒相结合来描述一个时间量,最高精度是纳秒。时间量可以为正也可以为负,比如1天(86400秒0纳秒)、-1天(-86400秒0纳秒)、1年(31556952秒0纳秒)、1毫秒(0秒1000000纳秒)等。

    1.5.1 创建方法

    (1)通过时间单位创建

           基于天、时、分、秒、毫秒、纳秒创建:ofDays()、ofHours()、ofMinutes()、ofSeconds()、ofMillis()、ofNanos()。例如:

     Duration fromDays = Duration.ofDays(1);

    (2)通过LocalDateTime或LocalTime

           通过LocalDateTime或者LocalTime 类,然后使用between获取创建Duration。

     LocalDateTime start = LocalDateTime.of(2022, 1, 1, 8, 0, 0);
     LocalDateTime end = LocalDateTime.of(2022, 1, 2, 8, 30, 30);
     Duration duration = Duration.between(start, end);

    (3)通过已有的Duration

     Duration du1 = Duration.ofHours(10);
     Duration duration = Duration.from(du1);

    1.5.2 解析方法

           Duration采用ISO-8601时间格式,格式为:PnYnMnDTnHnMnS (n为个数),其中,"P", "D", "H", "M" 和 "S"可以是大写或者小写,建议大写,可以用“-”表示负数。

     Duration fromChar1 = Duration.parse("P1DT1H10M10.5S");
     Duration fromChar2 = Duration.parse("PT10M");

    例如:P1Y2M10DT2H30M15.03S

    P:开始标记

    1Y:一年

    2M:两个月

    10D:十天

    T:日期和时间的分割标记

    2H:两个小时

    30M:三十分钟

    15.03S:15.03秒

    其他举例:

     "PT20.345S" -- parses as "20.345 seconds"
     "PT15M"     -- parses as "15 minutes" (where a minute is 60 seconds)
     "PT10H"     -- parses as "10 hours" (where an hour is 3600 seconds)
     "P2D"       -- parses as "2 days" (where a day is 24 hours or 86400 seconds)
     "P2DT3H4M"  -- parses as "2 days, 3 hours and 4 minutes"
     "P-6H3M"    -- parses as "-6 hours and +3 minutes"
     "-P6H3M"    -- parses as "-6 hours and -3 minutes"
     "-P-6H+3M"  -- parses as "+6 hours and -3 minutes"

    1.5.3 计算两个时间之间的时间差

     package timeAPI;
     ​
     import java.io.BufferedWriter;
     import java.time.Duration;
     import java.time.LocalDateTime;
     ​
     /**
      * @ClassName DurationTest
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/9/21 21:21
      * @Version 1.0
      */
     public class DurationTest {
         public static void main(String[] args) {
             // 获得当前日期时间
             LocalDateTime nowDateTime = LocalDateTime.now();
             System.out.println("nowDateTime = " + nowDateTime);
     ​
             // 指定日期时间
             LocalDateTime oldDateTime = LocalDateTime.of(2020, 10, 10, 10, 10, 10);
             System.out.println("oldDateTime = " + oldDateTime);
     ​
             // 计算两个时间的时间差 Duration.between(start, end):start - end
             Duration between = Duration.between(oldDateTime, nowDateTime);
             System.out.println("between = " + between);
     ​
             // 任何一个时间单元为负数,则返回true,即end早于start
             //               正数,  返回false,即end晚于start
             boolean negative = between.isNegative();
             System.out.println("negative = " + negative);
     ​
     ​
             // toX用来转换为其他单位,支持:toDays, toHours, toMinutes, toMillis, toNanos
             // 两个时间之间的时间差转换为天数
             System.out.println("between.toDays() = " + between.toDays());
     ​
             // 两个时间之间的时间差转换为小时数
             System.out.println("between.toHours() = " + between.toHours());
     ​
             // 两个时间之间的时间差转换为分钟数
             System.out.println("between.toMinutes() = " + between.toMinutes());
             // 两个时间之间的时间差转换为毫秒数
             System.out.println("between.toMillis() = " + between.toMillis());
     ​
             // 两个时间之间的时间差转换为纳秒数
             System.out.println("between.toNanos() = " + between.toNanos());
     ​
     ​
             // 可以用getX来获得指定位置的值,因为Duration是由秒和纳秒组成,所以只能获得秒和纳秒
             // 获得两个时间差中的秒数
             long seconds = between.getSeconds();
             System.out.println("seconds = " + seconds);
     ​
             // 获得两个时间差中的纳秒数
             int nano = between.getNano();
             System.out.println("nano = " + nano);
         }
     }

    输出结果:

     nowDateTime = 2022-09-21T23:32:01.592
     oldDateTime = 2020-10-10T10:10:10
     between = PT17077H21M51.592S
     negative = false
     between.toDays() = 711
     between.toHours() = 17077
     between.toMinutes() = 1024641
     between.toMillis() = 61478511592
     between.toNanos() = 61478511592000000
     seconds = 61478511
     nano = 592000000

    1.5.4 增减方法

    • plusX()、minusX():X表示days, hours, millis, minutes, nanos 或 seconds

     Duration duration = Duration.ofHours(2);
     Duration newDuration = duration.plusSeconds(33);
    • plus()/minus()方法:带TemporalUnit 类型参数进行加减

     Duration duration = Duration.ofHours(2);
     Duration newDuration = duration.plus(33, ChronoUnit.SECONDS);

    1.6 Period类

    参考链接:https://www.jb51.net/article/249084.htm

           Duration类通过秒和纳秒相结合来描述一个时间量,最高精度是纳秒。时间量可以为正也可以为负,比如1天(86400秒0纳秒)、-1天(-86400秒0纳秒)、1年(31556952秒0纳秒)、1毫秒(0秒1000000纳秒)等。

           Period类通过年、月、日相结合来描述一个时间量,最高精度是天。时间量可以为正也可以为负,例如2年(2年0个月0天)、3个月(0年3个月0天)、4天(0年0月4天)等。

           这两个类是不可变的、线程安全的、最终类。都是JDK8新增的。

    1.6.1 创建方法

    (1)通过时间单位创建

    如果仅一个值表示,如使用ofDays()方法,那么其他值为0。

    若仅用ofWeeks,则其天数为week数乘以7.

     Period fromUnits = Period.of(3, 10, 10);
     Period fromDays = Period.ofDays(50);
     Period fromMonths = Period.ofMonths(5);
     Period fromYears = Period.ofYears(10);
     Period fromWeeks = Period.ofWeeks(40);  //280天

    (2)通过LocalDate创建

     LocalDate startDate = LocalDate.of(2015, 2, 20);
     LocalDate endDate = LocalDate.of(2017, 1, 15);
     // startDate减endDate
     Period period = Period.between(startDate, endDate);

    1.6.2 解析方法

    格式1:“PnYnMnWnD”

    P:开始符,表示period(即:表示年月日);

    Y:year;

    M:month;

    W:week;

    D:day

    P, Y, M, W, D都可以用大写或者小写。

     Period period = Period.parse("P2Y");       //2年
     Period period = Period.parse("P2Y3M5D");   //2年3月5天
     Period period = Period.parse("P1Y2M3W4D"); // 1年2月3周4天。即:1年2月25天

    获得年月日:

     period.getYears();
     period.getMonths();
     period.getDays();

    1.6.3 比较方法(between)

     LocalDate startDate = LocalDate.of(2015, 2, 20);
     LocalDate endDate = LocalDate.of(2017, 1, 15);
     // startDate减endDate
     Period period = Period.between(startDate, endDate);
     // 任何一个时间单元为负数,则返回true,表示endDate早于startDate
     period.isNegative()

    1.6.4 增减方法

     Period period = Period.parse("P2Y3M5D");
     period.plusDays(50);
     period.minusMonths(2);

    1.6.5 转换单位

     Period period = Period.parse("P1Y2M3D");
     period.toTotalMonths(); // 14

    1.6.6 取值方法

     Period period = Period.parse("P1Y2M3D");
     period.getYears();  // 1
     period.getMonths(); // 2
     period.getDays();   // 3

    1.7 创建指定日期时间

     package timeAPI;
     ​
     import java.time.LocalDate;
     import java.time.LocalDateTime;
     import java.time.LocalTime;
     ​
     /**
      * @ClassName CreateDateTime
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/9/18 23:50
      * @Version 1.0
      */
     public class CreateDateTime {
         public static void main(String[] args) {
             LocalDateTime ofDateTime = LocalDateTime.of(2022, 9, 18, 23, 59, 59);
             System.out.println("ofDateTime = " + ofDateTime);// 2022-09-18T23:59:59
     ​
             LocalDate ofDate = LocalDate.of(2022, 9, 18);
             System.out.println("ofDate = " + ofDate);// 2022-09-18
     ​
             LocalTime ofTime = LocalTime.of(23, 59, 59);
             System.out.println("ofTime = " + ofTime);// 23:59:59
         }
     }

    1.8 日期时间加减及相关运算

     package timeAPI;
     ​
     import java.time.*;
     import java.time.chrono.IsoChronology;
     import java.time.temporal.ChronoUnit;
     import java.time.temporal.TemporalAdjusters;
     ​
     import static java.time.temporal.ChronoUnit.*;
     ​
     public class DateTimeOperate {
         public static void main(String[] args) {
             /**
              * 日期时间加减
              */
             LocalDateTime localDateTime = LocalDateTime.now();
             System.out.println("localDateTime = " + localDateTime);// 2022-09-19T19:58:10.146
     ​
             // 日期时间加法运算
             LocalDateTime localDateTime1 = localDateTime.plusYears(1).plusMonths(2).plusDays(3).plusHours(4).plusMinutes(5).plusSeconds(6);
             System.out.println("localDateTime1 = " + localDateTime1);// 2023-11-23T00:03:16.146
     ​
             // 日期时间减法运算
             LocalDateTime localDateTime2 = localDateTime.minusYears(1).minusMonths(2).minusDays(3).minusHours(4).minusMinutes(5).minusSeconds(6);
             System.out.println("localDateTime2 = " + localDateTime2);// 2021-07-16T15:53:04.146
     ​
             // ChronoUnit下类似ChronoUnit.DAYS的还有很多:ChronoUnit.YEARS、ChronoUnit.MONTHS、ChronoUnit.WEEKS等
             LocalDateTime localDateTime3 = localDateTime2.plus(1, ChronoUnit.YEARS);
             System.out.println("localDateTime3 = " + localDateTime3);
             LocalDateTime localDateTime4 = localDateTime2.minus(1, ChronoUnit.YEARS);
             System.out.println("localDateTime4 = " + localDateTime4);
     ​
     ​
             /**
              * 日期加减
              */
             LocalDate localDate = LocalDate.now();
             System.out.println("localDate = " + localDate);// 2022-09-19
     ​
             // 日期加法运算
             LocalDate localDate1 = localDate.plusYears(1).plusMonths(2).plusDays(3).plusWeeks(4);
             System.out.println("localDate1 = " + localDate1);// 2023-12-20
     ​
             // 日期减法运算
             LocalDate localDate2 = localDate.minusYears(1).minusMonths(2).minusDays(3).minusWeeks(4);
             System.out.println("localDate2 = " + localDate2);// 2021-06-18
     ​
             // ChronoUnit下类似ChronoUnit.DAYS的还有很多:ChronoUnit.YEARS、ChronoUnit.MONTHS、ChronoUnit.WEEKS等
             LocalDate localDate3 = localDate2.plus(1, ChronoUnit.DAYS);
             System.out.println("localDate3 = " + localDate3);// 2021-06-19
             LocalDate localDate4 = localDate3.plus(-1, ChronoUnit.DAYS);
             System.out.println("localDate4 = " + localDate4);// 2021-06-18
     ​
             
             /**
              * 时间加减
              */
             LocalTime localTime = LocalTime.now();
             System.out.println("localTime = " + localTime);// 20:10:36.512
     ​
             // 时间加法运算
             LocalTime localTime1 = localTime.plusHours(1).plusMinutes(2).plusSeconds(3);
             System.out.println("localTime1 = " + localTime1);// 21:12:39.512
     ​
             // 时间减法运算
             LocalTime localTime2 = localTime.minusHours(1).minusMinutes(2).minusSeconds(3);
             System.out.println("localTime2 = " + localTime2);// 19:08:33.512
     ​
             // ChronoUnit下类似ChronoUnit.DAYS的还有很多:ChronoUnit.YEARS、ChronoUnit.MONTHS、ChronoUnit.WEEKS等
             LocalTime localTime3 = localTime2.plus(1, HOURS);
             System.out.println("localTime3 = " + localTime3);
             LocalDateTime localTime4 = localDateTime2.minus(1, HOURS);
             System.out.println("localTime4 = " + localTime4);
     ​
             // 计算两个时间时间的时间差
             long betweenHour = HOURS.between(localTime1, localTime2);
             System.out.println("betweenHour = " + betweenHour);
             long betweenMinute = MINUTES.between(localTime1, localTime2);
             System.out.println("betweenMinute = " + betweenMinute);
             long betweenSecond = SECONDS.between(localTime1, localTime2);
             System.out.println("betweenSecond = " + betweenSecond);
     ​
     ​
             /**
              * 比较日期的先后
              */
             LocalDate nowDate = LocalDate.now();
             System.out.println("nowDate = " + nowDate);// 2022-09-19
     ​
             LocalDate date = LocalDate.of(2022, 9, 18);
             System.out.println("date = " + date);// 2022-09-18
     ​
             boolean equal = nowDate.isEqual(date);
             System.out.println("equal = " + equal);// false
     ​
             boolean before = nowDate.isBefore(date);
             System.out.println("before = " + before);// false
     ​
             boolean after = nowDate.isAfter(date);
             System.out.println("after = " + after);// true
     ​
             // -1表示早于,0表示相等,1表示晚于
             int i = nowDate.compareTo(date);
             System.out.println("i = " + i);// 1
     ​
             // 判断日期1是否早于日期2,早于返回false,晚于返回true
             Period period = Period.between(nowDate, date);
             System.out.println("period = " + period);// P-1D
             boolean periodNegative = period.isNegative();
             System.out.println("periodNegative = " + periodNegative);// true
             boolean periodZero = period.isZero();
             System.out.println("periodZero = " + periodZero);// false
     ​
             boolean supported = nowDate.isSupported(ChronoUnit.DAYS);
             System.out.println("supported = " + supported);// true
     ​
     ​
             /**
              * 判断平闰年
              */
             // 指定年份判断平闰年
             boolean leapYear1 = IsoChronology.INSTANCE.isLeapYear(2000);
             System.out.println("leapYear1 = " + leapYear1);// true
     ​
             // localDateTime.getYear()
             boolean leap = Year.isLeap(localDateTime4.getYear());
             System.out.println("leap = " + leap);// false
     ​
             // localDate.getYear()
             boolean leap1 = Year.isLeap(localDate.getYear());
             System.out.println("leap1 = " + leap1);// false
     ​
             // localDate.isLeapYear()
             boolean leapYear = nowDate.isLeapYear();
             System.out.println("leapYear = " + leapYear);// false
     ​
     ​
             /**
              * 计算指定日期所在月份的天数
              */
             int monthDays = nowDate.lengthOfMonth();
             System.out.println("monthDays = " + monthDays);// 30
     ​
             /**
              * 计算指定日期所在年份的天数
              */
             int yearDays = nowDate.lengthOfYear();
             System.out.println("yearDays = " + yearDays);// 365
     ​
             /**
              * 判断今天是不是星期一
              */
             boolean isMonday = LocalDate.now().getDayOfWeek() == DayOfWeek.MONDAY;
             System.out.println(isMonday);
     ​
             /**
              * 获取日期所在月份的最后一天
              */
             LocalDate lastDayOfMonth = nowDate.with(TemporalAdjusters.lastDayOfMonth());
             System.out.println("lastDayOfMonth = " + lastDayOfMonth);
     ​
     ​
             /**
              * 计算两个日期之间的时间间隔
              */
             long untilYear = nowDate.until(date, YEARS);
             System.out.println("untilYear = " + untilYear);
             long untilMonth = nowDate.until(date, MONTHS);
             System.out.println("untilMonth = " + untilMonth);
             long untilDay = nowDate.until(date, DAYS);
             System.out.println("untilDay = " + untilDay);
     ​
             Period periodDate = Period.between(nowDate, date);
             System.out.println("periodDate = " + periodDate);
             int periodDateYears = periodDate.getYears();
             System.out.println("periodDateYears = " + periodDateYears);
             int periodDateMonths = periodDate.getMonths();
             System.out.println("periodDateMonths = " + periodDateMonths);
             int periodDateDays = periodDate.getDays();
             System.out.println("periodDateDays = " + periodDateDays);
     ​
             /**
              * MonthDay表示月与日的组合
              */
             MonthDay monthDay = MonthDay.now();
             System.out.println(monthDay.getDayOfMonth());// 今天是这个月的第几天:19
             System.out.println(monthDay.getMonth());// 今天是几月:SEPTEMBER
             LocalDate monthDayDate = monthDay.atYear(2022);// 指定年份
             System.out.println(monthDayDate);// 2022-09-19
     ​
             /**
              * 计算生日
              */
             LocalDate birthDate = LocalDate.of(2020,02,02);
             MonthDay birthdayMonthDay = MonthDay.of(birthDate.getMonth(), birthDate.getDayOfMonth());
             MonthDay currentMonthDay = MonthDay.from(nowDate);// //LocalDate格式换转换为MonthDay
             if(currentMonthDay.equals(birthdayMonthDay)){
                 System.out.println("陌生人,生日快乐!");
             }else{
                 System.out.println("不着急,再等等,下次我们陪你一起过生日!");
             }
         }
     }

    1.9 Clock时间戳与其他时区时间

           Java 8 增加了一个 Clock 时钟类用于获取当时的时间戳,或当前时区下的日期时间信息。以前用到System.currentTimeInMillis() 和 TimeZone.getDefault() 的地方都可用 Clock 替换。

    • 获取时间戳:

     //获取时间戳方法1
     Instant timestamp = Instant.now();
     System.out.println("Instant获取时间戳:" + timestamp.toEpochMilli());
     ​
     //获取时间戳方法2
     Clock clock = Clock.systemUTC();
     System.out.println("Clock时间戳 : " + clock.millis());
     ​
     //获取时间戳方法3
     Clock defaultClock = Clock.systemDefaultZone();
     System.out.println("defaultClock时间戳: " + defaultClock.millis());

    输出结果:

     Instant获取时间戳:1663602236877
     Clock时间戳 : 1663602236877
     defaultClock时间戳: 1663602236877

           无论是使用Clock.systemUTC或者Clock.systemDefaultZone获得的时间戳都是一样的,区别在于Clock.systemUTC返回的时钟的区域为UTC时区,Clock.systemDefaultZone返回的是你所在国家的时区,所以如果你还要把你的时间戳转换成LocalDateTime这样具体的年月日时分秒,那你就应该用Clock.systemDefaultZone。

    • 时间戳转LocalDateTime:

     Clock defaultClock = Clock.systemDefaultZone();
     System.out.println("当前时间戳 : " + defaultClock.millis());
     LocalDateTime data1 = LocalDateTime.now(defaultClock);
     System.out.println("时间戳转化为时间" + data1.toString());

    输出结果:

     当前时间戳 : 1663602365479
     时间戳转化为时间2022-09-19T23:46:05.479
    • 获取巴黎的当前时间:

     Clock clock = Clock.system(ZoneId.of("Europe/Paris")); // 指定巴黎时区
     System.out.println("巴黎当前时间戳 : " + clock.millis());
     LocalDateTime data=LocalDateTime.now(clock);
     System.out.println("巴黎当前时间" + data.toString());

    输出结果:

     巴黎当前时间戳 : 1663602517128
     巴黎当前时间2022-09-19T17:48:37.128

    时间戳测试:​​​​​​​

     public class TimeStampTest {
         public static void main(String[] args) {
             /**
              *  系统时间
              */
             long l = System.currentTimeMillis();
             System.out.println("l = " + l);
             // 1668160031441
     ​
             /**
              * 系统时间转时间戳
              */
             Timestamp t = new Timestamp(System.currentTimeMillis());
             System.out.println("t = " + t);
             // t = 2022-11-14 08:55:05.524
     ​
             /**
              * 时间戳
              */
             Timestamp timestamp = new Timestamp(l);
             System.out.println("timestamp = " + timestamp);
             // timestamp = 2022-11-14 08:55:05.53
     ​
             /**
              * 时间戳.getTime()
              */
             long time = timestamp.getTime();
     ​
             /**
              * 时间戳.getTime()转Date
              */
             Date date = new Date(time);
             System.out.println("date = " + date);
             // date = 2022-11-14
     ​
             /**
              * 时间戳.getTime()转LocalDateTime
              */
             Instant instant = Instant.ofEpochMilli(time);
             LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
             System.out.println("localDateTime = " + localDateTime);
             // localDateTime = 2022-11-14T09:00:39.840
     ​
             /**
              * LocalDateTime转LocalDate
              */
             LocalDate localDate = localDateTime.toLocalDate();
             System.out.println("localDate = " + localDate);
             // localDate = 2022-11-14
     ​
             /**
              * LocalDateTime转LocalTime
              */
             LocalTime localTime = localDateTime.toLocalTime();
             System.out.println("localTime = " + localTime);
             // localTime = 09:04:13.453
         }
     }

    2. java.time.format包(格式化和解析时间和日期)

    2.1 LocalDateTime格式化

     package timeAPI;
     ​
     import java.time.LocalDateTime;
     import java.time.OffsetDateTime;
     import java.time.ZoneOffset;
     import java.time.format.DateTimeFormatter;
     ​
     /**
      * @ClassName DateTimeFormatterTest
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/9/18 23:13
      * @Version 1.0
      */
     public class LocalDateTimeFormatter {
         public static void main(String[] args) {
             // LocalDateTime格式化
             LocalDateTime localDateTime = LocalDateTime.now();// 2022-09-18T23:18:15.907
             System.out.println("localDateTime = " + localDateTime);
     ​
             DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
             String format = localDateTime.format(dateTimeFormatter);
             System.out.println("format = " + format);// 2022-09-18 23:18:15
     ​
             DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分ss秒");
             String format1 = localDateTime.format(dateTimeFormatter1);
             System.out.println("format1 = " + format1);// 2022年09月18日23时18分15秒
     ​
             String s = localDateTime.toString();
             System.out.println("s = " + s);// 2022-09-18T23:19:12.088
     ​
             // 添加时区
             OffsetDateTime offsetDateTime = localDateTime.atOffset(ZoneOffset.ofHours(+8));
             System.out.println("offsetDateTime = " + offsetDateTime);// 2022-09-18T23:21:12.122+08:00
             String s1 = offsetDateTime.toString();
             System.out.println("s1 = " + s1);// 2022-09-18T23:21:12.122+08:00
     ​
             // 解析字符串: 年月日之间要用-分割,时分秒用:分割,日期和时间之间用T分割
             String dateTimeString ="2022-09-18T23:18:00";
             LocalDateTime parseDateTime = LocalDateTime.parse(dateTimeString);
             System.out.println("parseDateTime = " + parseDateTime);// 2022-09-18T23:18
             // 注意: LocalDateTime当秒数刚好为0的时候格式化后秒会被省略,格式化要指定到秒。
         }
     }

    2.2 LocalDate格式化

     package timeAPI;
     ​
     import java.time.LocalDate;
     import java.time.LocalDateTime;
     import java.time.format.DateTimeFormatter;
     ​
     /**
      * @ClassName LocalDateFormatter
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/9/18 23:25
      * @Version 1.0
      */
     public class LocalDateFormatter {
         public static void main(String[] args) {
             LocalDate localDate = LocalDate.now();
             System.out.println("localDate = " + localDate);// 2022-09-18
     ​
             DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
             String format = localDate.format(dateTimeFormatter);
             System.out.println("format = " + format);// 2022年09月18日
     ​
             DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy.MM.dd");
             String format1 = localDate.format(dateTimeFormatter1);
             System.out.println("format1 = " + format1);// 2022.09.18
     ​
             // 解析字符串: 年月日用-分开,月份和日期如果小于10要补零
             String dateString ="2022-09-18";
             LocalDate parseDate = LocalDate.parse(dateString);
             System.out.println("parseDate = " + parseDate);// 2022-09-18
     ​
             dateString = "20220918";
             //除了DateTimeFormatter.BASIC_ISO_DATE格式DateTimeFormatter里还有其他格式可选择
             parseDate = LocalDate.parse(dateString, DateTimeFormatter.BASIC_ISO_DATE);
             System.out.println("parseDate = " + parseDate);// 2022-09-18
         }
     }

    2.3 LocalTime格式化

     package timeAPI;
     ​
     import java.time.LocalDateTime;
     import java.time.LocalTime;
     import java.time.format.DateTimeFormatter;
     ​
     /**
      * @ClassName LocalTimeFormatter
      * @Description TODO
      * @Author Jiangnan Cui
      * @Date 2022/9/18 23:25
      * @Version 1.0
      */
     public class LocalTimeFormatter {
         public static void main(String[] args) {
             LocalTime localTime = LocalTime.now();
             System.out.println("localTime = " + localTime);// 23:31:00.169
     ​
             DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("HH-mm-ss");
             String format = localTime.format(dateTimeFormatter);
             System.out.println("format = " + format);// 23-31-00
     ​
             DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("HH时mm分ss秒");
             String format1 = localTime.format(dateTimeFormatter1);
             System.out.println("format1 = " + format1);// 23时31分00秒
     ​
             // 解析字符串: 时分秒用:分开,时分秒如果小于10要补零
             String timeString ="23:18:00";
             LocalTime parseTime = LocalTime.parse(timeString);
             System.out.println("parseTime = " + parseTime);// 23:18
         }
     }

    3. java.time.temporal包(底层框架扩展特性)

    待完善

    4. java.time.chrono包(日历类访问)

    待完善

    5. java.time.zone包

    其中包含了对不同的时区的访问,日期就是年月日,时间就是时分秒 待完善

  • 相关阅读:
    【开源项目推荐-ColugoMum】这群本科生基于国产深度学习框架PaddlePadddle开源了零售行业解决方案
    UML建模案例分析-需求对类图的影响很大
    system V共享内存
    java11中String类,StringBuffer类和StringBuilder类区别
    日常工作中程序员最讨厌哪些工作事项?
    区块链技术与AI:IT领域的未来合作伙伴
    YOLOv7改进---注意力机制: EMA基于跨空间学习的高效多尺度注意力、效果优于ECA、CBAM、CA | 小目标涨点明显 | ICASSP2023
    辅助驾驶功能开发-功能规范篇(16)-2-领航辅助系统NAP-智能避让
    关于网络安全运营工作与安全建设工作的一些思考
    【操作系统】操作系统笔记
  • 原文地址:https://blog.csdn.net/xiaocui1995/article/details/126925478