JDK8 features - new date and time API

Problem with old version date and time

In the old version, JDK was very poor at 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(()->{
    
    
                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 dates. In addition, it is used for formatting and parsing. The class is under the java.text package.
  2. Non-thread safe, java.util.Date is not thread-safe, all date classes are mutable, 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.

New Date Time API

JDK 8 adds a new set of date and time APIs, which are well designed and thread-safe. The new date and time API is located in the java.time package. Below are some key classes.

  • LocalDate: represents the date, including year, month and day, in the format of 2019-10-16
  • LocalTime: represents time, including hours, minutes and seconds, in the format of 16:38:54.158549300
  • LocalDateTime: represents date and time, including year, month, day, hours, minutes and seconds, in the format of 2018-09-06T15:33:56.750
  • DateTimeFormatter: Date and time formatting class.
  • Instant: timestamp, representing a specific moment in time.
  • Duration: used to calculate the distance between two times (LocalTime, hours, minutes and seconds)
  • Period: used to calculate the distance between two dates (LocalDate, year, month and day)
  • ZonedDateTime: time containing time zone

The calendar used in Java is the ISO 8601 calendar system, which is the world's civil calendar, which is what we call the Gregorian calendar. There are 365 days in an ordinary 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: Calendar of the Republic of China
  • JapaneseDate: Japanese calendar
  • HijrahDate: Islamic calendar

Common operations on date and time

LocalDate operations:

    /**
     * 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());
    }

LocalTime operations:

    /**
     * 时间操作
     */
    @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 operations:

    /**
     * 日期时间类型  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());
    }

Date and time modification and comparison

Date and time modification:

    /**
     * 
     */
    @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));
    }

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 multi-threaded scenarios.

Date and time comparison

    /**
     * 
     */
    @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
    }

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);
    }

Instant class

A new Instant class (timestamp/timeline) is added to us in JDK8, which internally stores seconds and nanoseconds since 00:00:00 on January 1, 1970, which can be used to count time consumption.

    /**
     * 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()));

    }

Calculate date time difference

JDK8 provides two tool classes Duration/Period: calculating date and time difference

  1. Duration: used to calculate the difference between two times (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
    }

time corrector

Sometimes we may need to make the following adjustments: adjust the date to "the first day of the next month" and other operations. At this time, the effect may be better through the time corrector.

  • TemporalAdjuster: Time corrector
  • TemporalAdjusters: A large number of commonly used TemporalAdjuster implementations are provided through the static methods of this class.
    /**
     * 时间校正器
     */
    @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;
        };
        // LocalDateTime nextMonth = now.with(adJuster);
        // TemporalAdjusters 实现
        LocalDateTime nextMonth = now.with(TemporalAdjusters.firstDayOfNextMonth());
        System.out.println("nextMonth = " + nextMonth);
    }

date time time zone

Java8 has added support for time zones. LocalDate, LocalTime, and LocalDateTime do not have time zones. The date and time classes with time zones are: ZonedDate, ZonedTime, and ZonedDateTime. Each time zone corresponds to an ID, in the format of "region/city". For example: Asia/Shanghai, etc. ZoneId 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 the new date and time API

  1. In the new version of the date and time API, date and time objects are immutable. Operating dates will not affect the original values, but generate a new instance, so they are thread-safe.
  2. Provide two different methods to effectively distinguish between human and machine operations.
  3. TemporalAdjuster can operate dates more accurately and can also customize the date adjustment period.

Guess you like

Origin blog.csdn.net/qq_28314431/article/details/132907363