skip to content

Explain the difference between next(DayOfWeek), nextOrSame(DayOfWeek), and dayOfWeekInMonth in TemporalAdjusters.

level: middleimportance: should knowfreq 40%

answer

  1. next = strictly after (excludes today)
  2. nextOrSame = inclusive (keeps today if it matches)
  3. previous / previousOrSame mirror it backward
  4. dayOfWeekInMonth(n, dow) = positional n-th weekday
  5. ordinal 0 = last of previous month; negative = from the end

basics

~20 s

next(MONDAY) gives the next Monday strictly after the date, even if the date itself is Monday. nextOrSame(MONDAY) returns the same date if it is already Monday, otherwise the next one. dayOfWeekInMonth(n, MONDAY) gives the n-th Monday of that month.

solid answer

~40 s

All three are day-of-week adjusters but differ in their boundary behavior. next(dow) always moves strictly forward to the first matching weekday after the input, so even if today is Monday, next(MONDAY) returns next week's Monday. nextOrSame(dow) is inclusive: if the input already falls on that weekday it returns the input unchanged, otherwise it behaves like next. The mirror pair previous/previousOrSame works the same way going backward. dayOfWeekInMonth(ordinal, dow) is positional within a month: dayOfWeekInMonth(1, MONDAY) is the first Monday of the month, (3, WEDNESDAY) the third Wednesday. Ordinal 0 yields the last matching weekday of the previous month, and negative ordinals count from the month's end. firstInMonth and lastInMonth are convenience equivalents to ordinal 1 and the last occurrence. Choosing the inclusive vs strict variant is the classic off-by-one source.

go deeper

for a junior

Can use next/nextOrSame for simple weekday jumps and read the Javadoc to pick one.

for a middle

Clearly articulates strict-vs-inclusive semantics and the previous mirrors, and uses dayOfWeekInMonth for positional dates.

for a senior

Reasons about edge cases (ordinal 0, negatives, month overflow) and picks the variant deliberately to avoid off-by-one bugs in scheduling logic.

for a principal

Establishes team idioms (e.g. previousOrSame(MONDAY) for week start), reviews date logic for inclusive/strict mistakes, and considers locale/first-day-of-week concerns above raw adjusters.

## Setup These adjusters all come from the `TemporalAdjusters` factory and all take a `DayOfWeek` enum value (`MONDAY`..`SUNDAY`). You apply them with `date.with(adjuster)`, which returns a new immutable date. The interesting part is their **boundary semantics** — what happens when the input date already matches. ## next(DayOfWeek) — strictly after `next(MONDAY)` returns the **first Monday that comes strictly after** the input date. "Strictly after" means the input itself is excluded. So if today is Monday 2026-06-22, `next(MONDAY)` returns 2026-06-29, a full week later. Use this when you want "the *upcoming* Monday, not today." ## nextOrSame(DayOfWeek) — inclusive `nextOrSame(MONDAY)` is the **inclusive** variant: if the input is already a Monday it returns the input unchanged; otherwise it returns the next Monday. So on Monday 2026-06-22, `nextOrSame(MONDAY)` returns 2026-06-22 itself. Use this for "snap forward to a Monday, staying put if we're already there" — common when aligning to the start of a week. ## previous / previousOrSame — the mirrors `previous(dow)` goes the other direction: the first matching weekday **strictly before** the input. `previousOrSame(dow)` returns the input if it already matches, else the previous match. `previousOrSame(MONDAY)` is the idiomatic "start of this week (Monday-based)." ## dayOfWeekInMonth(ordinal, DayOfWeek) — positional This one is not relative to the input's weekday; it's **positional within the input's month**. `dayOfWeekInMonth(1, MONDAY)` = the first Monday of that month, `(3, WEDNESDAY)` = the third Wednesday. The ordinal is 1-based for normal use. Special cases: - **0** means "the last matching weekday of the *previous* month" (it underflows by design). - **Negative** ordinals count from the end: `(-1, FRIDAY)` is the last Friday of the month. Note it can overflow into the next month if you ask for, say, the 5th Monday and there are only four — it keeps counting forward rather than throwing. ## firstInMonth / lastInMonth Convenience wrappers: `firstInMonth(MONDAY)` equals `dayOfWeekInMonth(1, MONDAY)`, and `lastInMonth(MONDAY)` returns the last Monday of the month (equivalent to ordinal -1 semantics but without the overflow concern). ## The common bug The off-by-one trap is choosing `next` when you meant `nextOrSame` (or vice versa) for an input that lands exactly on the target weekday. Always ask: "if today already matches, do I want today or the following one?" Inclusive → use the `OrSame` variant.

  • How do you compute the Monday that starts the current week?
    date.with(TemporalAdjusters.previousOrSame(DayOfWeek.MONDAY)). The OrSame variant keeps the date if it is already Monday, giving the correct week start.
  • What does dayOfWeekInMonth(-1, DayOfWeek.FRIDAY) return?
    The last Friday of the input's month; negative ordinals count from the end of the month.

saying these in an interview costs you the question

  • Assuming next(MONDAY) returns today when today is Monday — it returns the following Monday
  • Thinking dayOfWeekInMonth ordinal is 0-based
  • Believing dayOfWeekInMonth throws when the ordinal overflows the month (it rolls forward)
  • Mixing up previousOrSame (start of week) with previous

context