The new date and time tool class in JDK8 is really easy to use. If you are not sure, come in and have a look. It is recommended to collect

Recently, I just have time to sort out the features of JDK8 for everyone. The role of this in actual development is getting more and more important. This article focuses on explaining the new date and time API.

New date and time API

1. The problem with the old version of the date and time

In the old version, the JDK was very bad for date and time.

    /**
     * 旧版日期时间设计的问题
     */
    @Test
    public void test01() throws Exception{
        // 1.设计不合理
        Date date = new Date(2021,05,05);
        System.out.println(date);

        // 2.时间格式化和解析操作是线程不安全的
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (int i = 0; i < 50; i++) {
            new Thread(()->{
               // System.out.println(sdf.format(date));
                try {
                    System.out.println(sdf.parse("2021-05-06"));
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
  1. The design is unreasonable. There are date classes in the java.util and java.sql packages. java.util.Date contains both date and time, while java.sql.Date only contains the date, in addition to formatting and parsing. The classes are in the java.text package.
  2. Not thread-safe, java.util.Date is not thread-safe, all date classes are variable, this is one of the biggest problems with java date classes.
  3. Time zone processing is troublesome, the date class does not provide internationalization, and there is no time zone support.

2. Introduction to the new date and time API

A new date and time API has been added to JDK 8. This API is designed reasonably and is thread-safe. The new date and time API is located in the java.time package
. Below are some key classes.

  • LocalDate: indicates the date, including year, month, and day, in the format 2019-10-16
  • LocalTime: Represents the time, including hours, minutes and seconds, in the format 16:38:54.158549300
  • LocalDateTime: Represents the date and time, including year, month, day, hour, minute, and second, in the format 2018-09-06T15:33:56.750
  • DateTimeFormatter: Date and time formatting class.
  • Instant: Timestamp, which represents a specific instant in time.
  • Duration: used to calculate the distance between 2 times (LocalTime, hours, minutes, and seconds)
  • Period: used to calculate the distance between 2 dates (LocalDate, year, month, day)
  • ZonedDateTime: Time including time zone

The calendar used in Java is the ISO 8601 calendar system, which is the world civil calendar, which is what we call the Gregorian calendar. There are 365 days in a normal year and 366
days in a leap year . In addition, Java 8 also provides 4 sets of other calendars, namely:

  • ThaiBuddhistDate: Thai Buddhist calendar
  • MinguoDate: Republic of China Calendar
  • JapaneseDate: Japanese calendar
  • HijrahDate: Islamic calendar

2.1 Common operations of date and time

Operation of LocalDate, LocalTime and LocalDateTime.

    /**
     * JDK8 日期时间操作
     */
    @Test
    public void test01(){
        // 1.创建指定的日期
        LocalDate date1 = LocalDate.of(2021, 05, 06);
        System.out.println("date1 = "+date1);

        // 2.得到当前的日期
        LocalDate now = LocalDate.now();
        System.out.println("now = "+now);

        // 3.根据LocalDate对象获取对应的日期信息
        System.out.println("年:" + now.getYear());
        System.out.println("月:" + now.getMonth().getValue());
        System.out.println("日:" + now.getDayOfMonth());
        System.out.println("星期:" + now.getDayOfWeek().getValue());
    }

    /**
     * 时间操作
     */
    @Test
    public void test02(){
        // 1.得到指定的时间
        LocalTime time = LocalTime.of(5,26,33,23145);
        System.out.println(time);
        // 2.获取当前的时间
        LocalTime now = LocalTime.now();
        System.out.println(now);
        // 3.获取时间信息
        System.out.println(now.getHour());
        System.out.println(now.getMinute());
        System.out.println(now.getSecond());
        System.out.println(now.getNano());
    }

    /**
     * 日期时间类型  LocalDateTime
     */
    @Test
    public void test03(){
        // 获取指定的日期时间
        LocalDateTime dateTime =
                LocalDateTime.of(2020
                        , 06
                        , 01
                        , 12
                        , 12
                        , 33
                        , 213);
        System.out.println(dateTime);
        // 获取当前的日期时间
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
        // 获取日期时间信息
        System.out.println(now.getYear());
        System.out.println(now.getMonth().getValue());
        System.out.println(now.getDayOfMonth());
        System.out.println(now.getDayOfWeek().getValue());
        System.out.println(now.getHour());
        System.out.println(now.getMinute());
        System.out.println(now.getSecond());
        System.out.println(now.getNano());
    }

2.2 Date and time modification and comparison

    /**
     * 日期时间的修改
     */
    @Test
    public void test01(){
        LocalDateTime now = LocalDateTime.now();
        System.out.println("now = "+now);
        // 修改日期时间  对日期时间的修改,对已存在的LocalDate对象,创建了它模板
        // 并不会修改原来的信息
        LocalDateTime localDateTime = now.withYear(1998);
        System.out.println("now :"+now);
        System.out.println("修改后的:" + localDateTime);

        System.out.println("月份:" + now.withMonth(10));
        System.out.println("天:" + now.withDayOfMonth(6));
        System.out.println("小时:" + now.withHour(8));
        System.out.println("分钟:" + now.withMinute(15));

        // 在当前日期时间的基础上 加上或者减去指定的时间
        System.out.println("两天后:" + now.plusDays(2));
        System.out.println("10年后:"+now.plusYears(10));
        System.out.println("6个月后 = " + now.plusMonths(6));

        System.out.println("10年前 = " + now.minusYears(10));
        System.out.println("半年前 = " + now.minusMonths(6));
        System.out.println("一周前 = " + now.minusDays(7));
    }

    /**
     * 日期时间的比较
     */
    @Test
    public void test02(){
        LocalDate now = LocalDate.now();
        LocalDate date = LocalDate.of(2020, 1, 3);
        // 在JDK8中要实现 日期的比较 isAfter  isBefore isEqual 通过这几个方法来直接比较
        System.out.println(now.isAfter(date)); // true
        System.out.println(now.isBefore(date)); // false
        System.out.println(now.isEqual(date)); // false
    }

Note: When modifying the date and time, the original LocalDate object will not be modified. Each operation returns a new LocalDate object, so it is data safe in a multi-threaded scenario.

2.3 Formatting and parsing operations

In JDK8, we can java.time.format.DateTimeFormatterperform date parsing and formatting operations through classes

    /**
     * 日期格式化
     */
    @Test
    public void test01(){
        LocalDateTime now = LocalDateTime.now();
        // 指定格式  使用系统默认的格式 2021-05-27T16:16:38.139
        DateTimeFormatter isoLocalDateTime = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
        // 将日期时间转换为字符串
        String format = now.format(isoLocalDateTime);
        System.out.println("format = " + format);

        // 通过 ofPattern 方法来指定特定的格式
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String format1 = now.format(dateTimeFormatter);
        // 2021-05-27 16:16:38
        System.out.println("format1 = " + format1);

        // 将字符串解析为一个 日期时间类型
        LocalDateTime parse = LocalDateTime.parse("1997-05-06 22:45:16", dateTimeFormatter);
        // parse = 1997-05-06T22:45:16
        System.out.println("parse = " + parse);
    }

2.4 Instant class

Add an Instant class (time stamp/timeline) to us in JDK8, which saves the seconds and nanoseconds since January 1, 1970 00:00:00

    /**
     * Instant 时间戳
     *    可以用来统计时间消耗
     */
    @Test
    public void test01() throws Exception{
        Instant now = Instant.now();
        System.out.println("now = " + now);

        // 获取从1970年一月一日 00:00:00 到现在的 纳秒
        System.out.println(now.getNano());
        Thread.sleep(5);
        Instant now1 = Instant.now();
        System.out.println("耗时:" + (now1.getNano() - now.getNano()));

    }

2.5 Calculate the date and time difference

Two tool classes Duration/Period are provided in JDK8: calculate the date and time difference

  1. Duration: used to calculate the difference between two time (LocalTime)
  2. Period: used to calculate the difference between two dates (LocalDate)
    /**
     * 计算日期时间差
     */
    @Test
    public void test01(){
        // 计算时间差
        LocalTime now = LocalTime.now();
        LocalTime time = LocalTime.of(22, 48, 59);
        System.out.println("now = " + now);
        // 通过Duration来计算时间差
        Duration duration = Duration.between(now, time);
        System.out.println(duration.toDays()); // 0
        System.out.println(duration.toHours()); // 6
        System.out.println(duration.toMinutes()); // 368
        System.out.println(duration.toMillis()); // 22124240

        // 计算日期差
        LocalDate nowDate = LocalDate.now();
        LocalDate date = LocalDate.of(1997, 12, 5);
        Period period = Period.between(date, nowDate);
        System.out.println(period.getYears()); // 23
        System.out.println(period.getMonths()); // 5
        System.out.println(period.getDays()); // 22
    }

2.6 Time corrector

Sometimes we may need to adjust as follows: adjust the date to "the first day of the next month" and other operations. At this time, the effect of our time corrector may be better.

  • TemporalAdjuster: time corrector
  • TemporalAdjusters: A large number of commonly used TemporalAdjuster implementations are provided through this class of static methods.
    /**
     * 时间校正器
     */
    @Test
    public void test02(){
        LocalDateTime now = LocalDateTime.now();
        // 将当前的日期调整到下个月的一号
        TemporalAdjuster adJuster = (temporal)->{
            LocalDateTime dateTime = (LocalDateTime) temporal;
            LocalDateTime nextMonth = dateTime.plusMonths(1).withDayOfMonth(1);
            System.out.println("nextMonth = " + nextMonth);
            return nextMonth;
        };
        // 我们可以通过TemporalAdjusters 来实现
        // LocalDateTime nextMonth = now.with(adJuster);
        LocalDateTime nextMonth = now.with(TemporalAdjusters.firstDayOfNextMonth());
        System.out.println("nextMonth = " + nextMonth);
    }

2.7 Time zone of date and time

Java8 has added support for time zone. LocalDate, LocalTime, and LocalDateTime are without time zone. The date and time classes with time zone are: ZonedDate, ZonedTime, ZonedDateTime.
Each time zone corresponds to an ID, and the format of the ID is "region/city". For example: Asia/Shanghai, etc.
ZoneId: This class contains all time zone information

    /**
     * 时区操作
     */
    @Test
    public void test01(){
        // 1.获取所有的时区id
        // ZoneId.getAvailableZoneIds().forEach(System.out::println);

        // 获取当前时间 中国使用的 东八区的时区,比标准时间早8个小时
        LocalDateTime now = LocalDateTime.now();
        System.out.println("now = " + now); // 2021-05-27T17:17:06.951
        // 获取标准时间
        ZonedDateTime bz = ZonedDateTime.now(Clock.systemUTC());
        System.out.println("bz = " + bz); // 2021-05-27T09:17:06.952Z

        // 使用计算机默认的时区,创建日期时间
        ZonedDateTime now1 = ZonedDateTime.now();
        System.out.println("now1 = " + now1); //2021-05-27T17:17:06.952+08:00[Asia/Shanghai]

        // 使用指定的时区创建日期时间
        ZonedDateTime now2 = ZonedDateTime.now(ZoneId.of("America/Marigot"));
        System.out.println("now2 = " + now2);

    }

Advantages of JDK's new date and time API:

  1. In the new version of the date and time API, date and time objects are immutable, and the operation date does not affect the original value, but a new instance is generated
  2. Provide two different ways, effectively distinguish the operation of human and machine
  3. TemporalAdjuster can be more precise operation date, you can also customize the date adjustment period
  4. Thread safe

~Okay, the new date and time API is really easy to use, quickly replace the previous Date, welcome to like, follow and add to favorites!!!