Working with LocalDate, LocalTime and LocalDateTime
Java 8 had a major change for the date and time APIs, which was the inclusion of Joda Time APIs into JDK under the JSR 310: Date and Time API. This JSR was lead by Stephen Colebourne, the creator of Joda Time.
There are many amazing APIs to work with date and time. In this article I will look at the most commonly used ones: java.time.LocalDate
, java.time.LocalTime
and java.time.LocalDateTime
. These represent the date and time values independent of the timezone. So they rely on the system clock to capture the values.
Creating an Instance
Lets look at the ways to create their instances using the now()
method and the factory method of()
:
jshell> LocalDate.now() $46 ==> 2018-07-07 jshell> LocalDate.of(2018, 3, 30) $47 ==> 2018-03-30 jshell> LocalTime.now() $48 ==> 00:32:06.883656 jshell> LocalTime.of(12,43,12,33333); $49 ==> 12:43:12.000033333 jshell> LocalDateTime.now() $50 ==> 2018-07-07T00:32:30.335562400 jshell> LocalDateTime.of(2018, 12, 30, 12,33) $51 ==> 2018-12-30T12:33 jshell> LocalDateTime.of(LocalDate.now(), LocalTime.now()) $52 ==> 2018-07-07T00:40:38.198318200
Manipulating Date and Time
Let’s look at how to manipulate or modify the date and time instances created:
jshell> LocalDate d = LocalDate.now() d ==> 2018-07-07 jshell> d.plusDays(12) $54 ==> 2018-07-19 jshell> d d ==> 2018-07-07 jshell> d.plusMonths(2) $56 ==> 2018-09-07 jshell> d.minusDays(5) $57 ==> 2018-07-02 jshell> d.minusWeeks(4) $58 ==> 2018-06-09
These plus*()
and minus*()
methods are immutable and return a new date and time instance. In the above example we saw few methods to manipulate the components of java.time.LocalDate
. On similar lines there are plus*()
and minus*()
methods for manipulating the components of java.time.LocalTime
and java.time.LocalDateTime
.
Comparing Date and Time instances
We would want to know if the given date and time is before or after another and in such cases we will make use of the isBefore()
and isAfter()
methods as shown below:
jshell> var d1 = LocalDate.of(2018, 7, 6) d1 ==> 2018-07-06 jshell> var d2 = LocalDate.of(2018, 7, 7) d2 ==> 2018-07-07 jshell> d1.isAfter(d2) $64 ==> false jshell> d1.isBefore(d2) $65 ==> true jshell> var dt1 = LocalDateTime.of(2018, 7, 7, 12, 30) dt1 ==> 2018-07-07T12:30 jshell> var dt2 = LocalDateTime.of(2018, 7, 7, 14, 30) dt2 ==> 2018-07-07T14:30 jshell> dt1.isBefore(dt2) $68 ==> true jshell> dt1.isAfter(dt2) $69 ==> false
Converting between String and date object representations
Often we have had the need to convert a String representation of date and time to its corresponding object and also convert the object into a String representation. With older date class java.util.Date
we use java.text.SimpleDateFormat
to parse string to date and vice-versa. In the new date time API a new class java.time.format.DateTimeFormatter
has been introduced for the same task.
If you follow the ISO standard of converting the date between its string and object representations lot of the integrations between layers and applications becomes seamless due to the predefined ISO formats available in the java.time.format.DateTimeFormatter
. Lets see this in action:
jshell> import java.time.* jshell> LocalDateTime ldt = LocalDateTime.now() ldt ==> 2018-09-26T22:58:32.229096300 jshell> import java.time.format.* jshell> ldt.format(DateTimeFormatter.ISO_DATE) $4 ==> "2018-09-26" jshell> ldt.format(DateTimeFormatter.ISO_DATE_TIME) $5 ==> "2018-09-26T22:58:32.2290963" jshell> ldt.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME) $9 ==> "2018-09-26T22:58:32.2290963" jshell> ldt.format(DateTimeFormatter.BASIC_ISO_DATE) $10 ==> "20180926"
We can even make use of custom formatting patterns as shown below:
jshell> ldt.format(DateTimeFormatter.ofPattern("d-M-y")); $11 ==> "26-9-2018" jshell> ldt.format(DateTimeFormatter.ofPattern("d-MM-y hh:mm:ss")); $12 ==> "26-09-2018 10:58:32" jshell> ldt.format(DateTimeFormatter.ofPattern("d/MMM/y hh:mm:ss")); $13 ==> "26/Sep/2018 10:58:32" jshell> ldt.format(DateTimeFormatter.ofPattern("d-MMM-y hh:mm:ss")); $14 ==> "26-Sep-2018 10:58:32" jshell> ldt.format(DateTimeFormatter.ofPattern("d-MMM-y hh:mm:ss")); $15 ==> "26-Sep-2018 10:58:32" jshell> ldt.format(DateTimeFormatter.ofPattern("d-MMM-y HH:mm:ss")); $16 ==> "26-Sep-2018 22:58:32"
The different rules for creating the patterns can be found in the Javadoc for java.time.format.DateTimeFormatter
.
Let us look at converting a valid String representation of date and time to LocalDateTime
and its related objects:
<br />jshell> LocalDate ld = LocalDate.parse("2018-09-26") ld ==> 2018-09-26 jshell> LocalDateTime ldt = LocalDateTime.parse("2018-09-26T22:24:33") ldt ==> 2018-09-26T22:24:33
You can see that in the above code we are not providing the pattern for parsing the string, instead it is making use of the default ISO formats. This approach is very useful when exchanging the date and time values via APIs.
With this, I have shown some basic things which you can do with the new date and time instances which are timezone independent. In the coming posts I will write about timezone dependent time, finding duration, period between time and date and also working with different calendar systems.
Published on Java Code Geeks with permission by Mohamed Sanaulla, partner at our JCG program. See the original article here: Working with LocalDate, LocalTime and LocalDateTime Opinions expressed by Java Code Geeks contributors are their own. |