Problems with older datetime apis

  1. Poor design: There are Date classes in both java.util and java.sql packages. Java.util.Date contains both Date and time, while java.sql. In addition, classes for formatting and parsing are defined in the java.text package.

  2. Non-thread-safe: Java.util. Date is non-thread-safe, and all Date classes are mutable, which is one of the biggest problems with Java Date classes.

  3. Calendar and Java.util.TimeZone classes are introduced, but they suffer from all of the problems mentioned above.

           /** * 1
            Date now = new Date(1985.9.23);
            System.out.println(now);
    
            /** * Thread is not complete */
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            for (int i = 0; i < 50; i++) {
                new Thread(() -> {
                    Date date = null;
                    try {
                        date = sdf.parse("2020-09-09");
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    System.out.println(date);
                });
            }
    Copy the code

The output

Connected to the target VM, address: '127.0.0.1:60324', transport: 'socket'
  Fri Oct 23 00:00:00 CST 3885
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Thu Sep 09 00:00:00 CST 2202
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  date=Wed Sep 09 00:00:00 CST 2020
  Exception in thread "Thread-40" java.lang.NumberFormatException: For input string: ""
  	at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
  	at java.lang.Long.parseLong(Long.java:601)
  	at java.lang.Long.parseLong(Long.java:631)
  	at java.text.DigitList.getLong(DigitList.java:195)
  	at java.text.DecimalFormat.parse(DecimalFormat.java:2051)
  	at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)
  	at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
  	at java.text.DateFormat.parse(DateFormat.java:364)
  	at com.example.jdk.demo07datetime.Test01.lambda$main$0(Test01.java:23)
  	at java.lang.Thread.run(Thread.java:748)
  Disconnected from the target VM, address: '127.0.0.1:60324', transport: 'socket'
  
  Process finished with exit code 0
  
Copy the code

New date and time API introduction

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

LocalDate: indicates the date in the format of 2019-10-19

LocalTime: indicates the time, including the hour, minute and second. The format is 16:53:33.143423434

LocalDateTime: indicates the date and time, including year, month, day, hour, minute and second in the format of 2018-10-12T15:12:13.234

DateTimeFormater: Format the date and time

Instant: timestamp: indicates a specific Instant in time

Duration: Used to calculate the interval between two times (LocalTime)

Period: Calculates the interval between two dates (LocalDate, month, year, day)

ZoneDateTime: time including the time zone

Date and time classes in JDK 8

Instances of the LocalDate, LocalTime, and LocalDateTime classes are immutable objects that represent the date, time, date, and time using the ISO-8601 calendar system, respectively. They provide simple dates and times that do not contain current date information or time zone specific information

 public static void testLocalDate(a) {
        // The current date
        LocalDate now = LocalDate.now();
        System.out.println(now);
        // Specify a date
        LocalDate date = LocalDate.of(2018.12.12);
        System.out.println(date);
        // Get the specified date
        System.out.println("year= " + now.getYear());
        System.out.println("month= " + now.getMonthValue());
        System.out.println("date= " + now.getDayOfMonth());

    }

    public static void testLocalTime(a) {
        //LocalTime indicates the time, sometimes minutes and seconds
        // The current time
        LocalTime nowTime =LocalTime.now();
        System.out.println(nowTime);

        // specify a time
        LocalTime localTime =LocalTime.of(13.22.34);
        System.out.println(localTime);

        // Get the time
        System.out.println(nowTime.getHour());
        System.out.println(nowTime.getMinute());
        System.out.println(nowTime.getSecond());
        System.out.println(nowTime.getNano());
    }

    public static void testLocalDateTime(a) {
        //LocalDateTime LocalDate+LocalTime, with year, month, day, hour, minute, second
        // The current time
        LocalDateTime nowDateTime =LocalDateTime.now();
        System.out.println(nowDateTime);

        // specify a time
        LocalDateTime localTime =LocalDateTime.of(2018.7.23.13.22.34);
        System.out.println(localTime);

        // Get the time
        System.out.println("year= " + nowDateTime.getYear());
        System.out.println("year= " + nowDateTime.getMonthValue());
        System.out.println("date= " + nowDateTime.getDayOfMonth());
        System.out.println(nowDateTime.getHour());
        System.out.println(nowDateTime.getMinute());
        System.out.println(nowDateTime.getSecond());
        System.out.println(nowDateTime.getNano());
    }

    /** * Change the time */
    @Test
    public void editLocalDateTime(a){
        LocalDateTime nowDateTime =LocalDateTime.now();
        // Return the new time after modification
        LocalDateTime localDateTime = nowDateTime.withYear(9102);
        System.out.println("nowDateTime= " + nowDateTime);
        System.out.println("localDateTime= " + localDateTime);

        // Add year: plus
        LocalDateTime plusYears = nowDateTime.plusYears(2);
        System.out.println("years+2 ="+plusYears);
        // Minus year: minus
        LocalDateTime minusYears = nowDateTime.minusYears(2);
        System.out.println("years-2 ="+minusYears);

    }

    /** ** compare time */
    @Test
    public void compareLocalDateTime(a){
        LocalDateTime nowDateTime =LocalDateTime.now();
        LocalDateTime localTime =LocalDateTime.of(2018.7.23.13.22.34);

        System.out.println(nowDateTime.isAfter(localTime));
        System.out.println(nowDateTime.isBefore(localTime));
        System.out.println(nowDateTime.isEqual(localTime)); 
    }
Copy the code

Time formatting and parsing of dates

Through the Java. Time. The format. DateTimeFormater class date/time parsing and formatting

   /**
     * 日期格式化
     */
    @Test
    public void formatLocalDateTime(a){
        LocalDateTime nowDateTime =LocalDateTime.now();
       // format, specify the time format, JDK built-in format
        DateTimeFormatter isoDateTime = DateTimeFormatter.ISO_DATE_TIME;
        String format = nowDateTime.format(isoDateTime);
        System.out.println(format);
        // Specify the format
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        System.out.println(dateTimeFormatter);

        / / parsing
        LocalDateTime parse = LocalDateTime.parse("The 2017-09-09 15:13:23",dateTimeFormatter);
        System.out.println(parse);
        for (int i = 0; i < 50; i++) {
            new Thread(()->{
                LocalDateTime parse2 = LocalDateTime.parse("The 2017-09-09 15:13:23",dateTimeFormatter);
                System.out.println("parse2 ="+parse2); }).start(); }}Copy the code

The Instant JDK8 class

Instant timestamps/timelines that internally preserve seconds and nanoseconds since 00:00:00 on January 1, 1970

 /** * get second/nanosecond */
    @Test
    public void testInstant(a){
        // Instant saves seconds and nanoseconds internally, generally not for user use, but convenient for our program to do some statistics
        Instant now = Instant.now();
        System.out.println(now);
        / / increase the seconds
        Instant plus = now.plusSeconds(20);
        / / reduce the seconds
        Instant minus = now.minusSeconds(120);
        // Get seconds/nanoseconds
        System.out.println(now.getEpochSecond());
        System.out.println(now.getNano());
    }
Copy the code

JDK8 calculates the date time difference class

Duration/Period class: calculates the date time difference

  1. Duration: Used to calculate the interval between two localtimes (minutes, seconds)

  2. Period: calculates the distance between two dates (LocalDate, month, year, day)

@Test
    public void testDuration(a){
        //Duration Interval for computing time
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime localTime =LocalDateTime.of(2018.7.23.13.22.34);
        Duration duration = Duration.between(now, localTime);
        System.out.println("Difference of days :" + duration.toDays());
        System.out.println("Difference in hours :" + duration.toHours());
        System.out.println("Difference in minutes :" + duration.toMinutes());
        System.out.println("Difference in seconds :" + duration.toMillis());

        //pperiod Date Interval of the date
        LocalDate now1 = LocalDate.now();
        LocalDate localDate = LocalDate.of(2018.12.12);
        //between subtracts the previous time from the latter
        Period period = Period.between(localDate, now1);
        System.out.println("Difference in years :" + period.getYears());
        System.out.println("Month difference :" + period.getMonths());
        System.out.println("Difference of days :" + period.getDays());
    }
Copy the code

Time corrector in JDK8

Sometimes we may need to get operations such as adjusting the date to “the first day of the next month”. This can be done with a time corrector

  • TemporalAdjuster: Time adjuster
  • TemporalAdjusters: This class provides a large number of commonly used TemporalAdjusters implementations through a static approach
@Test
    public void testTemporalAdjuster(a){
        // Change the date to the first day of the following month
        LocalDateTime now = LocalDateTime.now();
        LocalDateTime with = now.with(TemporalAdjusters.firstDayOfMonth());
        System.out.println(with);
    }
Copy the code

Set the time zone for the date and time

Java8 supports time zones. LocalDate, LocalTime, and LocalDateTime do not contain time zones. The date and time classes with time zones are ZonedDate, ZonedTime, and ZonedDateTime

Each time zone corresponds to an ID. The ID is in the format of “region/city”, for example, Asia/ShangHai

ZoneId: This class contains all time zone information.

@Test
    public void testZonedDate(a){
        // Get all time zone ids
        ZoneId.getAvailableZoneIds().forEach(System.out::println);

        // No time zone
        LocalDateTime now = LocalDateTime.now();
        System.out.println("now: "+now);
        
        // Standard world time with time zone
        ZonedDateTime zonedDateTime = ZonedDateTime.now(Clock.systemUTC());
        System.out.println("zonedDateTime: "+zonedDateTime);

        //now(): Use the computer's default time zone
        ZonedDateTime zonedDateTime2 = ZonedDateTime.now();
        System.out.println("zonedDateTime2: "+zonedDateTime2);

        // Specifies the time when the time zone was created
        ZonedDateTime zonedDateTime3 = ZonedDateTime.now(ZoneId.of("America/Vancouver"));
        System.out.println("zonedDateTime3: "+zonedDateTime3);

        // Change the time zone and time
        ZonedDateTime withZoneSameInstant = zonedDateTime2.withZoneSameInstant(ZoneId.of("Asia/ShangHai"));
        System.out.println("withZoneSameInstant: "+withZoneSameInstant);

        // Change the time zone but not the time
        ZonedDateTime withZoneSameLocal = zonedDateTime2.withZoneSameLocal(ZoneId.of("Asia/ShangHai"));
        System.out.println("withZoneSameLocal: "+withZoneSameLocal);
    }
Copy the code