Java 8 java.time.temporal. TemporalAdjuster tutorial with examples
This tutorial explains how date and time adjustments can be performed using Java 8’s new
These individual
Examples of common Temporal Adjusters - Date modification instructions such as finding the next working day, or the next Monday, last day of the week, first working day of the month are all examples of standard date calculation scenarios. All of these scenarios involve adjusting a given date to arrive at another date as per the adjustment requirement.
Java designers have, in fact, thought of the most common of such date adjustment scenarios, and provided predefined
We have now understood what a Temporal Adjuster is used for, and also had a look at the set of predefined Temporal Adjusters. Let us now see the two ways (or methods) for using a Temporal Adjuster in code. Two methods for using Temporal Adjusters in code Temporal Adjusters can be coded for using either of these two methods -
Defining a custom Temporal Adjuster
If your date adjustment requirement is not fulfilled by any of the predefined Temporal Adjusters provided by the
To create your custom implementation of a
To understand better, let us now see a code snippet which defines a
OUTPUT of the above code
Explanation of the code
Summary
In the above tutorial we first understood what is
TemporalAdjuster
interface with examples. It starts off with explaining what is a TemporalAdjuster
and its purpose. It then goes through the list of predefined Temporal Adjusters provided by the TemporalAdjusters
class. Next, the two ways (or methods) of using Temporal Adjusters for date adjustment viz Temporal.with()
and TemporalAdjuster.adjustInto()
are explained with code examples. Lastly, the tutorial explains how to define a custom TemporalAdjuster
implementation of one's own using lambda expressions, in case the predefined Temporal Adjusters are not able to serve your date-time adjustment requirements.
What is a Temporal Adjuster
Certain date-time modification operations may need to be applied to dates repeatedly based on business and application requirements. In Java 8’s new Date-Time APIClick to Read Overview of Java 8's new Date-Time API, these date-time modification operations can be abstracted out as individual java.time.temporal.
TemporalAdjuster
instances.These individual
TemporalAdjuster
instances can then be used to carry out the desired date modifications, or adjustments, as and when required. By abstracting out date adjustment strategies, application can be designed against the TemporalAdjuster contract. The design of such systems can then remain closed for modification. At the same time, the design remains open for extension by allowing different Temporal Adjustment implementations. Such a design, which allows multiple strategies to be used at runtime, while the application design itself remains constant, apart from adhering to the Open-Closed PrincipleClick to Read Tutorial on Open-Closed Principle, is also typical of a strategy design patternClick to Read Strategy Design Pattern Tutorial implementation.Examples of common Temporal Adjusters - Date modification instructions such as finding the next working day, or the next Monday, last day of the week, first working day of the month are all examples of standard date calculation scenarios. All of these scenarios involve adjusting a given date to arrive at another date as per the adjustment requirement.
TemporalAdjuster
implementations via the TemporalAdjusters
class. Let us first take a look at TemporalAdjusters
and the predefined Temporal Adjusters it provides.
Predefined Temporal Adjusters
java.time.temporal.TemporalAdjusters
has provided static factory methods to access predefined commonly used Temporal Adjusters. These are -
Table: Predefined Temporal Adjusters in
If any of the above date adjustments matches your requirement, then you don't need to implement a new TemporalAdjusters
classMethod Name | Purpose |
firstDayOfMonth() , lastDayOfMonth() | Get first/last day of month. |
firstDayOfNextMonth() | Get first day of previous month. |
firstDayOfNextYear() | Get first day of next year. |
firstDayOfYear() , lastDayOfYear() | Get first/last day of year. |
firstInMonth() , lastInMonth() | Get first/last occurrence of a DayOfWeek Click to Read Tutorial on Java 8's DayOfWeek Enum in month. |
next() , previous() | Next/Previous occurrence of DayOfWeek . |
nextOrSame() , previousOrSame() | Next/current DayOfWeek |
dayOfWeekInMonth() | Ordinal DayOfWeek in month |
TemporalAdjuster
of your own. Simply go ahead and get a reference to the instance of your required date adjuster using the static factory method mentioned above.We have now understood what a Temporal Adjuster is used for, and also had a look at the set of predefined Temporal Adjusters. Let us now see the two ways (or methods) for using a Temporal Adjuster in code. Two methods for using Temporal Adjusters in code Temporal Adjusters can be coded for using either of these two methods -
- Using
Temporal.with()
method (recommended way) -Temporal
is the parent interface of all the new Date-Time classes in Java 8. It defines the default method namedwith()
with the following signature -Where,default Temporal with(TemporalAdjuster adjuster)
-adjuster
is an instance ofTemporalAdjuster
containing the logic for adjusting theTemporal
object on which this method is invoked.
- the method returns an immutable instance ofTemporal
which will be of the same type (subclass ofTemporal
) on which this method is invoked.
- among the two methods for using Temporal Adjusters, this method is recommended due to better readability.
So, given a date, if you want to find out the last day of the month in which that date occurs, then finding the required date is quite simple using theTemporalAdjuster
instance returned byTemporalAdjusters.lastDayOfMonth()
method. Let us see a code snippet showing the use ofTemporal.with()
method and couple of predefined Temporal Adjusters.
Date adjustment using Temporal.with() method//Using TemporalAdjusters.lastDayOfMonth() LocalDate localDate= LocalDate.now(); LocalDate lastDayOfMonth=localDate.with(TemporalAdjusters.lastDayOfMonth()); System.out.println("Last day of month of "+localDate+" is: "+lastDayOfMonth); //Using TemporalAdjusters.firstDayOfNextMonth() LocalDate firstDayOfNextMonth=localDate.with(TemporalAdjusters.firstDayOfNextMonth()); System.out.println("First day of next month for "+localDate+" is: "+firstDayOfNextMonth);
Last day of month for 2017-01-11 is: 2017-01-31 First day of next month for 2017-01-11 is: 2017-02-01
LocalDate.now()
method is used to get the current date from the System clock. The value returned is ‘2017-01-11
’ and is stored in a variable namedlocalDate
.localDate.with()
method is invoked with the parameter being theTemporalAdjuster
instance returned byTemporalAdjusters.lastDayOfMonth()
method.- The adjusted date, i.e.last day of the month for
localDate
, is returned by thewith()
method, and assigned tolastDayOfMonth
variable. Note that the type oflocalDate
andlastDayOfMonth
is the same i.e.LocalDate
. - Next, the value for
lastDayOfMonth
is printed correctly as ‘2017-01-31
’. - In the same manner, first day of next month for
localDate
is determined using thewith()
method. This time the parameter of thewith()
method is theTemporalAdjuster
returned byTemporalAdjusters.firstDayOfNextMonth()
. - Value of
firstDayOfNextMonth
is determined correctly and printed as ‘2017-02-01
’.
- Using
TemporalAdjuster.adjustInto()
method-TemporalAdjuster
interface defines a method namedadjustInto()
with the following signature -Where,Temporal adjustInto(Temporal temporal);
-temporal
parameter is an instance of a subtype ofTemporal
which needs to be adjusted. I.e. this parameter is the temporal value based on which calculation has to be performed.
- the method returns an immutable instance ofTemporal
which will be of the same type (subclass ofTemporal
) as the input parameter.
- among the two methods for using Temporal Adjusters, this method is not recommended due to less readability.
Let us take the same use cases for seeingadjustInto()
method in action as we took forwith()
method. I.e. given a date, we want to find out the last day of the month in which that date occurs, and the first day of the next month.
Date adjustment using TemporalAdjuster.adjustInto() method//Using TemporalAdjusters.lastDayOfMonth() LocalDate localDate= LocalDate.now(); LocalDate lastDayOfMonth=(LocalDate)TemporalAdjusters.lastDayOfMonth().adjustInto(localDate); System.out.println("Last day of month for "+localDate+" is: "+lastDayOfMonth); //Using TemporalAdjusters.firstDayOfNextMonth() LocalDate firstDayOfNextMonth = (LocalDate)TemporalAdjusters.firstDayOfNextMonth().adjustInto(localDate); System.out.println("First day of next month for "+localDate+" is: "+firstDayOfNextMonth);
Last day of month for 2017-01-11 is: 2017-01-31 First day of next month for 2017-01-11 is: 2017-02-01
LocalDate.now()
method is used to get the current date from the System clock. The value returned is ‘2017-01-11
’ and is stored in a variable namedlocalDate
.adjustInto()
method is invoked on theTemporalAdjuster
instance obtained using the methodTemporalAdjusters.lastDayOfMonth()
.localDate
, which is to be adjusted to last date of the month, is passed as a parameter to theadjustInto()
method.- The value returned by the
adjustInto()
method is typecast into aLocalDate
and assigned to the variable namedlastDayOfMonth
. - Note that the typecasting needed for
adjustInto()
is not required when adjusting dates usingwith()
method we saw earlier. - Value for
lastDayOfMonth
is printed correctly as ‘2017-01-31
’. - Similarly, first day of next month is calculated using
TemporalAdjuster
obtained fromTemporalAdjusters.firstDayOfNextMonth()
method and is printed correctly as ‘2017-02-01
’.
TemporalAdjusters
class, then you will need to create a Temporal Adjuster of your own.TemporalAdjuster
interface in Java 8 is a functional interfaceClick to read tutorial on Functional Interfaces. It has a single method named adjustInto()
which is the same method we saw in the earlier section. On account of TemporalAdjuster
being a functional interface, creating its implementation is straightforward.To create your custom implementation of a
TemporalAdjuster
, all you need to do is define a lambda expressionClick to read Lambda Expressions tutorial, whose function descriptorClick to Read Tutorial explaining function descriptors matches the signature of adjustInto()
method. Then you can chose to either pass this lambda expression as a parameter to Temporal.with()
method. Or, you can use this instance of TemporalAdjuster
created using the lambda expression and invoke the adjustInto()
method on it.To understand better, let us now see a code snippet which defines a
TemporalAdjuster
using a lambda expression and then uses it for date adjustment. The custom Temporal Adjuster in the example will do the simple taks of adding 2 days to the date being adjusted.Creating a custom TemporalAdjuster using a lambda expression
package com.javabrahman.java8.time;
import java.time.LocalDate;
import java.time.temporal.Temporal;
import java.time.temporal.TemporalAdjuster;
public class CustomTemporalAdjuster {
public static void main(String args[]) {
LocalDate localDate = LocalDate.now();
TemporalAdjuster add2days = (Temporal date) -> ((LocalDate)date).plusDays(2);
System.out.println("2 days added to "+localDate+" gives: "+localDate.with(add2days));
}
}
2 days added to 2017-01-11 gives: 2017-01-13
CustomTemporalAdjuster
first creates an instance ofLocalDate
, namedlocalDate
, usingLocalDate.now()
method. The value stored inlocalDate
is‘2017-01-11’
.- Next an implementation of
TemporalAdjuster
, namedadd2days
, is created by defining its functionality using a lambda expression -(Temporal date) -> ((LocalDate)date).plusDays(2)
. - The lambda takes a
Temporal
as input named date. In this case theTemporal
type needs to be aLocalDate
. Hence, when the lambda is evaluated, date is typecast toLocalDate
and2
days are added to it. - Using the
Temporal.with()
methodadd2days
is used to adjust the value oflocalDate
. The adjusted value is then printed and as expected the resulting date is moved forward by 2 days to‘2017-01-13’
. - Note that this is a very simple example showing how to implement a custom
TemporalAdjuster
using a lambda expression. It does not take care of possible exception scenarios such as passing aTemporal
which is not aLocalDate
which will potentially lead to typecast exception, and similar exceptions.
TemporalAdjuster
interface via its definition and purpose, looked at predefined Temporal Adjusters which can be accessed through TemporalAdjusters
class, understood the two methods for coding these date adjustments, and lastly understood how to define custom TemporalAdjuster
implementation of our own using a lambda expression.Tutorials on Java 8’s new Date and Time API
Overview of Java 8's new Date and Time APIClick to Read Overview of Java 8's new Date-Time API Working with time zones in Java 8| ZonedDateTime, ZoneId tutorial with examplesClick to Read tutorial on time zone handling in Java 8 How to convert LocalDate to String and String to LocalDateClick to Read tutorial on String to LocalDate conversions How to convert java.util.Date to java.time.LocalDateClick to Read tutorial on java.util.Date to LocalDate conversion Formatting localized dates in Spanish and FrenchClick to Read date formatting in Spanish & French How to get day-of-week for a given dateHow to get day-of-week using java.time.DayOfWeek enumDate Modification using TemporalAdjuster Click to Read Tutorial on TemporalAdjusters
Overview of Java 8's new Date and Time APIClick to Read Overview of Java 8's new Date-Time API Working with time zones in Java 8| ZonedDateTime, ZoneId tutorial with examplesClick to Read tutorial on time zone handling in Java 8 How to convert LocalDate to String and String to LocalDateClick to Read tutorial on String to LocalDate conversions How to convert java.util.Date to java.time.LocalDateClick to Read tutorial on java.util.Date to LocalDate conversion Formatting localized dates in Spanish and FrenchClick to Read date formatting in Spanish & French How to get day-of-week for a given dateHow to get day-of-week using java.time.DayOfWeek enumDate Modification using TemporalAdjuster Click to Read Tutorial on TemporalAdjusters