preface

As a matter of fact, Java8 did not pay much attention to the Date API. For example, the popular Date class was not included in a special package, and SimpleDateFormat, a popular Date formatting utility class, was included in the java.text package.

Even SimpleDateFormat may cause an exception in the case of multithreaded access, the JDK does this If Multiple Threads Access a format concurrently, it must be synchronized.

The methods for manipulating dates in these classes are also confusing and hard to master, and many of the methods are outdated.

The world has long been bitter old! (No wonder I didn’t do well in this area before. There was a reason.)

After Java8, it’s much easier to manipulate dates. Let’s take a look.

Date/time

There are three common classes for dates and times:

  • LocalDateTime: indicates the default date format, YYYY-MM-DD HH: MM :ss.fff
  • LocalDate: yyyy – MM – dd
  • The LocalTime: HH: mm: ss. FFF

LocalDateTime = LocalDate + LocalTime

LocalDate is the year, month and day class

LocalTime is the time, minute and second class

It should be noted that the default time zone of these three classes is the local time zone (the default time zone of the system). Due to different geographical locations, the time expression is also different. Currently, The time zone of Shanghai, Asia/Shanghai, is used in China

From LocalDateTime, you can easily obtain LocalDate and LocalTime

LocalDateTime now = LocalDateTime.now();
LocalDate localDate = now.toLocalDate();
LocalTime localTime = now.toLocalTime();
Copy the code

LocalDate can also be converted to LocalDateTime by adding LocalTime

LocalDateTime localDateTime = localDate.atTime(localTime);
Copy the code

The LocalTime versa

LocalDateTime localDateTime = localTime.atDate(localDate);
Copy the code

The methods of the three date classes are similar. Here is an example of LocalDateTime

LocalDateTime now = LocalDateTime.now();
System.out.println("You can also specify a time:" + LocalDateTime.of(2020.4.15.9.30.2));

System.out.println("Current moment:" + now);
System.out.println(Current year: + now.getYear());
System.out.println("Current month:" + now.getMonthValue());
System.out.println("Current date:" + now.getDayOfMonth());
System.out.println("Present tense:" + now.getHour());
System.out.println("Current minute:" + now.getMinute());
System.out.println("Current second:" + now.getSecond());

System.out.println("Plus 2 years:" + now.plusYears(2l));
System.out.println("Minus 3 months:" + now.minusMonths(3l));
System.out.println("Minus 50 days:" + now.minusDays(50l));
System.out.println("Basically realize socialist modernization by 2035." + now.withYear(2035));
System.out.println("Each calculation will return a new object, the original object is not affected." + now);
Copy the code

These simple API calls you know, have an impression, when coding, there are code prompts, programming obstacles are relatively small. And date, time, timestamp mutual conversion and formatting, is the focus, this aspect is not familiar with, will cause a relatively large programming obstacles.

The time zone

Java8 provides the ZoneId to identify the time zone used by each country

You can use the systemDefault() method to get the default time zone for the current system, such as Asia/Shanghai

ZoneId zoneId = ZoneId.systemDefault();
Copy the code

Get all time zones

Set<String> zoneIds = ZoneId.getAvailableZoneIds();
Copy the code

Gets the time zone object based on the time zone name

ZoneId zoneId = ZoneId.of("Asia/Shanghai");
Copy the code

Date time with time zone, ZonedDateTime, which differs from LocalDateTime by adding the time zone at the end. There is no derivative ZonedDate or ZonedTime.

For example, get the date and time with the current time zone and print it

System.out.println(ZonedDateTime.now());
Copy the code

Print result:

2020-07-07T15:17:23.737+ 08:00[Asia/Shanghai]
Copy the code

The time stamp

The time stamp in the computer refers to the total number of seconds from 00 00 00 00 00 GMT on 01 01 1970 to the present day.

Timestamps are represented by Instant classes

Timestamp of Unix year 1

Instant.EPOCH
Copy the code

Gets the current timestamp

Instant now = Instant.now();
Copy the code

Convert the timestamp to the total number of seconds

long second = now.getEpochSecond();
Copy the code

Convert the time to the total millisecond value

long second = now.toEpochMilli();
Copy the code

GetEpochSecond (); toEpochMilli(); toEpochMilli()

The timestamp generates LocalDateTime with the time zone

Instant now = Instant.now();
LocalDateTime dateTime = LocalDateTime.ofInstant(now, ZoneId.systemDefault());
Copy the code

Sample diagram of the transformation

formatting

DateTimeFormatter is the latest date formatter class that provides a number of predefined time formats, in contrast to SimpleDateFormat, which was previously used for formatting.

Using LocalDateTime as an example, here are some simple date-time formatting operations:

LocalDateTime now = LocalDateTime.now();
System.out.println("yyyy-MM-dd HH:mm:ss.fff : " + now.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
System.out.println("yyyy-MM-dd : " + now.format(DateTimeFormatter.ISO_LOCAL_DATE));
System.out.println("HH:mm:ss.fff : " + now.format(DateTimeFormatter.ISO_LOCAL_TIME));
// Custom formatting
System.out.println(now.format(DateTimeFormatter.ofPattern("Yyyy yyyy MM dd day HH: MM :ss")));
Copy the code

Print result:

yyyy-MM-dd HH:mm:ss.fff : 2020-07-07T19:21:24.728 // No formatting
yyyy-MM-dd : 2020-07-07
HH:mm:ss.fff : 19:21:24.728
2020years07month07day19:21:24
Copy the code

You can see it up here

ISO_LOCAL_DATE_TIME = ISO_LOCAL_DATE + ISO_LOCAL_TIME, where ISO refers to the abbreviation of the International Organization for Standardization

The DateTimeFormatter can also format timestamps, although it is important to note that a time zone must be specified; without a time zone, the formatter will not know how to instantly convert to a human date-time field, so an exception will be thrown.

Sample code:

DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME.withZone(ZoneId.systemDefault());
System.out.println(formatter.format(Instant.now()));
Copy the code

Print result:

2020-07-07T19:42:28.805
Copy the code

The timestamp custom formatting is the same as LocalDateTime above, but more detail.

Period of time

Duration (Duration); Duration (Duration); Duration (Duration);

  • Duration: time seconds minutes
  • Period: year month day

The methods of both classes are similar, which we demonstrate with Duration:

Get the time period between current and future time:

LocalTime now = LocalTime.now();
LocalTime hour = now.plusHours(2);
LocalTime minute = now.plusMinutes(10);
LocalTime second = now.plusSeconds(30);
System.out.println(Duration.between(now, hour));
System.out.println(Duration.between(now, minute));
System.out.println(Duration.between(now, second));
Copy the code

Print result:

PT2H
PT10M
PT30S
Copy the code

Note that the default printed result is in the ISO date format, where H in PT2H stands for Hour, M for Minute, and S for Second

Other example operations:

LocalTime now = LocalTime.now();
LocalTime hour = now.plusHours(2);
Duration duration = Duration.between(now, hour);
System.out.println("The number of seconds to get the time range:" + duration.getSeconds());
System.out.println("Get the number of milliseconds for the time period:" +duration.toMillis());
System.out.println("Number of days to obtain time range:" +duration.toDays());
Copy the code

Print result:

The number of seconds to get the period:7200Get the number of milliseconds for the time period:7200000Number of days to obtain a time range:0
Copy the code

The Duration class also has related methods for adding and subtracting minutes and seconds, but I won’t go into detail here.

regulator

LocalDateTime, Duration, Instant, etc., although many methods of adding and subtracting dates have been provided, they are still relatively limited, and it is difficult to meet the needs of the next Sunday and the next wedding birthday.

To do that, we can use a modifier to adjust the date.

The date adjuster class is TemporalAdjuster, which is an interface. Java8 also provides a tool class for implementing TemporalAdjusters. The use of TemporalAdjusters is as follows:

LocalDateTime now = LocalDateTime.now();
System.out.println("Current time :"+now);
System.out.println("Next Sunday :" + now.with(TemporalAdjusters.next(DayOfWeek.SUNDAY)));
System.out.println("First day of next month :" + now.with(TemporalAdjusters.firstDayOfNextMonth()));
System.out.println("Next business day :" + now.with(l -> {
    LocalDateTime dateTime = (LocalDateTime) l;
    // Get the day of the week
    DayOfWeek dayOfWeek = dateTime.getDayOfWeek();
    if (DayOfWeek.FRIDAY.equals(dayOfWeek)){
        // Friday plus three days equals working days
        return dateTime.plusDays(3);
    }else if(DayOfWeek.SATURDAY.equals(dayOfWeek)){
        Saturday plus two days
        return dateTime.plusDays(2);
    }
    // Add one day for everything else
    return dateTime.plusDays(1);
}));
Copy the code

Print result:

Current time:2020-07-08T00:10:05.549Next Sunday:2020-07-12T00:10:05.549First day of next month:2020-08-01T00:10:05.549Next working day:2020-07-09T00:10:05.549
Copy the code

The DayOfWeek class has seven constant values from MONDAY to Sunday, such as MONDAY,TUESDAY,WEDNESDAY, and so on.

The Date conversion

The Date class currently has many outdated and unrecommended methods that you might consider replacing if you use it in your project.

The new Date API can use the timestamp millisecond value to new a Date object through the Date class constructor

As follows:

long milli = Instant.now().toEpochMilli();
Date date = new Date(milli);
Copy the code

Pay special attention! This constructor passes values in milliseconds

Date can be converted to a timestamp using the toInstant method

Instant instant = new Date().toInstant();
Copy the code