ChronoUnit and TemporalAdjusters

Naveen AnamaneniUpdated · 4 min read
mediumJava 25javadate-time

ChronoUnit and TemporalAdjusters are two helpers in the java.time.temporal package. ChronoUnit is an enum of time units, from NANOS to MILLENNIA. It is used to count the amount of time between two dates or times in one unit, and to add or truncate by a unit. TemporalAdjusters is a class of ready-made rules that move a date to a related date, such as "the last day of this month" or "the next Monday". In this lesson, you will learn both with examples.

ChronoUnit

UseExample
Count between two valuesChronoUnit.DAYS.between(start, end)
Add or subtract by a unitdate.plus(2, ChronoUnit.WEEKS)
Cut off smaller unitstime.truncatedTo(ChronoUnit.MINUTES)

Common units: NANOS, MILLIS, SECONDS, MINUTES, HOURS, HALF_DAYS, DAYS, WEEKS, MONTHS, YEARS, DECADES, CENTURIES.

Example: Counting and Adding with ChronoUnit

Let's see an example that counts the time until an exam.

Units.java▶ Try it
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
 
public class Units {
    public static void main(String[] args) {
        LocalDate today = LocalDate.of(2026, 11, 12);
        LocalDate exam = LocalDate.of(2027, 3, 1);
 
        System.out.println("Days to exam:   "
            + ChronoUnit.DAYS.between(today, exam));
        System.out.println("Weeks to exam:  "
            + ChronoUnit.WEEKS.between(today, exam));
        System.out.println("Months to exam: "
            + ChronoUnit.MONTHS.between(today, exam));
 
        System.out.println("Two weeks later: "
            + today.plus(2, ChronoUnit.WEEKS));
 
        LocalDateTime stamp = LocalDateTime.of(2026, 11, 12, 14, 47, 31);
        System.out.println("Truncated to hour: "
            + stamp.truncatedTo(ChronoUnit.HOURS));
    }
}
Output
Days to exam:   109
Weeks to exam:  15
Months to exam: 3
Two weeks later: 2026-11-26
Truncated to hour: 2026-11-12T14:00

Explanation: ChronoUnit.X.between counts whole units, so 109 days is 15 whole weeks and 3 whole months (not 4, because 1 March is before 12 March). plus(2, WEEKS) adds 14 days. truncatedTo(HOURS) drops the minutes and seconds.

TemporalAdjusters

MethodDescription
firstDayOfMonth() / lastDayOfMonth()It is used to move to the first or last day of the month.
firstDayOfNextMonth()It moves to the 1st of the next month.
firstDayOfYear() / lastDayOfYear()It moves to 1 January or 31 December.
next(DayOfWeek) / previous(DayOfWeek)It moves to the next or previous given weekday, never today.
nextOrSame(DayOfWeek) / previousOrSame(DayOfWeek)The same, but today counts if it matches.
firstInMonth(DayOfWeek) / lastInMonth(DayOfWeek)It moves to the first or last given weekday of the month.
dayOfWeekInMonth(n, DayOfWeek)It moves to the n-th given weekday of the month.

Adjusters are applied with date.with(adjuster).

Adjusters.java▶ Try it
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
 
public class Adjusters {
    public static void main(String[] args) {
        LocalDate today = LocalDate.of(2026, 11, 12);
 
        System.out.println("Today:            " + today + " "
            + today.getDayOfWeek());
        System.out.println("Last of month:    "
            + today.with(TemporalAdjusters.lastDayOfMonth()));
        System.out.println("Next Monday:      "
            + today.with(TemporalAdjusters.next(DayOfWeek.MONDAY)));
        System.out.println("Next Thursday:    "
            + today.with(TemporalAdjusters.next(DayOfWeek.THURSDAY)));
        System.out.println("This or next Thu: "
            + today.with(TemporalAdjusters.nextOrSame(DayOfWeek.THURSDAY)));
        System.out.println("Second Saturday:  "
            + today.with(
                TemporalAdjusters.dayOfWeekInMonth(2, DayOfWeek.SATURDAY)));
        System.out.println("Last Friday:      "
            + today.with(TemporalAdjusters.lastInMonth(DayOfWeek.FRIDAY)));
    }
}
Output
Today:            2026-11-12 THURSDAY
Last of month:    2026-11-30
Next Monday:      2026-11-16
Next Thursday:    2026-11-19
This or next Thu: 2026-11-12
Second Saturday:  2026-11-14
Last Friday:      2026-11-27

Explanation: Each adjuster moves the date by a rule. Today is a Thursday, so next(THURSDAY) skips to the following week, while nextOrSame(THURSDAY) returns today. dayOfWeekInMonth(2, SATURDAY) finds the second Saturday of November.

Common Mistakes

Expecting MONTHS.between to round up. It counts whole months only.

Using next(day) when today should count. Use nextOrSame.

Calling date.with(...) and ignoring the result. Dates are immutable; save the returned value.

Practice

  1. Easy: Print the first Monday and the last Sunday of every month in 2027.
  2. Harder: Write a TemporalAdjuster lambda nextWorkingDay that skips Saturdays and Sundays, and test it on a Friday and a Saturday.

Quick check: ChronoUnit and TemporalAdjusters

4 questions
1What does ChronoUnit.DAYS.between(a, b) return?
2Today is Thursday. What does next(THURSDAY) return?
3How do you apply an adjuster?
4Which gives the last day of the month?

Key Takeaways

Was this tutorial helpful?

Lesson 333 of 482