Learn to use Java TemporalAdjusters that helps complex date-time calculations such as getting recurring dates, processing weekly reports, sending automated monthly report outs, etc.
1. Overview
In the new Java Date API, Temporal
interface represents a date, time, or a combination of both. For example, LocalDate, LocalDateTime etc.
The TemporalAdjuster
allows us to do complex date-time calculations such as finding the next Sunday, second and last Saturday of the month, and handling recurring events. The names of most of these tell you directly what they do. If provided adjusters do not solve any specific business requirements, we can build our own custom TemporalAdjuster.
We can apply then to any temporal object with the with()
method of that date/time object. For example, there is always a weekly meeting every Monday in a team. We want to get the list of dates for the next 5 meetings.
LocalDate localDate = LocalDate.of(2020, 5, 9);
List<LocalDate> meetingDates = getWeeklyMeetingDates(localDate, 5);
private static List<LocalDate> getWeeklyMeetingDates(LocalDate localDate, int count)
{
List<LocalDate> dates = new ArrayList<>();
for(int i = 0; i < count; i++)
{
localDate = localDate
.with(TemporalAdjusters.next(DayOfWeek.MONDAY));
dates.add(localDate);
}
return dates;
}
Program output.
[2020-05-11,
2020-05-18,
2020-05-25,
2020-06-01,
2020-06-08]
2. Predefined Adjusters
This is the list of default provided adjusters for easy use. Visit the official Java Doc for detailed information.
Adjuster | Description |
---|---|
firstDayOfMonth() | returns a new date set it to the first day of the current month. |
lastDayOfMonth() | returns a new date set it to the last day of the current month. |
firstDayOfNextMonth() | returns a new date set it to the first day of the next month. |
firstDayOfYear() | returns a new date set it to the first day of the current year. |
lastDayOfYear() | returns a new date set it to the last day of the current year. |
firstDayOfNextYear() | returns a new date set it to the first day of the next year. |
firstInMonth() | returns a new date in the same month with the first matching day-of-week. Such as “first Wednesday in May”. |
lastInMonth() | returns a new date in the same month with the last matching day-of-week. |
dayOfWeekInMonth() | returns a new date in the same month with the ordinal day-of-week. |
next() | returns the date to the first occurrence of the specified day-of-week after the date being adjusted. |
previous() | returns the date to the first occurrence of the specified day-of-week before the date being adjusted. |
For example, this is the Java program to obtain the date of the Sunday after 2022-02-25.
LocalDate localDate = LocalDate.of(2022, 02, 25);
LocalDate nextSunday = localDate
.with(TemporalAdjusters.next(DayOfWeek.SUNDAY));
3. Custom Adjusters
Create a custom adjuster which can be used to get recurring dates adjusted to some business logic. It can be done in two ways:
- Implement
TemporalAdjuster
interface - Inline Lambda expression
//1. With TemporalAdjuster interface
class NextBirthDay implements TemporalAdjuster
{
@Override
public Temporal adjustInto(Temporal temporal)
{
return temporal.with(ChronoField.MONTH_OF_YEAR, 11)
.with(ChronoField.DAY_OF_MONTH, 22);
}
}
//2. With lambda expressions
TemporalAdjuster temporalAdjuster = t -> t.plus(Period.ofDays(7));
4. Conclusion
In this tutorial, we learned about the TemporalAdjuster interface and how to use its factory methods to manipulate the dates for complex usecases.
Comments