What is a TemporalAdjuster in java.time, and how do you apply one to a date?
answer
- TemporalAdjuster = single-method functional interface adjustInto
- Apply via date.with(adjuster), returns a NEW immutable value
- TemporalAdjusters (plural) = factory of ready-made adjusters
- next vs nextOrSame: strictly-after vs allow-same
- ofDateAdjuster wraps your own LocalDate lambda
basics
~20 sA TemporalAdjuster is a small object that knows how to move a date to a related date, like the last day of the month. You apply it with date.with(adjuster), which returns a new date and leaves the original unchanged.
solid answer
~40 sA TemporalAdjuster is a functional interface in java.time that encapsulates a rule for deriving a new temporal value from an existing one (for example, jump to the first day of next month). You apply it through the fluent with method: LocalDate result = date.with(adjuster). The factory class TemporalAdjusters ships ready-made adjusters such as firstDayOfMonth(), lastDayOfMonth(), firstDayOfNextMonth(), next(DayOfWeek), and nextOrSame(DayOfWeek). Because java.time types are immutable, with returns a brand-new instance and the original date is untouched. Adjusters compose cleanly with the rest of the fluent API, so you can chain plusMonths, withDayOfMonth, and with(adjuster) to express otherwise fiddly calendar math declaratively and readably.
code
java · 5 linesLocalDate d = LocalDate.of(2026, 6, 20); // a Saturday
LocalDate firstOfMonth = d.with(TemporalAdjusters.firstDayOfMonth()); // 2026-06-01
LocalDate lastOfMonth = d.with(TemporalAdjusters.lastDayOfMonth()); // 2026-06-30
LocalDate nextMonday = d.with(TemporalAdjusters.next(DayOfWeek.MONDAY)); // 2026-06-22
// d is still 2026-06-20 — nothing was mutatedgo deeper
Knows TemporalAdjusters exist and can call date.with(TemporalAdjusters.lastDayOfMonth()) and explain results are new objects.
Distinguishes the interface from the factory, knows the main built-ins, and writes a custom adjuster with ofDateAdjuster or a lambda.
Explains the immutability and functional-interface design, picks adjusters over manual arithmetic for clarity, and reasons about next vs nextOrSame edge cases.
Frames java.time's immutable/fluent design tradeoffs, sets team conventions for date math, and knows how adjusters interact with chronologies and TemporalField-based set operations.
## The problem it solves Before Java 8, computing things like "the last day of this month" or "next Friday" with the old `java.util.Calendar` was error-prone: you mutated a shared, stateful object, fields rolled over in surprising ways, and the code was hard to read. Java 8's `java.time` package (often called JSR-310) introduced **immutable** date/time types like `LocalDate` (a date with no time, e.g. 2026-06-20), `LocalDateTime` (date + time), and `ZonedDateTime` (date + time + time zone). ## What a TemporalAdjuster is A `TemporalAdjuster` is a **functional interface** — an interface with a single abstract method, so it can be written as a lambda. Its one method is `Temporal adjustInto(Temporal temporal)`. "Temporal" is the common supertype of all java.time values (LocalDate, LocalDateTime, etc.). So an adjuster is simply *a rule that takes a temporal and returns a related temporal*. Example rule: "return the same date but on the last day of its month." You rarely call `adjustInto` yourself. Instead every temporal type has a method `with(TemporalAdjuster adjuster)` that does the dispatch for you: ``` LocalDate d = LocalDate.of(2026, 6, 20); LocalDate end = d.with(TemporalAdjusters.lastDayOfMonth()); // 2026-06-30 ``` `with` is **fluent**: it returns a new value, so you can keep chaining. And because the types are **immutable**, `d` still equals 2026-06-20 after the call — nothing was mutated. This is a key safety property: you can pass dates around freely without anyone changing them under you. ## The TemporalAdjusters factory `TemporalAdjusters` (note the trailing **s**) is a utility class full of static factory methods that return common adjusters: - `firstDayOfMonth()`, `lastDayOfMonth()` - `firstDayOfNextMonth()` - `firstDayOfYear()`, `lastDayOfYear()`, `firstDayOfNextYear()` - `next(DayOfWeek)` — the next date that falls on that weekday, **strictly after** the input - `nextOrSame(DayOfWeek)` — same idea but returns the input date itself if it already matches - `previous(DayOfWeek)`, `previousOrSame(DayOfWeek)` - `dayOfWeekInMonth(int ordinal, DayOfWeek)` — e.g. the 3rd Tuesday of the month - `firstInMonth(DayOfWeek)`, `lastInMonth(DayOfWeek)` Don't confuse the singular interface `TemporalAdjuster` with the plural factory `TemporalAdjusters`. ## Writing your own Since it's a functional interface you can supply a lambda. A common need is "next working day": ``` TemporalAdjuster nextWorkday = TemporalAdjusters.ofDateAdjuster(date -> { DayOfWeek dow = date.getDayOfWeek(); int add = switch (dow) { case FRIDAY -> 3; case SATURDAY -> 2; default -> 1; }; return date.plusDays(add); }); ``` `ofDateAdjuster` wraps a `UnaryOperator<LocalDate>` so you only deal with `LocalDate` rather than the raw `Temporal`. ## Why it matters Adjusters turn awkward, bug-prone calendar arithmetic into small, named, reusable, testable rules, and the immutable fluent style means no accidental mutation. Combined with `truncatedTo` (which drops sub-units of time), they cover the vast majority of relative date/time math you need in business code.
- How would you get the third Wednesday of a month?date.with(TemporalAdjusters.dayOfWeekInMonth(3, DayOfWeek.WEDNESDAY)). The first argument is the ordinal (1-based); 0 means the last day of the previous month and negative values count from the end.
- What is the difference between with(TemporalAdjuster) and with(TemporalField, long)?with(adjuster) applies a rule object that derives a related date; with(field, value) sets one specific field (e.g. ChronoField.DAY_OF_MONTH to 1). Both return new immutable values.
saying these in an interview costs you the question
- Thinking with(...) mutates the original date (java.time is immutable)
- Confusing TemporalAdjuster (interface) with TemporalAdjusters (factory class)
- Believing next(MONDAY) can return the same day if it is already Monday (that is nextOrSame)
- Assuming you must implement adjustInto manually instead of using the factory