Java A long-term worry for developers is the lack of support for ordinary developers' date and time use cases .
for example , Existing classes （ for example java.util.Date and SimpleDateFormatter） It's not thread safe , This leads to potential concurrency problems for users , This is not a problem that the average developer would expect to deal with when writing date handling code . Some date and time classes also show fairly poor API Design . for example , year java.util.Date from 1900 Start , Month from 1 Start , Tiancong 0 Start , It's not very intuitive .
These and other issues lead to third-party date and time libraries （ for example Joda-Time） The prosperity of .
In order to solve these problems and in JDK Better support in the kernel , in the light of Java SE 8 Designed a new date and time without these problems API. The project consists of Joda-Time（Stephen Colebourne） and Oracle Author of JSR 310 Under common leadership , Appear in the Java SE 8 In the package java.time.
Java One of the serious drawbacks of existing formatters is that they are not thread safe . This puts a burden on developers , Make them need to use them in a thread safe way and consider concurrency in their daily processing of date processing code . new API Avoid this problem by ensuring that all of its core classes are immutable and represent well-defined values .
new API The model and the class domain representing different use cases are very precise Date and Time Tight . This is different from the previous Java Library is different , The latter is poor in this respect . for example ,java.util.Date Represent a moment on the timeline （ One self UNIX Millisecond wrappers since the beginning of the Millennium ）, But if you call toString(), It turns out that it has time zones , This leads to confusion among developers .
This emphasis on Domain Driven Design offers long-term benefits in terms of clarity and intelligibility , But from the previous API Migration to Java SE 8 when , You may need to consider the application's domain date model .
new API So that people can use different calendar systems to meet certain areas of the world （ Like Japan or Thailand ） User needs , And these users don't necessarily follow ISO-8601. This will not put an extra burden on most developers , They just need to use a standard chronology .
Both are local , Because they represent the date and time from the observer's point of view , For example, the calendar on the desk or the clock on the wall .
There is also a class called a composite class
LocalDateTime, This is a LocalDate and LocalTime Pairing of .
Time zones distinguish the context of different observers , Put it aside here ; When context is not needed , You should use these local classes . These classes can even be used to represent time on a distributed system with a consistent time zone .
Gets the current date in the default time zone system clock . This method will query the system clock in the default time zone , To get the current date . Using this method will prevent the use of the backup clock for testing , Because the clock is hard coded .
Convenient addition and subtraction , You don't have to figure it out ！
Return this copy LocalDate Added a specified number of months . This method will specify the months fields of the amount in three steps ：
for example ,2007-03-31 Adding one month will result in invalid dates 2007 year 4 month 31 Japan . Not returning an invalid result , It is 2007-04-30 It's the last valid date . The immutability of the calling instance is not affected by the method .
new API All the core classes in are constructed through skilled factory methods .
You can also change object values to perform calculations . Because of the new API All core classes in are immutable , So these methods will be called with And return the new object , Instead of using setter. There are also calculation methods based on different fields .
new API There's also the concept of a regulator — A block of code , It can be used to package general processing logic . You can write a WithAdjuster, Used to set one or more fields , You can also write a PlusAdjuster Used to add or subtract certain fields . Value classes can also act as regulators , under these circumstances , They will update the values of the fields they represent . The built-in regulator is made up of new API Definition , But if you have specific business logic that you want to reuse , You can write your own regulator .
import static java.time.temporal.TemporalAdjusters.*; LocalDateTime timePoint = ... foo = timePoint.with(lastDayOfMonth()); bar = timePoint.with(previousOrSame(ChronoUnit.WEDNESDAY)); // Use value classes as adjusters timePoint.with(LocalTime.now());
new API By providing a date , Time and date with time types to support different precision time points , But obviously , The concept of precision is higher than that .
The truncatedTo Methods exist to support this use , It can truncate your values to fields , as follows
LocalTime truncatedTime = time.truncatedTo(ChronoUnit.SECONDS);
The local class we looked at earlier abstracts the complexity introduced by time zones . Time zones are a set of rules , Corresponding to the same area of standard time . There are about 40 individual . Time zones are defined by their relation to coordinated universal time （UTC,Coordinated Universal Time） The offset definition of . They move roughly in sync , But there are some differences .
The time zone can be represented by two identifiers ： abbreviation , for example “ PLT”, Longer, for example “ Asia / Karachi”. When designing an application , You should consider which case is suitable to use time zone , When do I need an offset .
ZoneIdIs the identifier of the zone . Every ZoneId Rules correspond to some rules , These rules define the time zone of the location . When designing software , If you consider using something like “ PLT” or “ Asia / Karachi” Strings like that , Instead, use the domain class . An example use case is to store users' preferences for their time zones .
ZoneOffsetIt's Greenwich / UTC Time periods that differ from time zones . Can be in specific
ZoneId, Parsed at a specific time , Like the list 7 Shown .
ZoneOffset offset = ZoneOffset.of("+2:00");
ZonedDateTime Is a date and time with a fully qualified time zone . This can solve any point in time offset . Best practices ： To represent a date and time independent of the context of a particular server , You should use
OffsetDateTime Is the date and time with resolved offset . This is useful for serializing data into a database , If the server is in a different time zone , Should also be used as a serialization format for recording timestamps .
OffsetTime Is the time with a definite offset , as follows ：
OffsetTime time = OffsetTime.now(); // changes offset, while keeping the same point on the timeline OffsetTime sameTimeDifferentOffset = time.withOffsetSameInstant( offset); // changes the offset, and updates the point on the timeline OffsetTime changeTimeWithNewOffset = time.withOffsetSameLocal( offset); // Can also create new object with altered fields as before changeTimeWithNewOffset .withHour(3) .plusSeconds(2); OffsetTime time = OffsetTime.now(); // changes offset, while keeping the same point on the timeline OffsetTime sameTimeDifferentOffset = time.withOffsetSameInstant( offset); // changes the offset, and updates the point on the timeline OffsetTime changeTimeWithNewOffset = time.withOffsetSameLocal( offset); // Can also create new object with altered fields as before changeTimeWithNewOffset .withHour(3) .plusSeconds(2);
Java There is already a time zone class in ,java.util.TimeZone but Java SE 8 Not using it , Because all JSR 310 Classes are immutable and time zones are variable .
Period For example “ 3 One month and one day ” Value , It's the distance on the timeline . This is in sharp contrast to the other classes we've discussed so far , They're the focus of the timeline .
// 3 year , 2 month , 1 God Period period = Period.of(3, 2, 1); // Use period Modify the date value LocalDate newDate = oldDate.plus(period); ZonedDateTime newDateTime = oldDateTime.minus(period); // Components of a Period are represented by ChronoUnit values assertEquals(1, period.get(ChronoUnit.DAYS)); // 3 years, 2 months, 1 day Period period = Period.of(3, 2, 1); // You can modify the values of dates using periods LocalDate newDate = oldDate.plus(period); ZonedDateTime newDateTime = oldDateTime.minus(period); // Components of a Period are represented by ChronoUnit values assertEquals(1, period.get(ChronoUnit.DAYS));
Duration It's the distance measured by time on the timeline , It achieves a similar purpose to Period, But the accuracy is different ：
// 3 s and 5 ns Of Duration Duration duration = Duration.ofSeconds(3, 5); Duration oneDay = Duration.between(today, yesterday); // A duration of 3 seconds and 5 nanoseconds Duration duration = Duration.ofSeconds(3, 5); Duration oneDay = Duration.between(today, yesterday);
It can be done to Duration The instance performs the normal addition , Subtract and “ with” operation , You can also use values that modify the date or time Duration.
In order to meet the needs of using non ISO The requirements of calendar system developers ,Java SE 8 Introduced Chronology, On behalf of the calendar system , And act as a time point factory in the calendar system . There are also some interfaces corresponding to core point in time classes , But through
Chronology: ChronoLocalDate ChronoLocalDateTime ChronoZonedDateTime Chronology: ChronoLocalDate ChronoLocalDateTime ChronoZonedDateTime
These classes are only suitable for developers who are developing highly internationalized applications and need to consider the local calendar system , Developers without these requirements should not use them . Some calendar systems don't even have the concept of a month or a week , So you need to go through very general fields API Calculate .
Java SE 8 There are also classes with other common use cases . There is one MonthDay class , It contains a pair of Month and Day, Very useful for birthday . The YearMonth Class covers the use cases of credit card start date and expiration date, and scenarios where people don't specify a date .
Java SE 8 Medium JDBC These new types will be supported , But it won't change the public JDBC API. Existing generics setObject and getObject The method is enough .
These types can be mapped to vendor specific database types or ANSI SQL type .
Java SE 8 stay java.time With a new date and time API, Provides developers with greatly improved security and functionality . new API Well modeled the field , And provides a large number of classes for modeling various developer use cases .
Participation of this paper Tencent cloud media sharing plan , You are welcome to join us , share .