Java 8 time and date API

In the previous article "Java Time and Date API", we learned the "traditional time and date API" composed of Date, Calendar, DateFormat, etc., but the traditional processing interface design is not very friendly and difficult to use. Finally, Java 8 has redesigned a set of APIs with reference to the excellent third-party open source library Joda-time.

So in this article, we will simply learn about the new time and date processing interface.

Instant representing the moment

Like Date, Instant represents a timestamp and is used to describe a moment, but it can describe a more precise moment than Date. And Instant is timezone independent.

Date can represent up to millisecond moments, while Instant can represent nanosecond moments. E.g:

  • public static Instant now(): Create an Instant instance based on the current time of the system, representing the current moment
  • public static Instant ofEpochSecond(long epochSecond): Build an Instant instance by passing in a standard time offset value
  • public static Instant ofEpochMilli(long epochMilli): Constructs an Instant instance directly from the millisecond value

Take a look at the code:

public static void main(String[] args){
    //创建 Instant 实例
    Instant instant = Instant.now();
    System.out.println(instant);

    Instant instant1 = Instant.ofEpochSecond(20);
    System.out.println(instant1);

    Instant instant2 = Instant.ofEpochSecond(30,100);
    System.out.println(instant2);

    Instant instant3 = Instant.ofEpochMilli(1000);
    System.out.println(instant3);
}

Output result:

2018-04-23T02:43:10.973Z
1970-01-01T00:00:20Z
1970-01-01T00:00:30.000000100Z
1970-01-01T00:00:01Z

It can be seen that the difference between Instant and Date is that it is time zone independent, and is always related to Green zero time zone, that is, the output result is always Green zero time zone time.

LocalDate that handles dates

Unlike Calendar, which can handle both dates and times, java.time's modern API separates date and time and handles them in separate classes. LocalDate focuses on handling date-related information.

LocalDate is still an immutable class, it pays attention to the year, month and day part of the time. We can construct and initialize a LocalDate instance by the following methods:

  • public static LocalDate now(): truncate the year-month-day information of the current system time and initialize an instance object
  • public static LocalDate of(int year, int month, int dayOfMonth): Explicitly specify the year-month-day information
  • public static LocalDate ofYearDay(int year, int dayOfYear): month and dayOfMonth can be derived from dayOfYear
  • public static LocalDate ofEpochDay(long epochDay): The day offset relative to the Green Zero time zone time

Take a look at the code:

public static void main(String[] args){
    //构建 LocalDate 实例
    LocalDate localDate = LocalDate.now();
    System.out.println(localDate);

    LocalDate localDate1 = LocalDate.of(2017,7,22);
    System.out.println(localDate1);

    LocalDate localDate2 = LocalDate.ofYearDay(2018,100);
    System.out.println(localDate2);

    LocalDate localDate3 = LocalDate.ofEpochDay(10);
    System.out.println(localDate3);
}

Output result:

2018-04-23
2017-07-22
2018-04-10
1970-01-11

It should be noted that LocalDate will calculate the year-month-day information based on the current time in the system and the default time zone.

In addition, there are a lot of common methods for dates in LocalDate:

  • public int getYear(): Get year information
  • public int getMonthValue(): Get month information
  • public int getDayOfMonth(): Get the current day of the month
  • public int getDayOfYear(): Get the current day of the year
  • public boolean isLeapYear(): whether it is a leap year
  • public int lengthOfYear(): Get how many days there are in this year
  • public DayOfWeek getDayOfWeek(): returns week information
  • etc

These methods are well known and will not be repeated here.

LocalTime for processing time

Similar to LocalDate, LocalTime focuses on time processing. It provides various processing of hours, minutes, seconds, and nanoseconds. We can still create a LocalTime instance in a similar way.

  • public static LocalTime now(): Get the time part of the content according to the current time of the system
  • public static LocalTime of(int hour, int minute): explicitly pass in the hour and minute to build an instance object
  • public static LocalTime of(int hour, int minute, int second): Construct an instance by passing in the hour, minute and second
  • public static LocalTime of(int hour, int minute, int second, int nanoOfSecond): construct an instance by passing in hours, minutes, seconds and nanoseconds
  • public static LocalTime ofSecondOfDay(long secondOfDay): Pass in a long integer value representing the number of seconds that have passed in the current day
  • public static LocalTime ofNanoOfDay(long nanoOfDay): Pass in a long integer representing the number of nanoseconds that have passed in the current day

Similarly, LocalTime uses the system default time zone to process time by default, see the code:

public static void main(String[] a){
    LocalTime localTime = LocalTime.now();
    System.out.println(localTime);

    LocalTime localTime1 = LocalTime.of(23,59);
    System.out.println(localTime1);

    LocalTime localTime2 = LocalTime.ofSecondOfDay(10);
    System.out.println(localTime2);
}

Output result:

13:59:03.723
23:59
00:00:10

Of course, LocalTime also encapsulates many useful tool methods, such as:

  • public int getHour()
  • public int getMinute()
  • public int getSecond()
  • public int getNano()
  • public LocalTime withHour(int hour): Modify the hour property in the current LocalTime instance and return a new instance
  • public LocalTime withMinute(int minute):类似
  • public LocalTime withSecond(int second)
  • etc

The LocalDateTime class integrates LocalDate and LocalTime. It can represent both date and time information. The methods are similar, but there is a part of the conversion content involving time zone, which we will talk about later.

Timezone dependent datetime handling ZonedDateTime

Whether it is our LocalDate, or LocalTime, or even LocalDateTime, they are basically time zone-independent, there is no time zone attribute stored internally, and the system default time zone is basically used. Often in some scenarios, there is a lack of flexibility.

ZonedDateTime can be understood as the outer encapsulation of LocalDateTime, which stores an instance of LocalDateTime inside, which is specially used for ordinary date and time processing. In addition, it also defines ZoneId and ZoneOffset to describe the concept of time zone.

A big difference between ZonedDateTime and LocalDateTime is that the latter does not store a time zone internally, so it is highly dependent on the system. Often changing a time zone may lead to inconsistent date and time in the program.

The latter can use ZoneId for matching storage by passing in the name of the time zone, or use ZoneOffset to store time zone information by passing in the offset from the zero time zone.

Therefore, there are several ways to construct a ZonedDateTime instance:

  • public static ZonedDateTime now(): The system will calculate and store date-time information in the default time zone
  • public static ZonedDateTime now(ZoneId zone):指定时区
  • public static ZonedDateTime of(LocalDate date, LocalTime time, ZoneId zone): Specify date time and time zone
  • public static ZonedDateTime of(LocalDateTime localDateTime, ZoneId zone)
  • public static ZonedDateTime ofInstant(Instant instant, ZoneId zone): Build instance objects by moment and time zone
  • etc

Look at the code:

public static void main(String[] a){
    ZonedDateTime zonedDateTime = ZonedDateTime.now();
    System.out.println(zonedDateTime);

    LocalDateTime localDateTime = LocalDateTime.now();
    ZoneId zoneId = ZoneId.of("America/Los_Angeles");
    ZonedDateTime zonedDateTime1 = ZonedDateTime.of(localDateTime,zoneId);
    System.out.println(zonedDateTime1);

    Instant instant = Instant.now();
    ZoneId zoneId1 = ZoneId.of("GMT");
    ZonedDateTime zonedDateTime2 = ZonedDateTime.ofInstant(instant,zoneId1);
    System.out.println(zonedDateTime2);
}

Output result:

2018-04-23T16:10:29.510+08:00[Asia/Shanghai]
2018-04-23T16:10:29.511-07:00[America/Los_Angeles]
2018-04-23T08:10:29.532Z[GMT]

Briefly explain, first of all, the first output should be fine, the system saves the current system date and time and the default time zone.

In the second small example, the LocalDateTime instance saves the time zone-independent current date and time information, that is, the year, month, day, hour, minute, and second, and then constructs a ZonedDateTime instance and passes in a US time zone (West 7th zone). You will find that the date and time of the output is 16:29 in the West Seventh District.

The date and time associated with the time zone like this can solve the problem of time confusion in the program caused by changing the time zone. Because I associate the time zone, no matter where your program runs, the date + time zone has already uniquely determined a certain moment, which is equivalent to when I store a certain moment, I explained that this is a certain time zone. At a certain time, even if you change a region, you won't be able to parse this time according to your current time zone and use it directly.

The third small example is more straightforward. When constructing a ZonedDateTime instance, a time and a time zone are given, and the time value is the number of milliseconds that have elapsed relative to the standard time of the given time zone.

The processing method of other date and time related to ZonedDateTime is the same as that of LocalDateTime, because ZonedDateTime directly encapsulates a LocalDateTime instance object, so all related date and time operations will indirectly call the methods of the LocalDateTime instance, and we will not repeat them.

format datetime

In the new date and time API of Java 8, DateTimeFormatter is the main class for formatting date and time. The biggest difference between it and the previous DateFormat class is that it is thread-safe, and other operations are basically similar. Let's see:

public static void main(String[] a){
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
    LocalDateTime localDateTime = LocalDateTime.now();
    System.out.println(formatter.format(localDateTime));

    String str = "2008年08月23日 23:59:59";
    DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
    LocalDateTime localDateTime2 = LocalDateTime.parse(str,formatter2);
    System.out.println(localDateTime2);

}

Output result:

2018年04月23日 17:27:24
2008-08-23T23:59:59

There are two main cases of formatting, one is to format the date and time into a string, and the other is to replace the formatted string into a date-time object.

DateTimeFormatter provides the format method to convert a datetime object into a formatted string, but the reverse operation suggests using the specific datetime class's own parse method, which saves the step of type conversion.

Time difference

In real projects, we often encounter the situation of calculating the difference between two time points. The most crude way is to convert them all into milliseconds and perform subtraction, and finally convert them back to a date-time object.

But the java.time package provides a method for calculating the difference between two dates and times, let's take a look.

Regarding the calculation of the time difference, it mainly involves two categories:

  • Period: handles the difference between two dates
  • Duration: handle the difference between two times

E.g:

public static void main(String[] args){
    LocalDate date = LocalDate.of(2017,7,22);
    LocalDate date1 = LocalDate.now();
    Period period = Period.between(date,date1);
    System.out.println(period.getYears() + "年" +
            period.getMonths() + "月" +
            period.getDays() + "天");

    LocalTime time = LocalTime.of(20,30);
    LocalTime time1 = LocalTime.of(23,59);
    Duration duration = Duration.between(time,time1);
    System.out.println(duration.toMinutes() + "分钟");
}

Output result:

0年9月1天
209分钟

Obviously, it is enough to use the Period class to calculate the difference between the days of the year, month, and day, while the Duration class is needed to calculate the difference between the hours, minutes, seconds, and milliseconds.

Finally, about the new date and time API under the java.time package, we briefly studied it, but did not go deep into the source code implementation level to introduce it, because the bottom layer involves a large number of system interfaces, involving a large number of abstract classes and implementation classes. Interested friends can read the source code of jdk for in-depth study.


All the code, images and files in the article are stored in the cloud on my GitHub:

(https://github.com/SingleYam/overview_java)

Welcome to the WeChat public account: Gorky on the code, all articles will be synchronized on the public account.

image

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324826078&siteId=291194637