As part of this article, let us start with some problems with the existing Date and Calendar APIs and explore how the new Java 8 Date and Time APIs solve these problems.
We will also take a look at the core classes in the Java 8 time class library, such as LocalDate, LocalTime, LocalDateTime, ZonedDateTime, Period, Duration and their APIs.
Thread safety - Date and Calendar classes are not thread-safe, making it difficult for developers to debug these APIs Concurrency issues require writing additional code to handle thread safety. The new Date and Time APIs introduced in Java 8 are immutable and thread-safe, allowing these pain points to be solved.
API design and ease of understanding - The old time API is very difficult to understand, the operations are very complex, very convoluted, and does not provide some commonly used parsing and conversion methods. The new time API is ISO-centric and follows a consistent domain model for date, time, duration and periods. Some very useful methods are provided to support the most common operations. We no longer need to encapsulate some time operation classes ourselves.
ZonedDate and Time - In the old time api developers had to write additional logic to handle the time zone logic of the old API, while with the new API, Local and ZonedDate / Time can be used API to handle time zones. No need to worry too much about time zone conversion.
The most commonly used classes are LocalDate, LocalTime and LocalDateTime. As their name suggests, they represent local date/time combined with context.
These classes are mainly used when the time zone does not need to be explicitly specified in the context. As part of this section, we'll cover the most commonly used APIs.
LocalDate represents a date without specific time in ISO format (YYYY-MM-DD).
is often used to express birthdays or the salary dates we are most concerned about.
Get the date under the current system clock, as follows:
LocalDate localDate = LocalDate.now();
LocalDate representing a specific day, month and year can use the " of " method or use " parse " method to obtain. For example, the following code snippet represents the LocalDate of February 20, 2015:
LocalDate.of(2015, 02, 20); LocalDate.parse("2015-02-20");
Isn’t it very intuitive and convenient! LocalDate provides various utility methods to obtain various date information. Let's take a quick look at these API methods.
The following code snippet gets the current local date and adds one day:
LocalDate tomorrow = LocalDate.now().plusDays(1);
This example gets the current date and subtracts one month. Note how it accepts an enum as the time unit:
LocalDate previousMonthSameDay = LocalDate.now().minus(1, ChronoUnit.MONTHS);
In the following two code examples, we parse the date "2016-06-12" and get the day of the week and day of the month respectively. Pay attention to the return value. The first one is an object representing DayOfWeek, and the second one is an int representing the ordinal value of the month:
DayOfWeek sunday = LocalDate.parse("2016-06-12").getDayOfWeek(); int twelve = LocalDate.parse("2016-06-12").getDayOfMonth();
We can test whether a date occurs in a leap year. If we use the old method I’m afraid it’s not going to heaven:
boolean leapYear = LocalDate.now().isLeapYear();
Determine the order of dates:
boolean notBefore = LocalDate.parse("2016-06-12").isBefore(LocalDate.parse("2016-06-11")); boolean isAfter = LocalDate.parse("2016-06-12").isAfter(LocalDate.parse("2016-06-11"));
The date boundary can be obtained from the given date. In the following two examples we get a LocalDateTime which represents the start of the day for a given date (2016-06-12T00:00) and a LocalDate which represents the beginning of the month (2016-06-01):
LocalDateTime beginningOfDay = LocalDate.parse("2016-06-12").atStartOfDay(); LocalDate firstDayOfMonth = LocalDate.parse("2016-06-12") .with(TemporalAdjusters.firstDayOfMonth());
Now Let's see how we use local time.
to represent time without date in local time.
Similar to LocalDate, LocalTime instances can be created from the system clock or using the "parse" and "of" methods. Take a quick look at some commonly used APIs below.
An instance of the current LocalTime can be created from the system clock as follows:
LocalTime now = LocalTime.now();
In the following code example, we create representation 06 by parsing the string representation: LocalTime for 30 AM:
LocalTime sixThirty = LocalTime.parse("06:30");
Method "of" can be used to create a LocalTime. For example, the following code uses the "of" method to create a LocalTime representing 06:30 AM:
LocalTime sixThirty = LocalTime.of(6, 30);
The following example creates a LocalTime by parsing a string and adds an hour to it using the "plus" API. The result will be a LocalTime representing 07:30 AM:
LocalTime sevenThirty = LocalTime.parse("06:30").plus(1, ChronoUnit.HOURS);
Various getter methods can be used to get specific time units such as hours, minutes and seconds, get the hour as follows:
int six = LocalTime.parse("06:30").getHour();
Like LocalDate, checks whether a specific time is before or after another specific time. The following code example compares two LocalTimes that result in true:
boolean isbefore = LocalTime.parse("06:30").isBefore(LocalTime.parse("07:30"));
The maximum, minimum, and noon times of the day can be obtained through constants in the LocalTime class. This is useful when performing database queries to find records within a given time range. For example, the following code represents 23:59:59.99:
LocalTime maxTime = LocalTime.MAX
Now let’s take a deeper look at LocalDateTime.
The LocalDateTime is used to represent a combination of date and time.
This is the most commonly used class when we need to combine date and time. This class provides various APIs, and we will introduce some of the most commonly used APIs.
Similar to LocalDate and LocalTime, obtain an instance of LocalDateTime from the system clock:
LocalDateTime.now();
下面的代码示例解释了如何使用工厂“of”和“parse”方法创建实例。结果将是代表2015年2月20日06:30 AM 的LocalDateTime实例:
LocalDateTime.of(2015, Month.FEBRUARY, 20, 06, 30); LocalDateTime.parse("2015-02-20T06:30:00");
有一些实用的API可以支持特定时间单位的时间运算,例如天,月,年和分钟。以下代码示例演示了“加”和“减”方法的用法。这些API的行为与LocalDate和LocalTime中的 API完全相同:
localDateTime.plusDays(1); localDateTime.minusHours(2);
Getter方法可用于提取类似于日期和时间类的特定单位。鉴于上面的LocalDateTime实例,下面的代码示例将返回2月份的月份:
localDateTime.getMonth();
当我们需要处理时区特定的日期和时间时,Java 8提供了ZonedDateTime 类。ZoneID是用于表示不同区域的标识符。大约有40个不同的时区,使用ZoneID表示它们,如下所示
下面的代码我们来获取下“亚洲/上海”时区:
ZoneId zoneId = ZoneId.of("Aisa/Shanghai");
获取所有的时区:
Set<String> allZoneIds = ZoneId.getAvailableZoneIds();
LocalDateTime转化为特定的时区中的时间:
ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, zoneId);
ZonedDateTime提供解析方法来获取时区的特定日期时间:
ZonedDateTime.parse("2015-05-03T10:15:30+01:00[Aisa/Shanghai]");
使用时区的另一种方法是使用OffsetDateTime。OffsetDateTime是具有偏移量的日期时间的不可变表示形式。此类存储所有日期和时间字段,精确到纳秒,以及从UTC/格林威治的偏移量。可以使用ZoneOffset创建OffsetDateTime实例。这里我们创建一个LocalDateTime来表示2015年2月20日上午6:30:
LocalDateTime localDateTime = LocalDateTime.of(2015, Month.FEBRUARY, 20, 06, 30);
然后我们通过创建ZoneOffset并为LocalDateTime实例设置来增加两个小时:
ZoneOffset offset = ZoneOffset.of("+02:00"); OffsetDateTime offSetByTwo = OffsetDateTime.of(localDateTime, offset);
我们现在的本地日期时间为2015-02-20 06:30 +02:00。现在让我们继续讨论如何使用Period和Duration类修改日期和时间值。
Period : 用于计算两个日期(年月日)间隔。
Duration : 用于计算两个时间(秒,纳秒)间隔。
Period 类被广泛地用于修改给定的日期的值或者获取两个日期之间的差值:
LocalDate initialDate = LocalDate.parse("2007-05-10"); LocalDate finalDate = initialDate.plus(Period.ofDays(5));
Period 类有各种getter方法,如getYears,getMonths和getDays从获取值周期对象。下面的代码示例返回一个int值为5,是基于上面示例的逆序操作:
int five = Period.between(finalDate, initialDate).getDays();
该Period 可以在特定的单元获得两个日期之间的如天或月或数年,使用ChronoUnit.between:
int five = ChronoUnit.DAYS.between(finalDate , initialDate);
此代码示例返回五天。让我们继续看看Duration类。
类似Period ,该Duration类是用来处理时间。在下面的代码中,我们创建一个本地时间上午6:30,然后加30秒的持续时间,以使本地时间上午6时三十〇分30秒的:
LocalTime initialTime = LocalTime.of(6, 30, 0); LocalTime finalTime = initialTime.plus(Duration.ofSeconds(30));
两个时刻之间的持续时间可以作为持续时间或作为特定单位获得。在第一个代码片段中,我们使用Duration类的between()方法来查找finalTime和initialTime之间的时间差,并以秒为单位返回差异:
int thirty = Duration.between(finalTime, initialTime).getSeconds();
在第二个例子中,我们使用ChronoUnit类的between()方法来执行相同的操作:
int thirty = ChronoUnit.SECONDS.between(finalTime, initialTime);
现在我们来看看如何将旧的Date 和Calendar 转换为新的Date和Time。
Java 8添加了toInstant()方法,该方法有助于将旧API中的Date和Calendar实例转换为新的Date Time API,如下面的代码片段所示:
LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()); LocalDateTime.ofInstant(calendar.toInstant(), ZoneId.systemDefault());
所述LocalDateTime可以从如下“ofEpochSecond"方法来构造。以下代码的结果将是代表2016-06-13T11:34:50 的LocalDateTime:
LocalDateTime.ofEpochSecond(1465817690, 0, ZoneOffset.UTC);
现在让我们继续进行日期和时间格式化。
Java 8提供了用于轻松格式化日期和时间的 API :
LocalDateTime localDateTime = LocalDateTime.of(2015, Month.JANUARY, 25, 6, 30);
以下代码传递ISO日期格式以格式化本地日期。结果将是2015-01-25:
String localDateString = localDateTime.format(DateTimeFormatter.ISO_DATE);
该DateTimeFormatter提供多种标准格式选项。也可以提供自定义模式来格式化方法,如下所示,它将返回LocalDate为2015/01/25:
localDateTime.format(DateTimeFormatter.ofPattern("yyyy/MM/dd"));
我们可以将格式样式传递为SHORT,LONG或MEDIUM作为格式化选项的一部分。
下面的代码示例输出2015年1月25日06:30:00 me的输:
localDateTime .format(DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM) .withLocale(Locale.UK);
最后让我们看看Java 8 Core Date / Time API 可用的替代方案。
对于从Java 7或Java 6这些老项目来说可以使用Threeten ,然后可以像在上面java 8一样使用相同的功能,一旦你迁移到java 8 只需要修改你的包路径代码而无需变更:
<dependency> <groupId>org.threeten</groupId> <artifactId>threetenbp</artifactId> <version>LATEST</version> </dependency>
Java 8 日期和时间库的另一种替代方案是Joda-Time库。事实上,Java 8 Date Time API由Joda-Time库(Stephen Colebourne)和Oracle共同领导。该库提供了Java 8 Date Time项目中支持的几乎所有功能。通过在项目中引用以下pom依赖项就可以立即使用:
<dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>LATEST</version> </dependency>
The above is the detailed content of How to use Java8 Time API. For more information, please follow other related articles on the PHP Chinese website!