[Deep thinking] How should date types be used in JDK8?

Keywords: Java less

Prior to JDK8, we used three main classes for processing date and time, Date, SimpleDateFormat, and Calendar.

These three classes have some problems when they are used more or less, such as SimpleDateFormat is not thread safe.

For example, the months Date and Calendar get are from 0 to 11, not from 1 to 12 in real life, which is also mentioned in the Alibaba Java Development Manual because it is easy to make mistakes:

However, JDK8 has introduced new date-time processing classes to address these issues, such as Instant, LocalDate, LocalTime, LocalDateTime, DateTimeFormatter, which are also recommended in the Alibaba Java Development Manual.

LocalDateTime,DateTimeFormatter:

However, I find that many projects do not actually use these classes. They still use the previous Date, SimpleDateFormat, and Calendar. So this blog explains the new Date and time classes introduced by JDK8, mainly the following:

  1. Instant
  2. LocalDate
  3. LocalTime
  4. LocalDateTime
  5. DateTimeFormatter

1. Instant

1.1 Get the current time

Now that Instant can replace the Date class, it certainly gets the current time:

Instant instant = Instant.now();
System.out.println(instant);

Output results:

2020-06-10T08:22:13.759Z

Carefully, you will find that this time is 8 hours less than Beijing time. If you want to export Beijing time, you can add the default time zone:

System.out.println(instant.atZone(ZoneId.systemDefault()));

Output results:

2020-06-10T16:22:13.759+08:00[Asia/Shanghai]

1.2 Get Timestamp

Instant instant = Instant.now();

// Current timestamp: in seconds
System.out.println(instant.getEpochSecond());
// Current timestamp: in milliseconds
System.out.println(instant.toEpochMilli());

Output results:

1591777752

1591777752613

Of course, you can also use System.currentTimeMillis() Get the current number of milliseconds.

1.3 Convert long to Instant

1) Time stamp conversion based on seconds:

Instant instant = Instant.now();
System.out.println(instant);

long epochSecond = instant.getEpochSecond();
System.out.println(Instant.ofEpochSecond(epochSecond));
System.out.println(Instant.ofEpochSecond(epochSecond, instant.getNano()));

Output results:

2020-06-10T08:40:54.046Z

2020-06-10T08:40:54Z

2020-06-10T08:40:54.046Z

2) Time stamp conversion based on milliseconds:

Instant instant = Instant.now();
System.out.println(instant);

long epochMilli = instant.toEpochMilli();
System.out.println(Instant.ofEpochMilli(epochMilli));

Output results:

2020-06-10T08:43:25.607Z

2020-06-10T08:43:25.607Z

1.4 Convert String to Instant

String text = "2020-06-10T08:46:55.967Z";
Instant parseInstant = Instant.parse(text);
System.out.println("Seconds timestamp:" + parseInstant.getEpochSecond());
System.out.println("Hausage Time Stamp:" + parseInstant.toEpochMilli());
System.out.println("nanosecond:" + parseInstant.getNano());

Output results:

Seconds timestamp: 1591778815

Hausage time stamp: 1591778815967

Nanoseconds: 967000000

If the string is not in the correct format, such as 2020-06-10T08:46:55.967, it will be thrownJava.time.formatThe.DateTimeParseException exception is as follows:

2. LocalDate

2.1 Get the current date

Getting the current date using LocalDate is straightforward, as follows:

LocalDate today = LocalDate.now();
System.out.println("today: " + today);

Output results:

today: 2020-06-10

Without any formatting, the output will be very friendly. If you use Date, it will also be formatted with SimpleDateFormat specifying yyyy-MM-dd, and there will be a bug, such as a bug that was very hot at the end of last year, which I captured at that time:

These two friends were interested in me on December 31, 2019, but when I checked them on January 2, 2020, they turned out to be 2020/12/31. Why?Wrong formatting was used when formatting the date. It should be yyyy/MM/dd, but it was written as YYYY/MM/dd. Just over that week, it will show up as the next year, that is, 2020. Several bloggers wrote articles at that time to explain the reason. I will not explain much here.

Emphasis: All of this is said, give everyone my newly registered public name "Shencheng Aliens". Welcome to your attention. More original articles are waiting for you, oh, haha.

2.2 Get Year, Month and Day

LocalDate today = LocalDate.now();

int year = today.getYear();
int month = today.getMonthValue();
int day = today.getDayOfMonth();

System.out.println("year: " + year);
System.out.println("month: " + month);
System.out.println("day: " + day);

Output results:

year: 2020

month: 6

day: 10

The month of acquisition finally returned 1 to 12, unlikeJava.util.CalendarGetting the month returns 0 to 11, plus 1.

2.3 Specified date

LocalDate specifiedDate = LocalDate.of(2020, 6, 1);
System.out.println("specifiedDate: " + specifiedDate);

Output results:

specifiedDate: 2020-06-01

If a month is determined, another overload method is recommended, using enumeration to specify the month:

LocalDate specifiedDate = LocalDate.of(2020, Month.JUNE, 1);

2.4 Compare equal dates

LocalDate localDate1 = LocalDate.now();
LocalDate localDate2 = LocalDate.of(2020, 6, 10);
if (localDate1.equals(localDate2)) {
    System.out.println("localDate1 equals localDate2");
}

Output results:

localDate1 equals localDate2

2.5 Acquisition date is the day of the week/month/year

LocalDate today = LocalDate.now();

System.out.println("Today:" + today);
System.out.println("Today is:" + today.getDayOfWeek());
System.out.println("Today is the day of the week" + today.getDayOfWeek().getValue() + "day");
System.out.println("Today is the day of the month" + today.getDayOfMonth() + "day");
System.out.println("Today is the year" + today.getDayOfYear() + "day");

Output results:

Today:2020-06-11

Today is:THURSDAY

Today is the fourth day of the week

Today is the 11th day of the month

Today is 163 days of the year

2.6 Judging whether it is a leap year

LocalDate today = LocalDate.now();

System.out.println(today.getYear() + " is leap year:" + today.isLeapYear());

Output results:

2020 is leap year:true

3. LocalTime

3.1 Get Hours and Seconds

If usedJava.util.DateThe code is as follows:

Date date = new Date();

int hour = date.getHours();
int minute = date.getMinutes();
int second = date.getSeconds();

System.out.println("hour: " + hour);
System.out.println("minute: " + minute);
System.out.println("second: " + second);

Output results:

Note: These methods are out of date and are therefore strongly discouraged from being used in projects:

If usedJava.util.CalendarThe code is as follows:

Calendar calendar = Calendar.getInstance();

// 12-hour system
int hourOf12 = calendar.get(Calendar.HOUR);
// 24-hour system
int hourOf24 = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
int milliSecond = calendar.get(Calendar.MILLISECOND);

System.out.println("hourOf12: " + hourOf12);
System.out.println("hourOf24: " + hourOf24);
System.out.println("minute: " + minute);
System.out.println("second: " + second);
System.out.println("milliSecond: " + milliSecond);

Output results:

**IMPORTANT:** When getting hours, there are two options, one to return 12-hour hours and one to return 24-hour hours, because it is 8 p.m., soCalendar.get(Calendar.HOUR) returns 8, whileCalendar.get(Calendar.HOUR_OF_DAY) returns 20.

If usedJava.time.LocalTimeThe code is as follows:

LocalTime localTime = LocalTime.now();
System.out.println("localTime:" + localTime);

int hour = localTime.getHour();
int minute = localTime.getMinute();
int second = localTime.getSecond();

System.out.println("hour: " + hour);
System.out.println("minute: " + minute);
System.out.println("second: " + second);

Output results:

You can see that LocalTime only has time and no date.

4. LocalDateTime

4.1 Get the current time

LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime:" + localDateTime);

Output results:

localDateTime: 2020-06-11T11:03:21.376

4.2 Get years, months, days, minutes, seconds

LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime: " + localDateTime);

System.out.println("year: " + localDateTime.getYear());
System.out.println("month: " + localDateTime.getMonthValue());
System.out.println("day: " + localDateTime.getDayOfMonth());
System.out.println("hour: " + localDateTime.getHour());
System.out.println("minute: " + localDateTime.getMinute());
System.out.println("second: " + localDateTime.getSecond());

Output results:

4.3 Increase days/hours

LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime: " + localDateTime);

LocalDateTime tomorrow = localDateTime.plusDays(1);
System.out.println("tomorrow: " + tomorrow);

LocalDateTime nextHour = localDateTime.plusHours(1);
System.out.println("nextHour: " + nextHour);

Output results:

localDateTime: 2020-06-11T11:13:44.979

tomorrow: 2020-06-12T11:13:44.979

nextHour: 2020-06-11T12:13:44.979

LocalDateTime also provides ways to add years, weeks, minutes, seconds, which are not listed here:

4.4 Reduce days/hours

LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime: " + localDateTime);

LocalDateTime yesterday = localDateTime.minusDays(1);
System.out.println("yesterday: " + yesterday);

LocalDateTime lastHour = localDateTime.minusHours(1);
System.out.println("lastHour: " + lastHour);

Output results:

localDateTime: 2020-06-11T11:20:38.896

yesterday: 2020-06-10T11:20:38.896

lastHour: 2020-06-11T10:20:38.896

Similarly, LocalDateTime offers ways to reduce years, weeks, minutes, seconds, which are not listed here:

4.5 Availability date is the day of the week/year

LocalDateTime localDateTime = LocalDateTime.now();
System.out.println("localDateTime: " + localDateTime);

System.out.println("DayOfWeek: " + localDateTime.getDayOfWeek().getValue());
System.out.println("DayOfYear: " + localDateTime.getDayOfYear());

Output results:

localDateTime: 2020-06-11T11:32:31.731

DayOfWeek: 4

DayOfYear: 163

5. DateTimeFormatter

Launched in JDK8 Java.time.formatDateTimeFormatter handles date formatting, and the Alibaba Java Development Manual also recommends using DateTimeFormatter instead of SimpleDateFormat.

5.1 Format LocalDate

LocalDate localDate = LocalDate.now();

System.out.println("ISO_DATE: " + localDate.format(DateTimeFormatter.ISO_DATE));
System.out.println("BASIC_ISO_DATE: " + localDate.format(DateTimeFormatter.BASIC_ISO_DATE));
System.out.println("ISO_WEEK_DATE: " + localDate.format(DateTimeFormatter.ISO_WEEK_DATE));
System.out.println("ISO_ORDINAL_DATE: " + localDate.format(DateTimeFormatter.ISO_ORDINAL_DATE));

Output results:

If the format provided does not meet your needs, you can also customize the format as before:

LocalDate localDate = LocalDate.now();

System.out.println("yyyy/MM/dd: " + localDate.format(DateTimeFormatter.ofPattern("yyyy/MM/dd")));

Output results:

yyyy/MM/dd: 2020/06/11

5.2 Format LocalTime

LocalTime localTime = LocalTime.now();
System.out.println(localTime);
System.out.println("ISO_TIME: " + localTime.format(DateTimeFormatter.ISO_TIME));
System.out.println("HH:mm:ss: " + localTime.format(DateTimeFormatter.ofPattern("HH:mm:ss")));

Output results:

14:28:35.230

ISO_TIME: 14:28:35.23

HH:mm:ss: 14:28:35

5.3 Format LocalDateTime

LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime);
System.out.println("ISO_DATE_TIME: " + localDateTime.format(DateTimeFormatter.ISO_DATE_TIME));
System.out.println("ISO_DATE: " + localDateTime.format(DateTimeFormatter.ISO_DATE));

Output results:

2020-06-11T14:33:18.303

ISO_DATE_TIME: 2020-06-11T14:33:18.303

ISO_DATE: 2020-06-11

6. Type Conversion

6.1 Instant to Date

In JDK8, Date added the from() method, which converts Instant to Date with the following code:

Instant instant = Instant.now();
System.out.println(instant);

Date dateFromInstant = Date.from(instant);
System.out.println(dateFromInstant);

Output results:

2020-06-11T06:39:34.979Z

Thu Jun 11 14:39:34 CST 2020

6.2 Date to Instant

In JDK8, Date added the toInstant method, which converts Date to Instant with the following code:

Date date = new Date();
Instant dateToInstant = date.toInstant();
System.out.println(date);
System.out.println(dateToInstant);

Output results:

Thu Jun 11 14:46:12 CST 2020

2020-06-11T06:46:12.112Z

6.3 Date to LocalDateTime

Date date = new Date();
Instant instant = date.toInstant();
LocalDateTime localDateTimeOfInstant = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
System.out.println(date);
System.out.println(localDateTimeOfInstant);

Output results:

Thu Jun 11 14:51:07 CST 2020

2020-06-11T14:51:07.904

6.4 Date to LocalDate

Date date = new Date();
Instant instant = date.toInstant();
LocalDateTime localDateTimeOfInstant = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
LocalDate localDate = localDateTimeOfInstant.toLocalDate();
System.out.println(date);
System.out.println(localDate);

Output results:

Thu Jun 11 14:59:38 CST 2020

2020-06-11

You can see that Date is converted to Instant, then to LocalDateTime, and then to get LocalDate from LocalDateTime.

6.5 Date to LocalTime

Date date = new Date();
Instant instant = date.toInstant();
LocalDateTime localDateTimeOfInstant = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
LocalTime toLocalTime = localDateTimeOfInstant.toLocalTime();
System.out.println(date);
System.out.println(toLocalTime);

Output results:

Thu Jun 11 15:06:14 CST 2020

15:06:14.531

You can see that Date is converted to Instant, then to LocalDateTime, and then to get LocalTime from LocalDateTime.

6.6 LocalDateTime to Date

LocalDateTime localDateTime = LocalDateTime.now();

Instant toInstant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
Date dateFromInstant = Date.from(toInstant);
System.out.println(localDateTime);
System.out.println(dateFromInstant);

Output results:

2020-06-11T15:12:11.600

Thu Jun 11 15:12:11 CST 2020

6.7 LocalDate to Date

LocalDate today = LocalDate.now();

LocalDateTime localDateTime = localDate.atStartOfDay();
Instant toInstant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
Date dateFromLocalDate = Date.from(toInstant);
System.out.println(dateFromLocalDate);

Output results:

Thu Jun 11 00:00:00 CST 2020

6.8 LocalTime to Date

LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();

LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime);
Instant instantFromLocalTime = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
Date dateFromLocalTime = Date.from(instantFromLocalTime);

System.out.println(dateFromLocalTime);

Output results:

Thu Jun 11 15:24:18 CST 2020

7. Summary

JDK8 introduced new date-time classes, such as Instant, LocaleDate, LocalTime, LocalDateTime, DateTimeFormatter, which are more reasonably designed and thread-safe than before.

The Alibaba Java Development Specification also recommends Instant instead of Date, LocalDateTime instead of Calendar, and DateTimeFormatter instead of SimpleDateFormat.

Therefore, if conditions permit, it is recommended to use in the project, if not, you can consider upgrading.

Note: If you feel there are any errors or better suggestions in this blog, please leave a message, and I will follow up and correct the blog content in time!

The article is continuously updated. Welcome to read the WeChat Public Number "Shencheng Foreigners" for the first time!

Posted by webpals on Thu, 11 Jun 2020 18:59:37 -0700